From 85e934681d298a2fa226562e9dedfb18365b9968 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Mon, 16 Apr 2018 12:38:14 -0600 Subject: [PATCH 0001/1243] Added DMT and JKR pair styles with rolling friction --- src/GRANULAR/pair_gran_dmt_rolling.cpp | 720 +++++++++++++++++++++ src/GRANULAR/pair_gran_dmt_rolling.h | 55 ++ src/GRANULAR/pair_gran_hertz_history.cpp | 2 +- src/GRANULAR/pair_gran_hooke_history.cpp | 5 +- src/GRANULAR/pair_gran_hooke_history.h | 4 +- src/GRANULAR/pair_gran_jkr_rolling.cpp | 763 +++++++++++++++++++++++ src/GRANULAR/pair_gran_jkr_rolling.h | 56 ++ 7 files changed, 1601 insertions(+), 4 deletions(-) create mode 100644 src/GRANULAR/pair_gran_dmt_rolling.cpp create mode 100644 src/GRANULAR/pair_gran_dmt_rolling.h create mode 100644 src/GRANULAR/pair_gran_jkr_rolling.cpp create mode 100644 src/GRANULAR/pair_gran_jkr_rolling.h diff --git a/src/GRANULAR/pair_gran_dmt_rolling.cpp b/src/GRANULAR/pair_gran_dmt_rolling.cpp new file mode 100644 index 0000000000..08299f85b5 --- /dev/null +++ b/src/GRANULAR/pair_gran_dmt_rolling.cpp @@ -0,0 +1,720 @@ +/* ---------------------------------------------------------------------- + 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: Leo Silbert (SNL), Gary Grest (SNL) + ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_gran_dmt_rolling.h" +#include "atom.h" +#include "update.h" +#include "force.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define TWOTHIRDS 0.6666666666666666 +#define EPSILON 1e-10 + +enum {TSUJI, BRILLIANTOV}; +enum {INDEP, BRILLROLL}; + +/* ---------------------------------------------------------------------- */ + +PairGranDMTRolling::PairGranDMTRolling(LAMMPS *lmp) : + PairGranHookeHistory(lmp, 7), + E_one(0), G_one(0), pois(0), muS_one(0), cor(0), alpha_one(0), + Ecoh_one(0), kR_one(0), muR_one(0), etaR_one(0) +{ + int ntypes = atom->ntypes; + memory->create(E,ntypes+1,ntypes+1,"pair:E"); + memory->create(G,ntypes+1,ntypes+1,"pair:G"); + memory->create(alpha,ntypes+1,ntypes+1,"pair:alpha"); + memory->create(gamman,ntypes+1,ntypes+1,"pair:gamman"); + memory->create(muS,ntypes+1,ntypes+1,"pair:muS"); + memory->create(Ecoh,ntypes+1,ntypes+1,"pair:Ecoh"); + memory->create(kR,ntypes+1,ntypes+1,"pair:kR"); + memory->create(muR,ntypes+1,ntypes+1,"pair:muR"); + memory->create(etaR,ntypes+1,ntypes+1,"pair:etaR"); +} + +/* ---------------------------------------------------------------------- */ +PairGranDMTRolling::~PairGranDMTRolling() +{ + delete [] E_one; + delete [] G_one; + delete [] pois; + delete [] muS_one; + delete [] cor; + delete [] alpha_one; + delete [] Ecoh_one; + delete [] kR_one; + delete [] muR_one; + delete [] etaR_one; + //TODO: Make all this work with standard pair coeff type commands. + //Also these should not be in the destructor. + memory->destroy(E); + memory->destroy(G); + memory->destroy(alpha); + memory->destroy(gamman); + memory->destroy(muS); + memory->destroy(Ecoh); + memory->destroy(kR); + memory->destroy(muR); + memory->destroy(etaR); +} +/* ---------------------------------------------------------------------- */ + +void PairGranDMTRolling::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum; + int itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + double Fhz, Fdamp, Fdmt, Fne, Fntot, Fscrit, Frcrit; + double overlap; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + double signtwist, magtwist, magtortwist, Mtcrit; + double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; + double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int shearupdate = 1; + if (update->setupflag) shearupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + 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 *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firstshear = fix_history->firstvalue; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + 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]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + jtype = type[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]; + radsum = radi + radj; + + if (rsq >= radsum*radsum){ + // unset non-touching neighbors + touch[jj] = 0; + shear = &allshear[size_history*jj]; + for (int k = 0; k < size_history; k++) + shear[k] = 0.0; + } else { + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/(radi+radj); + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + //**************************************** + //Normal force = Hertzian contact + DMT + damping + //**************************************** + overlap = radsum - r; + a = sqrt(R*overlap); + kn = 4.0/3.0*E[itype][jtype]*a; + Fhz = kn*overlap; + + //Damping (based on Tsuji et al) + if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + //DMT + Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; + + Fne = Fhz + Fdmt; + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including shear history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting + //delta/2, i.e. instead of radi, use distance to center of contact point? + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + touch[jj] = 1; + shear = &allshear[size_history*jj]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // Rotate and update shear displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (shearupdate) { + rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shear[0] -= rsht*nx; + shear[1] -= rsht*ny; + shear[2] -= rsht*nz; + //Also rescale to preserve magnitude + shear[0] *= scalefac; + shear[1] *= scalefac; + shear[2] *= scalefac; + } + //Update shear history + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + + // tangential forces = shear + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = muS[itype][jtype] * fabs(Fne); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + //**************************************** + // Rolling force, including shear history effects + //**************************************** + + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // Rolling displacement + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); + rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; + + if (shearupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + shear[3] -= rolldotn*nx; + shear[4] -= rolldotn*ny; + shear[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + shear[3] *= scalefac; + shear[4] *= scalefac; + shear[5] *= scalefac; + } + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + } + + k_R = kR[itype][jtype]; + if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; + else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); + fr1 = -k_R*shear[3] - eta_R*vrl1; + fr2 = -k_R*shear[4] - eta_R*vrl2; + fr3 = -k_R*shear[5] - eta_R*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = muR[itype][jtype] * fabs(Fne); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + + + //**************************************** + // Twisting torque, including shear history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + shear[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit){ + shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + + if (force->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; + + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + +/* ---------------------------------------------------------------------- + global settings + ------------------------------------------------------------------------- */ + +void PairGranDMTRolling::settings(int narg, char **arg) +{ + if (narg < 6) error->all(FLERR,"Illegal pair_style command"); + + int ntypes = atom->ntypes; + + if (narg < 8*ntypes) error->all(FLERR,"Illegal pair_style command"); + + E_one = new double[ntypes+1]; + G_one = new double[ntypes+1]; + pois = new double[ntypes+1]; + muS_one = new double[ntypes+1]; + cor = new double[ntypes+1]; + alpha_one = new double[ntypes+1]; + Ecoh_one = new double[ntypes+1]; + kR_one = new double[ntypes+1]; + muR_one = new double[ntypes+1]; + etaR_one = new double[ntypes+1]; + + for (int i=0; i < ntypes;i++){ + E_one[i+1] = force->numeric(FLERR, arg[i]); + G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); + muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); + cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); + Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); + kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); + muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); + etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); + } + + //Defaults + normaldamp = TSUJI; + rollingdamp = INDEP; + + int iarg = 8*ntypes; + while (iarg < narg){ + if (strcmp(arg[iarg],"normaldamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else if (strcmp(arg[iarg],"rollingdamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else{ + iarg +=1; + } + } + + //Derived from inputs + for (int i=1; i <= ntypes; i++){ + pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; + alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; + for (int j=i; j <= ntypes; j++){ + E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); + G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); + if (normaldamp == TSUJI){ + alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); + } + else if (normaldamp == BRILLIANTOV){ + gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); + } + muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); + Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); + kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); + etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); + muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGranDMTRolling::single(int i, int j, int itype, int jtype, + double rsq, + double factor_coul, double factor_lj, + double &fforce) +{ + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double overlap, a; + double mi,mj,meff,damp,kn,kt; + double Fhz,Fdamp,Fdmt,Fne,Fntot,Fscrit; + double eta_N,eta_T; + double vtr1,vtr2,vtr3,vrel; + double fs1,fs2,fs3,fs; + double shrmag; + + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + + if (rsq >= radsum*radsum) { + fforce = 0.0; + svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + return 0.0; + } + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/radsum; + + // relative translational velocity + + double **v = atom->v; + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + + vnnr = vr1*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + + // normal force = Hertzian contact + normal velocity damping + overlap = radsum - r; + a = sqrt(R*overlap); + kn = 4.0/3.0*E[itype][jtype]*a; + Fhz = kn*overlap; + + //Damping (based on Tsuji et al) + + eta_N=alpha[itype][jtype]*sqrt(meff*kn); + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + //DMT + Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; + + Fne = Fhz + Fdmt; + Fntot = Fne + Fdamp; + + // relative velocities + + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + // neighprev = index of found neigh on previous call + // search entire jnum list of neighbors of I for neighbor J + // start from neighprev, since will typically be next neighbor + // reset neighprev to 0 as necessary + + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allshear = fix_history->firstvalue[i]; + + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + + double *shear = &allshear[size_history*neighprev]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // tangential forces = shear + tangential velocity damping + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; + fs1 = -kt*shear[0] - eta_T*vtr1; + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + Fscrit= muS[itype][jtype] * fabs(Fne); + + if (fs > Fscrit) { + if (shrmag != 0.0) { + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + fs *= Fscrit/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; + } + + // set all forces and return no energy + + fforce = Fntot; + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = vn1; + svector[5] = vn2; + svector[6] = vn3; + svector[7] = vt1; + svector[8] = vt2; + svector[9] = vt3; + return 0.0; +} diff --git a/src/GRANULAR/pair_gran_dmt_rolling.h b/src/GRANULAR/pair_gran_dmt_rolling.h new file mode 100644 index 0000000000..8f4ae2005e --- /dev/null +++ b/src/GRANULAR/pair_gran_dmt_rolling.h @@ -0,0 +1,55 @@ +/* -*- 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(gran/dmt/rolling,PairGranDMTRolling) + +#else + +#ifndef LMP_PAIR_GRAN_DMT_ROLLING_H +#define LMP_PAIR_GRAN_DMT_ROLLING_H + +#include "pair_gran_hooke_history.h" + +namespace LAMMPS_NS { + +class PairGranDMTRolling : public PairGranHookeHistory { +public: + PairGranDMTRolling(class LAMMPS *); + virtual ~PairGranDMTRolling(); + virtual void compute(int, int); + void settings(int, char **); //Eventually set this through coeff method so that user can specify a particular i-j set of coefficients + double single(int, int, int, int, double, double, double, double &); + double *E_one, *G_one, *pois, *muS_one, *cor, *alpha_one, *Ecoh_one, *kR_one, *muR_one, *etaR_one; //Public so as to be accessible to fix/wall/gran +private: + double **E, **G, **alpha, **muS, **Ecoh, **kR, **muR, **etaR, **gamman; + int normaldamp, rollingdamp; + + +}; + +} + +#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. + + */ diff --git a/src/GRANULAR/pair_gran_hertz_history.cpp b/src/GRANULAR/pair_gran_hertz_history.cpp index 9723531625..5508b17d99 100644 --- a/src/GRANULAR/pair_gran_hertz_history.cpp +++ b/src/GRANULAR/pair_gran_hertz_history.cpp @@ -36,7 +36,7 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ PairGranHertzHistory::PairGranHertzHistory(LAMMPS *lmp) : - PairGranHookeHistory(lmp) {} + PairGranHookeHistory(lmp, 3) {} /* ---------------------------------------------------------------------- */ diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 4f120150de..f1a155f2e4 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -39,7 +39,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp) +PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp, int _size_history) : Pair(lmp), + size_history(_size_history) { single_enable = 1; no_virial_fdotr_compute = 1; @@ -412,7 +413,7 @@ void PairGranHookeHistory::init_style() if (history && fix_history == NULL) { char dnumstr[16]; - sprintf(dnumstr,"%d",3); + sprintf(dnumstr,"%d",size_history); char **fixarg = new char*[4]; fixarg[0] = (char *) "NEIGH_HISTORY"; fixarg[1] = (char *) "all"; diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/GRANULAR/pair_gran_hooke_history.h index 3ca5c73116..c35de04109 100644 --- a/src/GRANULAR/pair_gran_hooke_history.h +++ b/src/GRANULAR/pair_gran_hooke_history.h @@ -26,7 +26,7 @@ namespace LAMMPS_NS { class PairGranHookeHistory : public Pair { public: - PairGranHookeHistory(class LAMMPS *); + PairGranHookeHistory(class LAMMPS *, int size_history = 3); virtual ~PairGranHookeHistory(); virtual void compute(int, int); virtual void settings(int, char **); @@ -54,6 +54,8 @@ class PairGranHookeHistory : public Pair { double *onerad_dynamic,*onerad_frozen; double *maxrad_dynamic,*maxrad_frozen; + int size_history; + class FixNeighHistory *fix_history; // storage of rigid body masses for use in granular interactions diff --git a/src/GRANULAR/pair_gran_jkr_rolling.cpp b/src/GRANULAR/pair_gran_jkr_rolling.cpp new file mode 100644 index 0000000000..ce109cccbc --- /dev/null +++ b/src/GRANULAR/pair_gran_jkr_rolling.cpp @@ -0,0 +1,763 @@ +/* ---------------------------------------------------------------------- + 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: Leo Silbert (SNL), Gary Grest (SNL) + ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_gran_jkr_rolling.h" +#include "atom.h" +#include "update.h" +#include "force.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define ONETHIRD 0.33333333333333333 +#define TWOTHIRDS 0.66666666666666666 +#define POW6ONE 0.550321208149104 //6^(-1/3) +#define POW6TWO 0.30285343213869 //6^(-2/3) + +#define EPSILON 1e-10 + +enum {TSUJI, BRILLIANTOV}; +enum {INDEP, BRILLROLL}; + +/* ---------------------------------------------------------------------- */ + +PairGranJKRRolling::PairGranJKRRolling(LAMMPS *lmp) : + PairGranHookeHistory(lmp, 7) +{ + E_one = NULL; + G_one = NULL; + pois = NULL; + muS_one = NULL; + cor = NULL; + alpha_one = NULL; + Ecoh_one = NULL; + kR_one = NULL; + muR_one = NULL; + etaR_one = NULL; + int ntypes = atom->ntypes; + memory->create(E,ntypes+1,ntypes+1,"pair:E"); + memory->create(G,ntypes+1,ntypes+1,"pair:G"); + memory->create(alpha,ntypes+1,ntypes+1,"pair:alpha"); + memory->create(gamman,ntypes+1,ntypes+1,"pair:gamman"); + memory->create(muS,ntypes+1,ntypes+1,"pair:muS"); + memory->create(Ecoh,ntypes+1,ntypes+1,"pair:Ecoh"); + memory->create(kR,ntypes+1,ntypes+1,"pair:kR"); + memory->create(muR,ntypes+1,ntypes+1,"pair:muR"); + memory->create(etaR,ntypes+1,ntypes+1,"pair:etaR"); +} + +/* ---------------------------------------------------------------------- */ +PairGranJKRRolling::~PairGranJKRRolling() +{ + delete [] E_one; + delete [] G_one; + delete [] pois; + delete [] muS_one; + delete [] cor; + delete [] alpha_one; + delete [] Ecoh_one; + delete [] kR_one; + delete [] muR_one; + delete [] etaR_one; + //TODO: Make all this work with standard pair coeff type commands. + //Also these should not be in the destructor. + memory->destroy(E); + memory->destroy(G); + memory->destroy(alpha); + memory->destroy(gamman); + memory->destroy(muS); + memory->destroy(Ecoh); + memory->destroy(kR); + memory->destroy(muR); + memory->destroy(etaR); +} +/* ---------------------------------------------------------------------- */ + +void PairGranJKRRolling::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum; + int itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + double Fne, Fdamp, Fntot, Fscrit, Frcrit, F_C, delta_C, delta_Cinv; + double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; + double keyterm, keyterm2, keyterm3, aovera0, foverFc; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + double signtwist, magtwist, magtortwist, Mtcrit; + double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; + double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int shearupdate = 1; + if (update->setupflag) shearupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + 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 *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firstshear = fix_history->firstvalue; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + 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]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + jtype = type[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]; + radsum = radi + radj; + R = radi*radj/(radi+radj); + a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); + delta_C = 0.5*a0*a0*POW6ONE/R; + + if ((rsq >= radsum*radsum && touch[jj] == 0) || + (rsq >= (radsum+delta_C)*(radsum+delta_C))){ + // unset non-touching neighbors + touch[jj] = 0; + shear = &allshear[size_history*jj]; + for (int k = 0; k < size_history; k++) + shear[k] = 0.0; + } else { + F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + //**************************************** + //Normal force = JKR-adjusted Hertzian contact + damping + //**************************************** + if (Ecoh[itype][jtype] != 0.0) delta_Cinv = 1.0/delta_C; + else delta_Cinv = 1.0; + overlap = (radsum - r)*delta_Cinv; + olapsq = overlap*overlap; + olapcubed = olapsq*overlap; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,ONETHIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = POW6TWO * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 + a = aovera0*a0; + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + + Fne = F_C*foverFc; + + //Damping + kn = 4.0/3.0*E[itype][jtype]*a; + if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including shear history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting + //delta/2, i.e. instead of radi, use distance to center of contact point? + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + touch[jj] = 1; + shear = &allshear[size_history*jj]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // Rotate and update shear displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (shearupdate) { + rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shear[0] -= rsht*nx; + shear[1] -= rsht*ny; + shear[2] -= rsht*nz; + //Also rescale to preserve magnitude + shear[0] *= scalefac; + shear[1] *= scalefac; + shear[2] *= scalefac; + } + //Update shear history + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + + // tangential forces = shear + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = muS[itype][jtype] * fabs(Fne + 2*F_C); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + //**************************************** + // Rolling force, including shear history effects + //**************************************** + + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // Rolling displacement + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); + rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; + + if (shearupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + shear[3] -= rolldotn*nx; + shear[4] -= rolldotn*ny; + shear[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + shear[3] *= scalefac; + shear[4] *= scalefac; + shear[5] *= scalefac; + } + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + } + + k_R = kR[itype][jtype]*4.0*F_C*pow(aovera0,1.5); + if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; + else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); + fr1 = -k_R*shear[3] - eta_R*vrl1; + fr2 = -k_R*shear[4] - eta_R*vrl2; + fr3 = -k_R*shear[5] - eta_R*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = muR[itype][jtype] * fabs(Fne + 2*F_C); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + + + //**************************************** + // Twisting torque, including shear history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + shear[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + //shear[6] = Mtcrit/k_Q*magtwist/fabs(magtwist); + shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + + if (force->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; + + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + +/* ---------------------------------------------------------------------- + global settings + ------------------------------------------------------------------------- */ + +void PairGranJKRRolling::settings(int narg, char **arg) +{ + if (narg < 6) error->all(FLERR,"Illegal pair_style command"); + + int ntypes = atom->ntypes; + + if (narg < 8*ntypes) error->all(FLERR,"Illegal pair_style command"); + + E_one = new double[ntypes+1]; + G_one = new double[ntypes+1]; + pois = new double[ntypes+1]; + muS_one = new double[ntypes+1]; + cor = new double[ntypes+1]; + alpha_one = new double[ntypes+1]; + Ecoh_one = new double[ntypes+1]; + kR_one = new double[ntypes+1]; + muR_one = new double[ntypes+1]; + etaR_one = new double[ntypes+1]; + + //Defaults + normaldamp = TSUJI; + rollingdamp = INDEP; + + int iarg = 8*ntypes; + while (iarg < narg){ + if (strcmp(arg[iarg],"normaldamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else if (strcmp(arg[iarg],"rollingdamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); + iarg +=2; + } + else iarg += 1; + } + + for (int i=0; i < ntypes;i++){ + + E_one[i+1] = force->numeric(FLERR, arg[i]); + G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); + muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); + cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); + Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); + kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); + muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); + etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); + } + + //Optional keywords: + // normaldamp tsuji, or normaldamp brilliantov + // rollingdamp brilliantov + + //Derived from inputs + for (int i=1; i <= ntypes; i++){ + pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; + alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; + for (int j=i; j <= ntypes; j++){ + E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); + G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); + if (normaldamp == TSUJI){ + alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); + } + else if (normaldamp == BRILLIANTOV){ + gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); + } + muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); + Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); + kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); + etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); + muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGranJKRRolling::single(int i, int j, int itype, int jtype, + double rsq, + double factor_coul, double factor_lj, + double &fforce) +{//TODO: update PairGranJKRRolling::single for JKR + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double overlap, a; + double mi,mj,meff,damp,kn,kt; + double Fdamp,Fne,Fntot,Fscrit; + double eta_N,eta_T; + double vtr1,vtr2,vtr3,vrel; + double fs1,fs2,fs3,fs; + double shrmag; + double F_C, delta_C, olapsq, olapcubed, sqrtterm, tmp, a0; + double keyterm, keyterm2, keyterm3, aovera0, foverFc; + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/(radi+radj); + a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); + delta_C = 0.5*a0*a0*POW6ONE/R; + + int *touch = fix_history->firstflag[i]; + if ((rsq >= (radsum+delta_C)*(radsum+delta_C) )|| + (rsq >= radsum*radsum && touch[j])){ + fforce = 0.0; + svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + return 0.0; + } + + // relative translational velocity + + double **v = atom->v; + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + + vnnr = vr1*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + + // normal force = JKR + F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + overlap = radsum - r; + olapsq = overlap*overlap; + olapcubed = olapsq*olapsq; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,ONETHIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = POW6TWO * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 + a = aovera0*a0; + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + + Fne = F_C*foverFc; + + //Damping + kn = 4.0/3.0*E[itype][jtype]*a; + if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + Fntot = Fne + Fdamp; + + // relative velocities + + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + // neighprev = index of found neigh on previous call + // search entire jnum list of neighbors of I for neighbor J + // start from neighprev, since will typically be next neighbor + // reset neighprev to 0 as necessary + + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allshear = fix_history->firstvalue[i]; + + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + + double *shear = &allshear[size_history*neighprev]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // tangential forces = shear + tangential velocity damping + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; + fs1 = -kt*shear[0] - eta_T*vtr1; + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + Fscrit= muS[itype][jtype] * fabs(Fne + 2*F_C); + + if (fs > Fscrit) { + if (shrmag != 0.0) { + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + fs *= Fscrit/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; + } + + // set all forces and return no energy + + fforce = Fntot; + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = vn1; + svector[5] = vn2; + svector[6] = vn3; + svector[7] = vt1; + svector[8] = vt2; + svector[9] = vt3; + return 0.0; +} diff --git a/src/GRANULAR/pair_gran_jkr_rolling.h b/src/GRANULAR/pair_gran_jkr_rolling.h new file mode 100644 index 0000000000..8c4b339eb3 --- /dev/null +++ b/src/GRANULAR/pair_gran_jkr_rolling.h @@ -0,0 +1,56 @@ +/* -*- 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(gran/jkr/rolling,PairGranJKRRolling) + +#else + +#ifndef LMP_PAIR_GRAN_JKR_ROLLING_H +#define LMP_PAIR_GRAN_JKR_ROLLING_H + +#include "pair_gran_hooke_history.h" + +namespace LAMMPS_NS { + +class PairGranJKRRolling : public PairGranHookeHistory { +public: + PairGranJKRRolling(class LAMMPS *); + virtual ~PairGranJKRRolling(); + virtual void compute(int, int); + void settings(int, char **); //Eventually set this through coeff method so that user can specify a particular i-j set of coefficients + double single(int, int, int, int, double, double, double, double &); + double *E_one, *G_one, *pois, *muS_one, *cor, *alpha_one, *Ecoh_one, *kR_one, *muR_one, *etaR_one; //Public so as to be accessible to fix/wall/gran +private: + double **E, **G, **alpha, **muS, **Ecoh, **kR, **muR, **etaR, **gamman; + int normaldamp, rollingdamp; + + + +}; + +} + +#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. + + */ -- GitLab From f94c5b7637ac5840ddbd3db0e5f45e07e1413477 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Mon, 16 Apr 2018 12:40:22 -0600 Subject: [PATCH 0002/1243] Added 'store_contacts' option to fix/wall/gran/region to store info about individual particle-wall contacts --- src/GRANULAR/fix_wall_gran.cpp | 112 ++++++++++++++++++++++---- src/GRANULAR/fix_wall_gran.h | 11 ++- src/GRANULAR/fix_wall_gran_region.cpp | 94 ++++++++++++++------- 3 files changed, 165 insertions(+), 52 deletions(-) diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 033c35dbac..a8386238d7 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -100,7 +100,6 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : iarg = 10; } - else { if (narg < 10) error->all(FLERR,"Illegal fix wall/gran command"); @@ -165,6 +164,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : wiggle = 0; wshear = 0; + peratom_flag = 0; while (iarg < narg) { if (strcmp(arg[iarg],"wiggle") == 0) { @@ -186,7 +186,13 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : vshear = force->numeric(FLERR,arg[iarg+2]); wshear = 1; iarg += 3; + } else if (strcmp(arg[iarg],"store_contacts") == 0){ + peratom_flag = 1; + size_peratom_cols = 8; //Could make this a user input option? + peratom_freq = 1; + iarg += 1; } else error->all(FLERR,"Illegal fix wall/gran command"); + } if (wallstyle == XPLANE && domain->xperiodic) @@ -239,6 +245,13 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : shearone[i][j] = 0.0; } + if (peratom_flag){ + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) + for (int m = 0; m < size_peratom_cols; m++) + array_atom[i][m] = 0.0; + } + time_origin = update->ntimestep; } @@ -425,20 +438,37 @@ void FixWallGran::post_force(int vflag) meff = rmass[i]; if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; + // store contact info + if (peratom_flag){ + array_atom[i][0] = (double)atom->tag[i]; + array_atom[i][4] = x[i][0] - dx; + array_atom[i][5] = x[i][1] - dy; + array_atom[i][6] = x[i][2] - dz; + array_atom[i][7] = radius[i]; + } + // invoke sphere/wall interaction + double *contact; + if (peratom_flag) + contact = array_atom[i]; + else + contact = NULL; if (pairstyle == HOOKE) hooke(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff); + omega[i],torque[i],radius[i],meff, contact); else if (pairstyle == HOOKE_HISTORY) hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i]); + omega[i],torque[i],radius[i],meff,shearone[i], + contact); else if (pairstyle == HERTZ_HISTORY) hertz_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i]); + omega[i],torque[i],radius[i],meff,shearone[i], + contact); else if (pairstyle == BONDED_HISTORY) bonded_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i]); + omega[i],torque[i],radius[i],meff,shearone[i], + contact); } } } @@ -456,7 +486,7 @@ void FixWallGran::post_force_respa(int vflag, int ilevel, int iloop) void FixWallGran::hooke(double rsq, double dx, double dy, double dz, double *vwall, double *v, double *f, double *omega, double *torque, - double radius, double meff) + double radius, double meff, double* contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -523,6 +553,12 @@ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, fy = dy*ccel + fs2; fz = dz*ccel + fs3; + if (peratom_flag){ + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } + f[0] += fx; f[1] += fy; f[2] += fz; @@ -540,7 +576,8 @@ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, double *vwall, double *v, double *f, double *omega, double *torque, - double radius, double meff, double *shear) + double radius, double meff, double *shear, + double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -643,6 +680,12 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, f[1] += fy; f[2] += fz; + if (peratom_flag){ + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } + tor1 = rinv * (dy*fs3 - dz*fs2); tor2 = rinv * (dz*fs1 - dx*fs3); tor3 = rinv * (dx*fs2 - dy*fs1); @@ -656,7 +699,8 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, double *vwall, double rwall, double *v, double *f, double *omega, double *torque, - double radius, double meff, double *shear) + double radius, double meff, double *shear, + double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -762,6 +806,12 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, fy = dy*ccel + fs2; fz = dz*ccel + fs3; + if (peratom_flag){ + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } + f[0] += fx; f[1] += fy; f[2] += fz; @@ -780,7 +830,8 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, void FixWallGran::bonded_history(double rsq, double dx, double dy, double dz, double *vwall, double rwall, double *v, double *f, double *omega, double *torque, - double radius, double meff, double *shear) + double radius, double meff, double *shear, + double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -999,6 +1050,12 @@ void FixWallGran::bonded_history(double rsq, double dx, double dy, double dz, f[1] += fy; f[2] += fz; + if (peratom_flag){ + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } + tor1 = rinv * (dy*fs3 - dz*fs2); tor2 = rinv * (dz*fs1 - dx*fs3); tor3 = rinv * (dx*fs2 - dy*fs1); @@ -1025,6 +1082,7 @@ double FixWallGran::memory_usage() double bytes = 0.0; if (history) bytes += nmax*sheardim * sizeof(double); // shear history if (fix_rigid) bytes += nmax * sizeof(int); // mass_rigid + if (peratom_flag) bytes += nmax*size_peratom_cols*sizeof(double); //store contacts return bytes; } @@ -1035,6 +1093,9 @@ double FixWallGran::memory_usage() void FixWallGran::grow_arrays(int nmax) { if (history) memory->grow(shearone,nmax,sheardim,"fix_wall_gran:shearone"); + if (peratom_flag){ + memory->grow(array_atom,nmax,size_peratom_cols,"fix_wall_gran:array_atom"); + } } /* ---------------------------------------------------------------------- @@ -1046,6 +1107,10 @@ void FixWallGran::copy_arrays(int i, int j, int delflag) if (history) for (int m = 0; m < sheardim; m++) shearone[j][m] = shearone[i][m]; + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + array_atom[j][m] = array_atom[i][m]; + } } /* ---------------------------------------------------------------------- @@ -1057,6 +1122,10 @@ void FixWallGran::set_arrays(int i) if (history) for (int m = 0; m < sheardim; m++) shearone[i][m] = 0; + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + array_atom[i][m] = 0; + } } /* ---------------------------------------------------------------------- @@ -1065,11 +1134,15 @@ void FixWallGran::set_arrays(int i) int FixWallGran::pack_exchange(int i, double *buf) { - if (!history) return 0; - int n = 0; - for (int m = 0; m < sheardim; m++) - buf[n++] = shearone[i][m]; + if (history){ + for (int m = 0; m < sheardim; m++) + buf[n++] = shearone[i][m]; + } + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + buf[n++] = array_atom[i][m]; + } return n; } @@ -1079,11 +1152,15 @@ int FixWallGran::pack_exchange(int i, double *buf) int FixWallGran::unpack_exchange(int nlocal, double *buf) { - if (!history) return 0; - int n = 0; - for (int m = 0; m < sheardim; m++) - shearone[nlocal][m] = buf[n++]; + if (history){ + for (int m = 0; m < sheardim; m++) + shearone[nlocal][m] = buf[n++]; + } + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + array_atom[nlocal][m] = buf[n++]; + } return n; } @@ -1148,3 +1225,4 @@ void FixWallGran::reset_dt() { dt = update->dt; } + diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran.h index 2403a31907..f1a5dbc842 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran.h @@ -47,16 +47,16 @@ class FixWallGran : public Fix { void reset_dt(); void hooke(double, double, double, double, double *, - double *, double *, double *, double *, double, double); + double *, double *, double *, double *, double, double, double*); void hooke_history(double, double, double, double, double *, double *, double *, double *, double *, double, double, - double *); + double *, double *); void hertz_history(double, double, double, double, double *, double, double *, double *, double *, double *, double, double, - double *); + double *, double *); void bonded_history(double, double, double, double, double *, double, double *, double *, double *, double *, double, double, - double *); + double *, double *); protected: int wallstyle,wiggle,wshear,axis; @@ -82,6 +82,9 @@ class FixWallGran : public Fix { class Fix *fix_rigid; // ptr to rigid body fix, NULL if none double *mass_rigid; // rigid mass for owned+ghost atoms int nmax; // allocated size of mass_rigid + + // Store particle interactions + int store; }; } diff --git a/src/GRANULAR/fix_wall_gran_region.cpp b/src/GRANULAR/fix_wall_gran_region.cpp index d1c5d4c9c7..e00036c26a 100644 --- a/src/GRANULAR/fix_wall_gran_region.cpp +++ b/src/GRANULAR/fix_wall_gran_region.cpp @@ -238,23 +238,37 @@ void FixWallGranRegion::post_force(int vflag) meff = rmass[i]; if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; - // invoke sphere/wall interaction + // store contact info + if (peratom_flag){ + array_atom[i][0] = (double)atom->tag[i]; + array_atom[i][4] = x[i][0] - dx; + array_atom[i][5] = x[i][1] - dy; + array_atom[i][6] = x[i][2] - dz; + array_atom[i][7] = radius[i]; + } + // invoke sphere/wall interaction + double *contact; + if (peratom_flag) + contact = array_atom[i]; + else + contact = NULL; + if (pairstyle == HOOKE) hooke(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff); + omega[i],torque[i],radius[i],meff, contact); else if (pairstyle == HOOKE_HISTORY) hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], omega[i],torque[i],radius[i],meff, - shearmany[i][c2r[ic]]); + shearmany[i][c2r[ic]], contact); else if (pairstyle == HERTZ_HISTORY) hertz_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, v[i],f[i],omega[i],torque[i], - radius[i],meff,shearmany[i][c2r[ic]]); + radius[i],meff,shearmany[i][c2r[ic]], contact); else if (pairstyle == BONDED_HISTORY) bonded_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, v[i],f[i],omega[i],torque[i], - radius[i],meff,shearmany[i][c2r[ic]]); + radius[i],meff,shearmany[i][c2r[ic]], contact); } } } @@ -341,6 +355,9 @@ void FixWallGranRegion::grow_arrays(int nmax) memory->grow(walls,nmax,tmax,"fix_wall_gran:walls"); memory->grow(shearmany,nmax,tmax,sheardim,"fix_wall_gran:shearmany"); } + if (peratom_flag){ + memory->grow(array_atom,nmax,size_peratom_cols,"fix_wall_gran:array_atom"); + } } /* ---------------------------------------------------------------------- @@ -351,16 +368,20 @@ void FixWallGranRegion::copy_arrays(int i, int j, int delflag) { int m,n,iwall; - if (!history) return; - - n = ncontact[i]; + if (history){ + n = ncontact[i]; + for (iwall = 0; iwall < n; iwall++) { + walls[j][iwall] = walls[i][iwall]; + for (m = 0; m < sheardim; m++) + shearmany[j][iwall][m] = shearmany[i][iwall][m]; + } + ncontact[j] = ncontact[i]; + } - for (iwall = 0; iwall < n; iwall++) { - walls[j][iwall] = walls[i][iwall]; - for (m = 0; m < sheardim; m++) - shearmany[j][iwall][m] = shearmany[i][iwall][m]; + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + array_atom[j][m] = array_atom[i][m]; } - ncontact[j] = ncontact[i]; } /* ---------------------------------------------------------------------- @@ -369,8 +390,12 @@ void FixWallGranRegion::copy_arrays(int i, int j, int delflag) void FixWallGranRegion::set_arrays(int i) { - if (!history) return; - ncontact[i] = 0; + if (history) + ncontact[i] = 0; + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + array_atom[i][m] = 0; + } } /* ---------------------------------------------------------------------- @@ -381,16 +406,19 @@ int FixWallGranRegion::pack_exchange(int i, double *buf) { int m; - if (!history) return 0; - int n = 0; - int count = ncontact[i]; - - buf[n++] = ubuf(count).d; - for (int iwall = 0; iwall < count; iwall++) { - buf[n++] = ubuf(walls[i][iwall]).d; - for (m = 0; m < sheardim; m++) - buf[n++] = shearmany[i][iwall][m]; + if (history){ + int count = ncontact[i]; + buf[n++] = ubuf(count).d; + for (int iwall = 0; iwall < count; iwall++) { + buf[n++] = ubuf(walls[i][iwall]).d; + for (m = 0; m < sheardim; m++) + buf[n++] = shearmany[i][iwall][m]; + } + } + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + buf[n++] = array_atom[i][m]; } return n; @@ -404,15 +432,19 @@ int FixWallGranRegion::unpack_exchange(int nlocal, double *buf) { int m; - if (!history) return 0; int n = 0; - int count = ncontact[nlocal] = (int) ubuf(buf[n++]).i; - - for (int iwall = 0; iwall < count; iwall++) { - walls[nlocal][iwall] = (int) ubuf(buf[n++]).i; - for (m = 0; m < sheardim; m++) - shearmany[nlocal][iwall][m] = buf[n++]; + if (history){ + int count = ncontact[nlocal] = (int) ubuf(buf[n++]).i; + for (int iwall = 0; iwall < count; iwall++) { + walls[nlocal][iwall] = (int) ubuf(buf[n++]).i; + for (m = 0; m < sheardim; m++) + shearmany[nlocal][iwall][m] = buf[n++]; + } + } + if (peratom_flag){ + for (int m = 0; m < size_peratom_cols; m++) + array_atom[nlocal][m] = buf[n++]; } return n; -- GitLab From 158c7531fe4a46631eb55d764b62ecba574157e7 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Mon, 16 Apr 2018 15:51:06 -0600 Subject: [PATCH 0003/1243] Added pair/gran/dmt as a granular wall interaction option --- src/GRANULAR/fix_wall_gran.cpp | 511 +++++++++-------- src/GRANULAR/fix_wall_gran.h | 26 +- src/GRANULAR/fix_wall_gran_region.cpp | 32 +- src/GRANULAR/pair_gran_dmt_rolling.cpp | 746 ++++++++++++------------- 4 files changed, 684 insertions(+), 631 deletions(-) diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index a8386238d7..0c2aaed403 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -39,15 +39,19 @@ using namespace MathConst; // XYZ PLANE need to be 0,1,2 enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER,REGION}; -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,BONDED_HISTORY}; +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,JKR_ROLLING,DMT_ROLLING}; enum{NONE,CONSTANT,EQUAL}; +enum {TSUJI, BRILLIANTOV}; +enum {INDEP, BRILLROLL}; + #define BIG 1.0e20 +#define EPSILON 1e-10 /* ---------------------------------------------------------------------- */ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), idregion(NULL), shearone(NULL), fix_rigid(NULL), mass_rigid(NULL) + Fix(lmp, narg, arg), idregion(NULL), shearone(NULL), fix_rigid(NULL), mass_rigid(NULL) { if (narg < 4) error->all(FLERR,"Illegal fix wall/gran command"); @@ -62,7 +66,8 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[3],"hooke") == 0) pairstyle = HOOKE; else if (strcmp(arg[3],"hooke/history") == 0) pairstyle = HOOKE_HISTORY; else if (strcmp(arg[3],"hertz/history") == 0) pairstyle = HERTZ_HISTORY; - //else if (strcmp(arg[3],"bonded/history") == 0) pairstyle = BONDED_HISTORY; + else if (strcmp(arg[3],"dmt/rolling") == 0) pairstyle = DMT_ROLLING; + //else if (strcmp(arg[3],"jkr/rolling") == 0) pairstyle = JKR_ROLLING; else error->all(FLERR,"Invalid fix wall/gran interaction style"); history = restart_peratom = 1; @@ -72,7 +77,8 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : int iarg; - if (pairstyle != BONDED_HISTORY) { + if (pairstyle != JKR_ROLLING && pairstyle != DMT_ROLLING) { + sheardim = 3; if (narg < 11) error->all(FLERR,"Illegal fix wall/gran command"); kn = force->numeric(FLERR,arg[4]); @@ -101,20 +107,42 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : iarg = 10; } else { - if (narg < 10) error->all(FLERR,"Illegal fix wall/gran command"); + if (narg < 12) error->all(FLERR,"Illegal fix wall/gran command"); - E = force->numeric(FLERR,arg[4]); - G = force->numeric(FLERR,arg[5]); - SurfEnergy = force->numeric(FLERR,arg[6]); - // Note: this doesn't get used, check w/ Jeremy? + sheardim = 7; + Emod = force->numeric(FLERR,arg[4]); + Gmod = force->numeric(FLERR,arg[5]); + xmu = force->numeric(FLERR,arg[6]); gamman = force->numeric(FLERR,arg[7]); - - xmu = force->numeric(FLERR,arg[8]); - // pois = E/(2.0*G) - 1.0; - // kn = 2.0*E/(3.0*(1.0+pois)*(1.0-pois)); - // gammat=0.5*gamman; - - iarg = 9; + Ecoh = force->numeric(FLERR,arg[8]); + kR = force->numeric(FLERR,arg[9]); + muR = force->numeric(FLERR,arg[10]); + etaR = force->numeric(FLERR,arg[11]); + + //Defaults + normaldamp = TSUJI; + rollingdamp = INDEP; + + iarg = 12; + for (int iiarg=iarg; iiarg < narg; ++iiarg){ + if (strcmp(arg[iiarg], "normaldamp") == 0){ + if(iiarg+2 > narg) error->all(FLERR, "Invalid fix/wall/gran region command"); + if (strcmp(arg[iiarg+1],"tsuji") == 0){ + normaldamp = TSUJI; + alpha = gamman; + } + else if (strcmp(arg[iiarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for fix wall/gran dmt/rolling"); + iarg += 2; + } + if (strcmp(arg[iiarg], "rollingdamp") == 0){ + if(iiarg+2 > narg) error->all(FLERR, "Invalid fix/wall/gran region command"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for fix wall/gran dmt/rolling"); + iarg += 2; + } + } } // wallstyle args @@ -224,9 +252,6 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : // perform initial allocation of atom-based arrays // register with Atom class - if (pairstyle == BONDED_HISTORY) sheardim = 7; - else sheardim = 3; - shearone = NULL; grow_arrays(atom->nmax); atom->add_callback(0); @@ -448,27 +473,31 @@ void FixWallGran::post_force(int vflag) } // invoke sphere/wall interaction - double *contact; + double *contact; if (peratom_flag) contact = array_atom[i]; else - contact = NULL; + contact = NULL; if (pairstyle == HOOKE) hooke(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff, contact); + omega[i],torque[i],radius[i],meff, contact); else if (pairstyle == HOOKE_HISTORY) hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], - contact); + omega[i],torque[i],radius[i],meff,shearone[i], + contact); else if (pairstyle == HERTZ_HISTORY) hertz_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], - contact); - else if (pairstyle == BONDED_HISTORY) - bonded_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], - contact); + omega[i],torque[i],radius[i],meff,shearone[i], + contact); + else if (pairstyle == DMT_ROLLING) + dmt_rolling(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i], + contact); + /*else if (pairstyle == JKR_ROLLING) + jkr_rolling(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,shearone[i], + contact);*/ } } } @@ -484,9 +513,9 @@ void FixWallGran::post_force_respa(int vflag, int ilevel, int iloop) /* ---------------------------------------------------------------------- */ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, - double *vwall, double *v, - double *f, double *omega, double *torque, - double radius, double meff, double* contact) + double *vwall, double *v, + double *f, double *omega, double *torque, + double radius, double meff, double* contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -554,10 +583,10 @@ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, fz = dz*ccel + fs3; if (peratom_flag){ - contact[1] = fx; - contact[2] = fy; - contact[3] = fz; - } + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } f[0] += fx; f[1] += fy; @@ -574,10 +603,10 @@ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, /* ---------------------------------------------------------------------- */ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, - double *vwall, double *v, - double *f, double *omega, double *torque, - double radius, double meff, double *shear, - double *contact) + double *vwall, double *v, + double *f, double *omega, double *torque, + double radius, double meff, double *shear, + double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -659,11 +688,11 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, if (fs > fn) { if (shrmag != 0.0) { shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) - - meff*gammat*vtr1/kt; + meff*gammat*vtr1/kt; shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) - - meff*gammat*vtr2/kt; + meff*gammat*vtr2/kt; shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) - - meff*gammat*vtr3/kt; + meff*gammat*vtr3/kt; fs1 *= fn/fs ; fs2 *= fn/fs; fs3 *= fn/fs; @@ -697,10 +726,10 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, /* ---------------------------------------------------------------------- */ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, - double *vwall, double rwall, double *v, - double *f, double *omega, double *torque, - double radius, double meff, double *shear, - double *contact) + double *vwall, double rwall, double *v, + double *f, double *omega, double *torque, + double radius, double meff, double *shear, + double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; @@ -789,11 +818,11 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, if (fs > fn) { if (shrmag != 0.0) { shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) - - meff*gammat*vtr1/kt; + meff*gammat*vtr1/kt; shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) - - meff*gammat*vtr2/kt; + meff*gammat*vtr2/kt; shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) - - meff*gammat*vtr3/kt; + meff*gammat*vtr3/kt; fs1 *= fn/fs ; fs2 *= fn/fs; fs3 *= fn/fs; @@ -807,10 +836,10 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, fz = dz*ccel + fs3; if (peratom_flag){ - contact[1] = fx; - contact[2] = fy; - contact[3] = fz; - } + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } f[0] += fx; f[1] += fy; @@ -825,34 +854,44 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, } -/* ---------------------------------------------------------------------- */ - -void FixWallGran::bonded_history(double rsq, double dx, double dy, double dz, - double *vwall, double rwall, double *v, - double *f, double *omega, double *torque, - double radius, double meff, double *shear, - double *contact) +void FixWallGran::dmt_rolling(double rsq, double dx, double dy, double dz, + double *vwall, double rwall, double *v, + double *f, double *omega, double *torque, + double radius, double meff, double *shear, + double *contact) { - double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3,damp,ccel,vtr1,vtr2,vtr3,vrel; - double fn,fs,fs1,fs2,fs3,fx,fy,fz,tor1,tor2,tor3; - double shrmag,rsht,polyhertz,rinv,rsqinv; - - double pois,E_eff,G_eff,rad_eff; - double a0,Fcrit,delcrit,delcritinv; - double overlap,olapsq,olapcubed,sqrtterm,tmp,keyterm,keyterm2,keyterm3; - double aovera0,foverFc; - double gammatsuji; - - double ktwist,kroll,twistcrit,rollcrit; + int i,j,ii,jj,inum,jnum; + int itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,r,rinv,rsqinv,R,a; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + double Fhz, Fdamp, Fdmt, Fne, Fntot, Fscrit, Frcrit; + double overlap; + double mi,mj,damp,ccel,tor1,tor2,tor3; double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double magtwist,magtortwist; - double magrollsq,magroll,magrollinv,magtorroll; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + double signtwist, magtwist, magtortwist, Mtcrit; + double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; + double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; + r = sqrt(rsq); rinv = 1.0/r; rsqinv = 1.0/rsq; + radsum = radius + rwall; + if (rwall == 0) R = radius; + else R = radius*rwall/(radius+rwall); + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + // relative translational velocity vr1 = v[0] - vwall[0]; @@ -861,13 +900,37 @@ void FixWallGran::bonded_history(double rsq, double dx, double dy, double dz, // normal component - vnnr = vr1*dx + vr2*dy + vr3*dz; - vn1 = dx*vnnr / rsq; - vn2 = dy*vnnr / rsq; - vn3 = dz*vnnr / rsq; + vnnr = vr1*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; - // tangential component + //**************************************** + //Normal force = Hertzian contact + DMT + damping + //**************************************** + overlap = radsum - r; + a = sqrt(R*overlap); + kn = 4.0/3.0*Emod*a; + Fhz = kn*overlap; + + //Damping (based on Tsuji et al) + if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman; + else if (normaldamp == TSUJI) eta_N=alpha*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + //DMT + Fdmt = -4*MY_PI*Ecoh*R; + + Fne = Fhz + Fdmt; + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including shear history effects + //**************************************** + + // tangential component vt1 = vr1 - vn1; vt2 = vr2 - vn2; vt3 = vr3 - vn3; @@ -878,200 +941,182 @@ void FixWallGran::bonded_history(double rsq, double dx, double dy, double dz, wr2 = radius*omega[1] * rinv; wr3 = radius*omega[2] * rinv; - // normal forces = Hertzian contact + normal velocity damping - // material properties: currently assumes identical materials - - pois = E/(2.0*G) - 1.0; - E_eff=0.5*E/(1.0-pois*pois); - G_eff=G/(4.0-2.0*pois); - - // rwall = 0 is infinite wall radius of curvature (flat wall) - - if (rwall == 0) rad_eff = radius; - else rad_eff = radius*rwall/(radius+rwall); - - Fcrit = rad_eff * (3.0 * M_PI * SurfEnergy); - a0=pow(9.0*M_PI*SurfEnergy*rad_eff*rad_eff/E_eff,1.0/3.0); - delcrit = 1.0/rad_eff*(0.5 * a0*a0/pow(6.0,1.0/3.0)); - delcritinv = 1.0/delcrit; - - overlap = (radius-r) * delcritinv; - olapsq = overlap*overlap; - olapcubed = olapsq*overlap; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,THIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = pow(6.0,-TWOTHIRDS) * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3)); - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5)); - ccel = Fcrit*foverFc*rinv; - - // damp = meff*gamman*vnnr*rsqinv; - // ccel = kn*(radius-r)*rinv - damp; - // polyhertz = sqrt((radius-r)*radius); - // ccel *= polyhertz; - - // use Tsuji et al form - - polyhertz = 1.2728- 4.2783*0.9 + 11.087*0.9*0.9 - 22.348*0.9*0.9*0.9 + - 27.467*0.9*0.9*0.9*0.9 - 18.022*0.9*0.9*0.9*0.9*0.9 + - 4.8218*0.9*0.9*0.9*0.9*0.9*0.9; - - gammatsuji = 0.2*sqrt(meff*kn); - damp = gammatsuji*vnnr/rsq; - ccel = ccel - polyhertz * damp; - - // relative velocities - - vtr1 = vt1 - (dz*wr2-dy*wr3); - vtr2 = vt2 - (dx*wr3-dz*wr1); - vtr3 = vt3 - (dy*wr1-dx*wr2); + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); // shear history effects + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + // Rotate and update shear displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 if (shearupdate) { + rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shear[0] -= rsht*nx; + shear[1] -= rsht*ny; + shear[2] -= rsht*nz; + //Also rescale to preserve magnitude + shear[0] *= scalefac; + shear[1] *= scalefac; + shear[2] *= scalefac; + } + //Update shear history 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]*dx + shear[1]*dy + shear[2]*dz; - rsht = rsht*rsqinv; - if (shearupdate) { - shear[0] -= rsht*dx; - shear[1] -= rsht*dy; - shear[2] -= rsht*dz; - } // tangential forces = shear + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*Gmod*a; - fs1 = -polyhertz * (kt*shear[0] + meff*gammat*vtr1); - fs2 = -polyhertz * (kt*shear[1] + meff*gammat*vtr2); - fs3 = -polyhertz * (kt*shear[2] + meff*gammat*vtr3); - - kt=8.0*G_eff*a0*aovera0; - - // shear damping uses Tsuji et al form also - - fs1 = -kt*shear[0] - polyhertz*gammatsuji*vtr1; - fs2 = -kt*shear[1] - polyhertz*gammatsuji*vtr2; - fs3 = -kt*shear[2] - polyhertz*gammatsuji*vtr3; + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; // rescale frictional displacements and forces if needed + Fscrit = xmu * fabs(Fne); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + //Redundant, should be same as above? + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - fn = xmu * fabs(ccel*r + 2.0*Fcrit); - - if (fs > fn) { + if (fs > Fscrit) { if (shrmag != 0.0) { - shear[0] = (fn/fs) * (shear[0] + polyhertz*gammatsuji*vtr1/kt) - - polyhertz*gammatsuji*vtr1/kt; - shear[1] = (fn/fs) * (shear[1] + polyhertz*gammatsuji*vtr2/kt) - - polyhertz*gammatsuji*vtr2/kt; - shear[2] = (fn/fs) * (shear[2] + polyhertz*gammatsuji*vtr3/kt) - - polyhertz*gammatsuji*vtr3/kt; - fs1 *= fn/fs ; - fs2 *= fn/fs; - fs3 *= fn/fs; + //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; } else fs1 = fs2 = fs3 = 0.0; } - // calculate twisting and rolling components of torque - // NOTE: this assumes spheres! - - relrot1 = omega[0]; - relrot2 = omega[1]; - relrot3 = omega[2]; + //**************************************** + // Rolling force, including shear history effects + //**************************************** - // rolling velocity - // NOTE: this assumes mondisperse spheres! + relrot1 = omega[0]; //- omega[j][0]; TODO: figure out how to + relrot2 = omega[1]; //- omega[j][1]; incorporate wall angular + relrot3 = omega[2]; //- omega[j][2]; velocity - vrl1 = -rad_eff*rinv * (relrot2*dz - relrot3*dy); - vrl2 = -rad_eff*rinv * (relrot3*dx - relrot1*dz); - vrl3 = -rad_eff*rinv * (relrot1*dy - relrot2*dx); + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; else vrlmaginv = 0.0; - // bond history effects + // Rolling displacement + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); + rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; + if (shearupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + shear[3] -= rolldotn*nx; + shear[4] -= rolldotn*ny; + shear[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + shear[3] *= scalefac; + shear[4] *= scalefac; + shear[5] *= scalefac; + } + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + } - // rotate bonded displacements correctly + if (rollingdamp == BRILLROLL) etaR = muR*fabs(Fne); + fr1 = -kR*shear[3] - etaR*vrl1; + fr2 = -kR*shear[4] - etaR*vrl2; + fr3 = -kR*shear[5] - etaR*vrl3; - double rlt = shear[3]*dx + shear[4]*dy + shear[5]*dz; - rlt /= rsq; - shear[3] -= rlt*dx; - shear[4] -= rlt*dy; - shear[5] -= rlt*dz; + // rescale frictional displacements and forces if needed + Frcrit = muR * fabs(Fne); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + shear[3] = -1.0/kR*(Frcrit*fr1/fr + etaR*vrl1); + shear[4] = -1.0/kR*(Frcrit*fr2/fr + etaR*vrl2); + shear[5] = -1.0/kR*(Frcrit*fr3/fr + etaR*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } - // twisting torque - magtwist = rinv*(relrot1*dx + relrot2*dy + relrot3*dz); + //**************************************** + // Twisting torque, including shear history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) shear[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit){ + shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } - ktwist = 0.5*kt*(a0*aovera0)*(a0*aovera0); - magtortwist = -ktwist*shear[6] - - 0.5*polyhertz*gammatsuji*(a0*aovera0)*(a0*aovera0)*magtwist; - - twistcrit=TWOTHIRDS*a0*aovera0*Fcrit; - if (fabs(magtortwist) > twistcrit) - magtortwist = -twistcrit * magtwist/fabs(magtwist); - - // rolling torque - - magrollsq = shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]; - magroll = sqrt(magrollsq); - if (magroll != 0.0) magrollinv = 1.0/magroll; - else magrollinv = 0.0; - - kroll = 1.0*4.0*Fcrit*pow(aovera0,1.5); - magtorroll = -kroll*magroll - 0.1*gammat*vrlmag; - - rollcrit = 0.01; - if (magroll > rollcrit) magtorroll = -kroll*rollcrit; - - // forces & torques + // Apply forces & torques - fx = dx*ccel + fs1; - fy = dy*ccel + fs2; - fz = dz*ccel + fs3; + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; f[0] += fx; f[1] += fy; f[2] += fz; - if (peratom_flag){ - contact[1] = fx; - contact[2] = fy; - contact[3] = fz; - } + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; - tor1 = rinv * (dy*fs3 - dz*fs2); - tor2 = rinv * (dz*fs1 - dx*fs3); - tor3 = rinv * (dx*fs2 - dy*fs1); - torque[0] -= radius*tor1; - torque[1] -= radius*tor2; - torque[2] -= radius*tor3; + torque[0] -= radi*tor1; + torque[1] -= radi*tor2; + torque[2] -= radi*tor3; - torque[0] += magtortwist * dx*rinv; - torque[1] += magtortwist * dy*rinv; - torque[2] += magtortwist * dz*rinv; + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[0] += tortwist1; + torque[1] += tortwist2; + torque[2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[0] += torroll1; + torque[1] += torroll2; + torque[2] += torroll3; - torque[0] += magtorroll * (shear[4]*dz - shear[5]*dy)*rinv*magrollinv; - torque[1] += magtorroll * (shear[5]*dx - shear[3]*dz)*rinv*magrollinv; - torque[2] += magtorroll * (shear[3]*dy - shear[4]*dx)*rinv*magrollinv; } + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ @@ -1108,8 +1153,8 @@ void FixWallGran::copy_arrays(int i, int j, int delflag) for (int m = 0; m < sheardim; m++) shearone[j][m] = shearone[i][m]; if (peratom_flag){ - for (int m = 0; m < size_peratom_cols; m++) - array_atom[j][m] = array_atom[i][m]; + for (int m = 0; m < size_peratom_cols; m++) + array_atom[j][m] = array_atom[i][m]; } } @@ -1124,7 +1169,7 @@ void FixWallGran::set_arrays(int i) shearone[i][m] = 0; if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) - array_atom[i][m] = 0; + array_atom[i][m] = 0; } } diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran.h index f1a5dbc842..4212b96544 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran.h @@ -47,23 +47,31 @@ class FixWallGran : public Fix { void reset_dt(); void hooke(double, double, double, double, double *, - double *, double *, double *, double *, double, double, double*); + double *, double *, double *, double *, double, double, double*); void hooke_history(double, double, double, double, double *, - double *, double *, double *, double *, double, double, - double *, double *); + double *, double *, double *, double *, double, double, + double *, double *); void hertz_history(double, double, double, double, double *, double, - double *, double *, double *, double *, double, double, - double *, double *); - void bonded_history(double, double, double, double, double *, double, - double *, double *, double *, double *, double, double, - double *, double *); + double *, double *, double *, double *, double, double, + double *, double *); + void dmt_rolling(double, double, double, double, double *, double, + double *, double *, double *, double *, double, double, + double *, double *); + // void jkr_rolling(double, double, double, double, double *, double, + // double *, double *, double *, double *, double, double, + // double *, double *); protected: int wallstyle,wiggle,wshear,axis; int pairstyle,nlevels_respa; bigint time_origin; double kn,kt,gamman,gammat,xmu; - double E,G,SurfEnergy; + + //For DMT/ROLLING + int normaldamp, rollingdamp; + double Emod, Gmod, alpha, Ecoh, kR, muR, etaR; + + double lo,hi,cylradius; double amplitude,period,omega,vshear; double dt; diff --git a/src/GRANULAR/fix_wall_gran_region.cpp b/src/GRANULAR/fix_wall_gran_region.cpp index e00036c26a..71b6503f36 100644 --- a/src/GRANULAR/fix_wall_gran_region.cpp +++ b/src/GRANULAR/fix_wall_gran_region.cpp @@ -39,15 +39,15 @@ using namespace MathConst; // same as FixWallGran -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,BONDED_HISTORY}; +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,JKR_ROLLING,DMT_ROLLING}; #define BIG 1.0e20 /* ---------------------------------------------------------------------- */ FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) : - FixWallGran(lmp, narg, arg), region(NULL), region_style(NULL), ncontact(NULL), - walls(NULL), shearmany(NULL), c2r(NULL) + FixWallGran(lmp, narg, arg), region(NULL), region_style(NULL), ncontact(NULL), + walls(NULL), shearmany(NULL), c2r(NULL) { restart_global = 1; motion_resetflag = 0; @@ -114,7 +114,7 @@ void FixWallGranRegion::init() nregion != region->nregion) { char str[256]; sprintf(str,"Region properties for region %s changed between runs, " - "resetting its motion",idregion); + "resetting its motion",idregion); error->warning(FLERR,str); region->reset_vel(); } @@ -122,7 +122,7 @@ void FixWallGranRegion::init() if (motion_resetflag){ char str[256]; sprintf(str,"Region properties for region %s are inconsistent " - "with restart file, resetting its motion",idregion); + "with restart file, resetting its motion",idregion); error->warning(FLERR,str); region->reset_vel(); } @@ -253,22 +253,22 @@ void FixWallGranRegion::post_force(int vflag) contact = array_atom[i]; else contact = NULL; - + if (pairstyle == HOOKE) hooke(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff, contact); + omega[i],torque[i],radius[i],meff, contact); else if (pairstyle == HOOKE_HISTORY) hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff, - shearmany[i][c2r[ic]], contact); + omega[i],torque[i],radius[i],meff, + shearmany[i][c2r[ic]], contact); else if (pairstyle == HERTZ_HISTORY) hertz_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, - v[i],f[i],omega[i],torque[i], - radius[i],meff,shearmany[i][c2r[ic]], contact); - else if (pairstyle == BONDED_HISTORY) - bonded_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, - v[i],f[i],omega[i],torque[i], - radius[i],meff,shearmany[i][c2r[ic]], contact); + v[i],f[i],omega[i],torque[i], + radius[i],meff,shearmany[i][c2r[ic]], contact); + else if (pairstyle == DMT_ROLLING) + dmt_rolling(rsq,dx,dy,dz,vwall,region->contact[ic].radius, + v[i],f[i],omega[i],torque[i], + radius[i],meff,shearmany[i][c2r[ic]], contact); } } } @@ -394,7 +394,7 @@ void FixWallGranRegion::set_arrays(int i) ncontact[i] = 0; if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) - array_atom[i][m] = 0; + array_atom[i][m] = 0; } } diff --git a/src/GRANULAR/pair_gran_dmt_rolling.cpp b/src/GRANULAR/pair_gran_dmt_rolling.cpp index 08299f85b5..7a71fc7200 100644 --- a/src/GRANULAR/pair_gran_dmt_rolling.cpp +++ b/src/GRANULAR/pair_gran_dmt_rolling.cpp @@ -44,9 +44,9 @@ enum {INDEP, BRILLROLL}; /* ---------------------------------------------------------------------- */ PairGranDMTRolling::PairGranDMTRolling(LAMMPS *lmp) : - PairGranHookeHistory(lmp, 7), - E_one(0), G_one(0), pois(0), muS_one(0), cor(0), alpha_one(0), - Ecoh_one(0), kR_one(0), muR_one(0), etaR_one(0) + PairGranHookeHistory(lmp, 7), + E_one(0), G_one(0), pois(0), muS_one(0), cor(0), alpha_one(0), + Ecoh_one(0), kR_one(0), muR_one(0), etaR_one(0) { int ntypes = atom->ntypes; memory->create(E,ntypes+1,ntypes+1,"pair:E"); @@ -122,19 +122,19 @@ void PairGranDMTRolling::compute(int eflag, int vflag) // mass_body = mass of each rigid body if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); } double **x = atom->x; @@ -158,304 +158,304 @@ void PairGranDMTRolling::compute(int eflag, int vflag) // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - 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]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - jtype = type[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]; - radsum = radi + radj; - - if (rsq >= radsum*radsum){ - // unset non-touching neighbors - touch[jj] = 0; - shear = &allshear[size_history*jj]; - for (int k = 0; k < size_history; k++) - shear[k] = 0.0; - } else { - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/(radi+radj); - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - //**************************************** - //Normal force = Hertzian contact + DMT + damping - //**************************************** - overlap = radsum - r; - a = sqrt(R*overlap); - kn = 4.0/3.0*E[itype][jtype]*a; - Fhz = kn*overlap; - - //Damping (based on Tsuji et al) - if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - //DMT - Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; - - Fne = Fhz + Fdmt; - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including shear history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting - //delta/2, i.e. instead of radi, use distance to center of contact point? - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - touch[jj] = 1; - shear = &allshear[size_history*jj]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // Rotate and update shear displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (shearupdate) { - rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - shear[0] -= rsht*nx; - shear[1] -= rsht*ny; - shear[2] -= rsht*nz; - //Also rescale to preserve magnitude - shear[0] *= scalefac; - shear[1] *= scalefac; - shear[2] *= scalefac; - } - //Update shear history - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; - } - - // tangential forces = shear + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = muS[itype][jtype] * fabs(Fne); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - //**************************************** - // Rolling force, including shear history effects - //**************************************** - - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - - if (shearupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - shear[3] -= rolldotn*nx; - shear[4] -= rolldotn*ny; - shear[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - shear[3] *= scalefac; - shear[4] *= scalefac; - shear[5] *= scalefac; - } - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; - } - - k_R = kR[itype][jtype]; - if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; - else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); - fr1 = -k_R*shear[3] - eta_R*vrl1; - fr2 = -k_R*shear[4] - eta_R*vrl2; - fr3 = -k_R*shear[5] - eta_R*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR[itype][jtype] * fabs(Fne); - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - - - //**************************************** - // Twisting torque, including shear history effects - //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - shear[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit){ - shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - - if (force->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; - - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } + i = ilist[ii]; + itype = type[i]; + 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]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + jtype = type[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]; + radsum = radi + radj; + + if (rsq >= radsum*radsum){ + // unset non-touching neighbors + touch[jj] = 0; + shear = &allshear[size_history*jj]; + for (int k = 0; k < size_history; k++) + shear[k] = 0.0; + } else { + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/(radi+radj); + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + //**************************************** + //Normal force = Hertzian contact + DMT + damping + //**************************************** + overlap = radsum - r; + a = sqrt(R*overlap); + kn = 4.0/3.0*E[itype][jtype]*a; + Fhz = kn*overlap; + + //Damping (based on Tsuji et al) + if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + //DMT + Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; + + Fne = Fhz + Fdmt; + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including shear history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting + //delta/2, i.e. instead of radi, use distance to center of contact point? + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + touch[jj] = 1; + shear = &allshear[size_history*jj]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // Rotate and update shear displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (shearupdate) { + rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shear[0] -= rsht*nx; + shear[1] -= rsht*ny; + shear[2] -= rsht*nz; + //Also rescale to preserve magnitude + shear[0] *= scalefac; + shear[1] *= scalefac; + shear[2] *= scalefac; + } + //Update shear history + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + + // tangential forces = shear + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = muS[itype][jtype] * fabs(Fne); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + //**************************************** + // Rolling force, including shear history effects + //**************************************** + + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // Rolling displacement + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); + rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; + + if (shearupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + shear[3] -= rolldotn*nx; + shear[4] -= rolldotn*ny; + shear[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + shear[3] *= scalefac; + shear[4] *= scalefac; + shear[5] *= scalefac; + } + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + } + + k_R = kR[itype][jtype]; + if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; + else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); + fr1 = -k_R*shear[3] - eta_R*vrl1; + fr2 = -k_R*shear[4] - eta_R*vrl2; + fr3 = -k_R*shear[5] - eta_R*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = muR[itype][jtype] * fabs(Fne); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + + + //**************************************** + // Twisting torque, including shear history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + shear[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit){ + shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + + if (force->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; + + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); } + } } } @@ -483,14 +483,14 @@ void PairGranDMTRolling::settings(int narg, char **arg) etaR_one = new double[ntypes+1]; for (int i=0; i < ntypes;i++){ - E_one[i+1] = force->numeric(FLERR, arg[i]); - G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); - muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); - cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); - Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); - kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); - muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); - etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); + E_one[i+1] = force->numeric(FLERR, arg[i]); + G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); + muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); + cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); + Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); + kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); + muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); + etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); } //Defaults @@ -499,53 +499,53 @@ void PairGranDMTRolling::settings(int narg, char **arg) int iarg = 8*ntypes; while (iarg < narg){ - if (strcmp(arg[iarg],"normaldamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else if (strcmp(arg[iarg],"rollingdamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else{ - iarg +=1; - } + if (strcmp(arg[iarg],"normaldamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else if (strcmp(arg[iarg],"rollingdamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else{ + iarg +=1; + } } //Derived from inputs for (int i=1; i <= ntypes; i++){ - pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; - alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; - for (int j=i; j <= ntypes; j++){ - E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); - G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); - if (normaldamp == TSUJI){ - alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); - } - else if (normaldamp == BRILLIANTOV){ - gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); - } - muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); - Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); - kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); - etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); - muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); + pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; + alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; + for (int j=i; j <= ntypes; j++){ + E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); + G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); + if (normaldamp == TSUJI){ + alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); + } + else if (normaldamp == BRILLIANTOV){ + gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); } + muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); + Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); + kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); + etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); + muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); + } } } /* ---------------------------------------------------------------------- */ double PairGranDMTRolling::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - double &fforce) + double rsq, + double factor_coul, double factor_lj, + double &fforce) { double radi,radj,radsum; double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; @@ -565,9 +565,9 @@ double PairGranDMTRolling::single(int i, int j, int itype, int jtype, radsum = radi + radj; if (rsq >= radsum*radsum) { - fforce = 0.0; - svector[0] = svector[1] = svector[2] = svector[3] = 0.0; - return 0.0; + fforce = 0.0; + svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + return 0.0; } r = sqrt(rsq); @@ -623,9 +623,9 @@ double PairGranDMTRolling::single(int i, int j, int itype, int jtype, mi = rmass[i]; mj = rmass[j]; if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; } meff = mi*mj / (mi+mj); @@ -669,14 +669,14 @@ double PairGranDMTRolling::single(int i, int j, int itype, int jtype, double *allshear = fix_history->firstvalue[i]; for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; } double *shear = &allshear[size_history*neighprev]; shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); + shear[2]*shear[2]); // tangential forces = shear + tangential velocity damping kt=8.0*G[itype][jtype]*a; @@ -692,12 +692,12 @@ double PairGranDMTRolling::single(int i, int j, int itype, int jtype, Fscrit= muS[itype][jtype] * fabs(Fne); if (fs > Fscrit) { - if (shrmag != 0.0) { - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - fs *= Fscrit/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; + if (shrmag != 0.0) { + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + fs *= Fscrit/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; } // set all forces and return no energy -- GitLab From 5dafd03d1f261950ec0522e23cc9f6374a0a8549 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Thu, 10 May 2018 13:56:02 -0600 Subject: [PATCH 0004/1243] Various fixes to fix/wall/gran DMT --- src/GRANULAR/fix_wall_gran.cpp | 13 ++++++------- src/GRANULAR/fix_wall_gran_region.cpp | 6 ++---- src/GRANULAR/pair_gran_dmt_rolling.cpp | 1 + src/GRANULAR/pair_gran_hooke_history.cpp | 2 ++ src/GRANULAR/pair_gran_hooke_history.h | 1 + src/MAKE/Makefile.mpi | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 0c2aaed403..0cf1dde90b 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -879,7 +879,6 @@ void FixWallGran::dmt_rolling(double rsq, double dx, double dy, double dz, double tortwist1, tortwist2, tortwist3; double shrmag,rsht; - r = sqrt(rsq); rinv = 1.0/r; rsqinv = 1.0/rsq; @@ -888,9 +887,9 @@ void FixWallGran::dmt_rolling(double rsq, double dx, double dy, double dz, if (rwall == 0) R = radius; else R = radius*rwall/(radius+rwall); - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; + nx = dx*rinv; + ny = dy*rinv; + nz = dz*rinv; // relative translational velocity @@ -986,9 +985,8 @@ void FixWallGran::dmt_rolling(double rsq, double dx, double dy, double dz, Fscrit = xmu * fabs(Fne); // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - //Redundant, should be same as above? - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); if (fs > Fscrit) { if (shrmag != 0.0) { @@ -1050,6 +1048,7 @@ void FixWallGran::dmt_rolling(double rsq, double dx, double dy, double dz, // rescale frictional displacements and forces if needed Frcrit = muR * fabs(Fne); + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); if (fr > Frcrit) { diff --git a/src/GRANULAR/fix_wall_gran_region.cpp b/src/GRANULAR/fix_wall_gran_region.cpp index 71b6503f36..2f415a0bc6 100644 --- a/src/GRANULAR/fix_wall_gran_region.cpp +++ b/src/GRANULAR/fix_wall_gran_region.cpp @@ -217,7 +217,6 @@ void FixWallGranRegion::post_force(int vflag) } // process current contacts - for (int ic = 0; ic < nc; ic++) { // rsq = squared contact distance @@ -266,9 +265,8 @@ void FixWallGranRegion::post_force(int vflag) v[i],f[i],omega[i],torque[i], radius[i],meff,shearmany[i][c2r[ic]], contact); else if (pairstyle == DMT_ROLLING) - dmt_rolling(rsq,dx,dy,dz,vwall,region->contact[ic].radius, - v[i],f[i],omega[i],torque[i], - radius[i],meff,shearmany[i][c2r[ic]], contact); + dmt_rolling(rsq,dx,dy,dz,vwall,region->contact[ic].radius, v[i],f[i],omega[i],torque[i], radius[i],meff,shearmany[i][c2r[ic]], contact); + } } } diff --git a/src/GRANULAR/pair_gran_dmt_rolling.cpp b/src/GRANULAR/pair_gran_dmt_rolling.cpp index 7a71fc7200..f293998e92 100644 --- a/src/GRANULAR/pair_gran_dmt_rolling.cpp +++ b/src/GRANULAR/pair_gran_dmt_rolling.cpp @@ -372,6 +372,7 @@ void PairGranDMTRolling::compute(int eflag, int vflag) // rescale frictional displacements and forces if needed Frcrit = muR[itype][jtype] * fabs(Fne); + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); if (fr > Frcrit) { if (rollmag != 0.0) { diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index f1a155f2e4..2f56b53736 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -58,6 +58,8 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp, int _size_history) : Pai // set comm size needed by this Pair if used with fix rigid comm_forward = 1; + + nondefault_history_transfer = 0; //keep default behavior of history[i][j] = -history[j][i] } /* ---------------------------------------------------------------------- */ diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/GRANULAR/pair_gran_hooke_history.h index c35de04109..6d9980919b 100644 --- a/src/GRANULAR/pair_gran_hooke_history.h +++ b/src/GRANULAR/pair_gran_hooke_history.h @@ -42,6 +42,7 @@ class PairGranHookeHistory : public Pair { int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); double memory_usage(); + int nondefault_history_transfer; protected: double kn,kt,gamman,gammat,xmu; diff --git a/src/MAKE/Makefile.mpi b/src/MAKE/Makefile.mpi index aebb465454..f30220da3d 100644 --- a/src/MAKE/Makefile.mpi +++ b/src/MAKE/Makefile.mpi @@ -12,7 +12,7 @@ SHFLAGS = -fPIC DEPFLAGS = -M LINK = mpicxx -LINKFLAGS = -g -O +LINKFLAGS = -g -O3 LIB = SIZE = size -- GitLab From 2fa9a986de88ded5c0768be36b0a7935c2b5777a Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Thu, 21 Jun 2018 10:48:07 -0500 Subject: [PATCH 0005/1243] Strip out all but NEIGH_PURE_F and Loca from pair_kim Progress toward implementation of kim-api-v2 support --- src/KIM/pair_kim.cpp | 458 +++++-------------------------------------- src/KIM/pair_kim.h | 26 +-- 2 files changed, 56 insertions(+), 428 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index fe638214ba..8947bd6c3b 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -18,8 +18,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the openkim-api-v1.5.0 package and for use with - the kim-api-v1.6.0 (and newer) package + Designed for use with the kim-api-v1.6.0 (and newer) package ------------------------------------------------------------------------- */ #include @@ -42,13 +41,6 @@ #include "KIM_API.h" #include "KIM_API_status.h" -#ifndef KIM_API_VERSION_MAJOR -// support v1.5.0 -#define KIM_API_VERSION_MAJOR 1 -#define KIM_API_VERSION_MINOR 5 -#define KIM_API_VERSION_PATCH 0 -#endif - using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ @@ -81,10 +73,7 @@ PairKIM::PairKIM(LAMMPS *lmp) : kim_global_cutoff(0.0), lmps_maxalloc(0), kim_particleSpecies(0), - lmps_force_tmp(0), - lmps_stripped_neigh_list(0), - kim_iterator_position(0), - Rij(0) + lmps_stripped_neigh_list(0) { // Initialize Pair data members to appropriate values single_enable = 0; // We do not provide the Single() function @@ -115,7 +104,6 @@ PairKIM::~PairKIM() // clean up local memory used to support KIM interface memory->destroy(kim_particleSpecies); - memory->destroy(lmps_force_tmp); memory->destroy(lmps_stripped_neigh_list); // clean up allocated memory for standard Pair class usage @@ -126,9 +114,6 @@ PairKIM::~PairKIM() delete [] lmps_map_species_to_unique; } - // clean up Rij array - memory->destroy(Rij); - // clean up KIM interface (if necessary) kim_free(); @@ -150,11 +135,9 @@ void PairKIM::compute(int eflag , int vflag) // needs to be atom->nmax in length if (atom->nmax > lmps_maxalloc) { memory->destroy(kim_particleSpecies); - memory->destroy(lmps_force_tmp); lmps_maxalloc = atom->nmax; memory->create(kim_particleSpecies,lmps_maxalloc,"pair:kim_particleSpecies"); - memory->create(lmps_force_tmp,lmps_maxalloc,3,"pair:lmps_force_tmp"); } // kim_particleSpecies = KIM atom species for each LAMMPS atom @@ -167,11 +150,6 @@ void PairKIM::compute(int eflag , int vflag) for (int i = 0; i < nall; i++) { ielement = lmps_map_species_to_unique[species[i]]; ielement = MAX(ielement,0); - // @@ this (above line) provides bogus info - // @@ (when lmps_map_species_to_unique[species[i]]==-1) to KIM, but - // @@ I guess this only happens when lmps_hybrid==true, - // @@ and we are sure that iterator mode will - // @@ not use these atoms.... (?) kim_particleSpecies[i] = kim_particle_codes[ielement]; } @@ -193,16 +171,6 @@ void PairKIM::compute(int eflag , int vflag) // assemble force and particleVirial if needed if (!lmps_using_newton) comm->reverse_comm_pair(this); - // sum lmps_force_tmp to f if running in hybrid mode - if (lmps_hybrid) { - double **f = atom->f; - for (int i = 0; i < nall; i++) { - f[i][0] += lmps_force_tmp[i][0]; - f[i][1] += lmps_force_tmp[i][1]; - f[i][2] += lmps_force_tmp[i][2]; - } - } - if ((no_virial_fdotr_compute == 1) && (vflag_global)) { // flip sign and order of virial if KIM is computing it for (int i = 0; i < 3; ++i) virial[i] = -1.0*virial[i]; @@ -313,6 +281,7 @@ void PairKIM::settings(int narg, char **arg) strcpy(kim_modelname, arg[1]); // set print_kim_file + // @@@ should be removed for v2; update docs if ((2 == narg) || ('0' == *(arg[2]))) { print_kim_file = false; @@ -341,13 +310,19 @@ void PairKIM::coeff(int narg, char **arg) if (narg != 2 + 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"); + + int ilo,ihi,jlo,jhi; force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); // read args that map atom species to KIM elements // lmps_map_species_to_unique[i] = - // which element the Ith atom type is, -1 if NULL + // which element the Ith atom type is // lmps_num_unique_elements = # of unique elements // lmps_unique_elements = list of element names @@ -360,23 +335,20 @@ void PairKIM::coeff(int narg, char **arg) lmps_unique_elements = new char*[atom->ntypes]; for (i = 0; i < atom->ntypes; i++) lmps_unique_elements[i] = 0; + + // Assume all species arguments are valid + // errors will be detected by kim_api_init() matching lmps_num_unique_elements = 0; for (i = 2; i < narg; i++) { - if (strcmp(arg[i],"NULL") == 0) { - if (!lmps_hybrid) - error->all(FLERR,"Invalid args for non-hybrid pair coefficients"); - lmps_map_species_to_unique[i-1] = -1; - continue; - } - for (j = 0; j < lmps_num_unique_elements; j++) - if (strcmp(arg[i],lmps_unique_elements[j]) == 0) break; - lmps_map_species_to_unique[i-1] = j; - if (j == lmps_num_unique_elements) { - n = strlen(arg[i]) + 1; - lmps_unique_elements[j] = new char[n]; - strcpy(lmps_unique_elements[j],arg[i]); - lmps_num_unique_elements++; - } + for (j = 0; j < lmps_num_unique_elements; j++) + if (strcmp(arg[i],lmps_unique_elements[j]) == 0) break; + lmps_map_species_to_unique[i-1] = j; + if (j == lmps_num_unique_elements) { + n = strlen(arg[i]) + 1; + lmps_unique_elements[j] = new char[n]; + strcpy(lmps_unique_elements[j],arg[i]); + lmps_num_unique_elements++; + } } int count = 0; @@ -419,43 +391,18 @@ void PairKIM::init_style() else { kim_model_init_ok = true; - - // allocate enough memory to ensure we are safe - // (by using neighbor->oneatom) - if (kim_model_using_Rij) - memory->create(Rij,3*(neighbor->oneatom),"pair:Rij"); } } - // request none, half, or full neighbor list - // depending on KIM model requirement + // make sure comm_reverse expects (at most) 9 values when newton is off + if (!lmps_using_newton) comm_reverse_off = 9; + // request full neighbor list int irequest = neighbor->request(this,instance_me); - if (kim_model_using_cluster) - { - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 0; - } - else - { - // make sure comm_reverse expects (at most) 9 values when newton is off - if (!lmps_using_newton) comm_reverse_off = 9; - - if (kim_model_using_half) - { - neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full = 0; - // make sure half lists also include local-ghost pairs - if (lmps_using_newton) neighbor->requests[irequest]->newton = 2; - } - else - { - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 1; - // make sure full lists also include local-ghost pairs - if (lmps_using_newton) neighbor->requests[irequest]->newton = 0; - } - } + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + // make sure full lists also include local-ghost pairs + if (lmps_using_newton) neighbor->requests[irequest]->newton = 0; return; } @@ -476,27 +423,11 @@ double PairKIM::init_one(int i, int j) /* ---------------------------------------------------------------------- */ -void PairKIM::reinit() -{ - // This is called by fix-adapt - - // Call parent class implementation - Pair::reinit(); - - // Then reinit KIM model - int kimerror; - kimerror = pkim->model_reinit(); - kim_error(__LINE__,"model_reinit unsuccessful", kimerror); -} - -/* ---------------------------------------------------------------------- */ - int PairKIM::pack_reverse_comm(int n, int first, double *buf) { int i,m,last; double *fp; - if (lmps_hybrid) fp = &(lmps_force_tmp[0][0]); - else fp = &(atom->f[0][0]); + fp = &(atom->f[0][0]); m = 0; last = first + n; @@ -555,8 +486,7 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,m; double *fp; - if (lmps_hybrid) fp = &(lmps_force_tmp[0][0]); - else fp = &(atom->f[0][0]); + fp = &(atom->f[0][0]); m = 0; if ((kim_model_has_forces) && ((vflag_atom == 0) || @@ -643,13 +573,6 @@ int PairKIM::get_neigh(void **kimmdl,int *mode,int *request, int kimerror; PairKIM *self = (PairKIM *) pkim->get_sim_buffer(&kimerror); - if (self->kim_model_using_Rij) { - *pRij = &(self->Rij[0]); - } else { - *pRij = 0; - } - - // subvert KIM api by using direct access to self->list // // get neighObj from KIM API obj @@ -671,53 +594,7 @@ int PairKIM::get_neigh(void **kimmdl,int *mode,int *request, firstneigh = neiobj->firstneigh; // ptr to 1st J int value of each I atom if (*mode==0){ //iterator mode - if (*request==1) { //increment iterator - if (self->kim_iterator_position < inum) { - *atom = ilist[self->kim_iterator_position]; - *numnei = numneigh[*atom]; - - // strip off neighbor mask for molecular systems - if (!self->lmps_using_molecular) - *nei1atom = firstneigh[*atom]; - else - { - int n = *numnei; - int *ptr = firstneigh[*atom]; - int *lmps_stripped_neigh_list = self->lmps_stripped_neigh_list; - for (int i = 0; i < n; i++) - lmps_stripped_neigh_list[i] = *(ptr++) & NEIGHMASK; - *nei1atom = lmps_stripped_neigh_list; - } - - // set Rij if needed - if (self->kim_model_using_Rij) { - double* x = (double *) - (*pkim).get_data_by_index(self->kim_ind_coordinates, - &kimerror); - for (jj=0; jj < *numnei; jj++) { - int i = *atom; - j = (*nei1atom)[jj]; - self->Rij[jj*3 +0] = -x[i*3+0] + x[j*3+0]; - self->Rij[jj*3 +1] = -x[i*3+1] + x[j*3+1]; - self->Rij[jj*3 +2] = -x[i*3+2] + x[j*3+2]; - } - } - - // increment iterator - self->kim_iterator_position++; - - return KIM_STATUS_OK; //successful increment - } else if (self->kim_iterator_position == inum) { - *numnei = 0; - return KIM_STATUS_NEIGH_ITER_PAST_END; //reached end by iterator - } else if (self->kim_iterator_position > inum || inum < 0){ - self->error->one(FLERR, "KIM neighbor iterator exceeded range"); - } - } else if (*request == 0){ //restart iterator - self->kim_iterator_position = 0; - *numnei = 0; - return KIM_STATUS_NEIGH_ITER_INIT_OK; //succsesful restart - } + return KIM_STATUS_NEIGH_INVALID_MODE; //unsupported mode } else if (*mode == 1){//locator mode //... if (*request < inum) { @@ -737,18 +614,7 @@ int PairKIM::get_neigh(void **kimmdl,int *mode,int *request, *nei1atom = lmps_stripped_neigh_list; } - // set Rij if needed - if (self->kim_model_using_Rij){ - double* x = (double *) - (*pkim).get_data_by_index(self->kim_ind_coordinates, &kimerror); - for(int jj=0; jj < *numnei; jj++){ - int i = *atom; - int j = (*nei1atom)[jj]; - self->Rij[jj*3 +0] = -x[i*3+0] + x[j*3+0]; - self->Rij[jj*3 +1] = -x[i*3+1] + x[j*3+1]; - self->Rij[jj*3 +2] = -x[i*3+2] + x[j*3+2]; - } - } + *pRij = NULL; return KIM_STATUS_OK; //successful end } else if (*request >= nAtoms || inum < 0) @@ -800,8 +666,6 @@ void PairKIM::kim_init() { int kimerror; - // - // determine KIM Model capabilities (used in this function below) set_kim_model_has_flags(); @@ -827,40 +691,19 @@ void PairKIM::kim_init() test_descriptor_string = 0; } - // determine kim_model_using_* true/false values - // - // check for half or full list - kim_model_using_half = (pkim->is_half_neighbors(&kimerror)); - // - const char* NBC_method; - kimerror = pkim->get_NBC_method(&NBC_method); - kim_error(__LINE__,"NBC method not set",kimerror); - // check for CLUSTER mode - kim_model_using_cluster = (strcmp(NBC_method,"CLUSTER")==0); - // check if Rij needed for get_neigh - kim_model_using_Rij = ((strcmp(NBC_method,"NEIGH_RVEC_H")==0) || - (strcmp(NBC_method,"NEIGH_RVEC_F")==0)); - // get correct index of each variable in kim_api object - pkim->getm_index(&kimerror, 3*13, + pkim->getm_index(&kimerror, 3*12, "coordinates", &kim_ind_coordinates, 1, "cutoff", &kim_ind_cutoff, 1, "numberOfParticles", &kim_ind_numberOfParticles, 1, -#if KIM_API_VERSION_MAJOR == 1 && KIM_API_VERSON_MINOR == 5 - "numberParticleTypes", &kim_ind_numberOfSpecies, 1, - "particleTypes", &kim_ind_particleSpecies, 1, -#else "numberOfSpecies", &kim_ind_numberOfSpecies, 1, "particleSpecies", &kim_ind_particleSpecies, 1, -#endif - "numberContributingParticles", &kim_ind_numberContributingParticles, - kim_model_using_half, "particleEnergy", &kim_ind_particleEnergy, (int) kim_model_has_particleEnergy, "energy", &kim_ind_energy, (int) kim_model_has_energy, "forces", &kim_ind_forces, (int) kim_model_has_forces, - "neighObject", &kim_ind_neighObject, (int) !kim_model_using_cluster, - "get_neigh", &kim_ind_get_neigh, (int) !kim_model_using_cluster, + "neighObject", &kim_ind_neighObject, 1, + "get_neigh", &kim_ind_get_neigh, 1, "particleVirial", &kim_ind_particleVirial, (int) kim_model_has_particleVirial, "virial", &kim_ind_virial, no_virial_fdotr_compute); @@ -891,21 +734,17 @@ void PairKIM::set_statics() lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); int kimerror; - pkim->setm_data_by_index(&kimerror, 4*6, + pkim->setm_data_by_index(&kimerror, 4*5, kim_ind_numberOfSpecies, 1, (void *) &(atom->ntypes), 1, kim_ind_cutoff, 1, (void *) &(kim_global_cutoff), 1, kim_ind_numberOfParticles, 1, (void *) &lmps_local_tot_num_atoms, 1, - kim_ind_numberContributingParticles, 1, (void *) &(atom->nlocal), - (int) kim_model_using_half, kim_ind_energy, 1, (void *) &(eng_vdwl), (int) kim_model_has_energy, kim_ind_virial, 1, (void *) &(virial[0]), no_virial_fdotr_compute); kim_error(__LINE__, "setm_data_by_index", kimerror); - if (!kim_model_using_cluster) - { - kimerror = pkim->set_method_by_index(kim_ind_get_neigh, 1, - (func_ptr) &get_neigh); - kim_error(__LINE__, "set_method_by_index", kimerror); - } + + kimerror = pkim->set_method_by_index(kim_ind_get_neigh, 1, + (func_ptr) &get_neigh); + kim_error(__LINE__, "set_method_by_index", kimerror); pkim->set_sim_buffer((void *)this, &kimerror); kim_error(__LINE__, "set_sim_buffer", kimerror); @@ -942,13 +781,9 @@ void PairKIM::set_volatiles() if (kim_model_has_forces) { - if (lmps_hybrid) - kimerror = pkim->set_data_by_index(kim_ind_forces, nall*3, - (void*) &(lmps_force_tmp[0][0])); - else - kimerror = pkim->set_data_by_index(kim_ind_forces, nall*3, - (void*) &(atom->f[0][0])); - kim_error(__LINE__, "setm_data_by_index", kimerror); + kimerror = pkim->set_data_by_index(kim_ind_forces, nall*3, + (void*) &(atom->f[0][0])); + kim_error(__LINE__, "set_data_by_index", kimerror); } // subvert the KIM api by direct access to this->list in get_neigh @@ -994,16 +829,10 @@ void PairKIM::set_lmps_flags() } // determine if running with pair hybrid - lmps_hybrid = (force->pair_match("hybrid",0)); - - // support cluster mode if everything is just right - lmps_support_cluster = ((domain->xperiodic == 0 && - domain->yperiodic == 0 && - domain->zperiodic == 0 - ) - && - (comm->nprocs == 1) - ); + if (force->pair_match("hybrid",0)) + { + error->all(FLERR,"pair_kim does not support hybrid."); + } // determine unit system and set lmps_units flag if ((strcmp(update->unit_style,"real")==0)) @@ -1177,30 +1006,9 @@ void PairKIM::write_descriptor(char** test_descriptor_string) "\n" "CONVENTIONS:\n" "# Name Type\n" - "ZeroBasedLists flag\n"); - // can use iterator or locator neighbor mode, unless in hybrid mode - if (lmps_hybrid) - strcat(*test_descriptor_string, - "Neigh_IterAccess flag\n"); - else - strcat(*test_descriptor_string, - "Neigh_BothAccess flag\n\n"); - - strcat(*test_descriptor_string, - "NEIGH_PURE_H flag\n" - "NEIGH_PURE_F flag\n" - "NEIGH_RVEC_H flag\n" - "NEIGH_RVEC_F flag\n"); - // @@ add code for MI_OPBC_? support ???? - if (lmps_support_cluster) - { - strcat(*test_descriptor_string, - "CLUSTER flag\n\n"); - } - else - { - strcat(*test_descriptor_string, "\n"); - } + "ZeroBasedLists flag\n" + "Neigh_LocaAccess flag\n" + "NEIGH_PURE_F flag\n\n"); // Write input section strcat(*test_descriptor_string, @@ -1208,14 +1016,8 @@ void PairKIM::write_descriptor(char** test_descriptor_string) "MODEL_INPUT:\n" "# Name Type Unit Shape\n" "numberOfParticles integer none []\n" - "numberContributingParticles integer none []\n" -#if KIM_API_VERSION_MAJOR == 1 && KIM_API_VERSON_MINOR == 5 - "numberParticleTypes integer none []\n" - "particleTypes integer none " -#else "numberOfSpecies integer none []\n" "particleSpecies integer none " -#endif "[numberOfParticles]\n" "coordinates double length " "[numberOfParticles,3]\n" @@ -1256,161 +1058,3 @@ void PairKIM::write_descriptor(char** test_descriptor_string) return; } - -void *PairKIM::extract(const char *str, int &dim) -{ - void *paramData; - int kimerror=0; - int ier; - int dummyint; - int isIndexed = 0; - const int MAXLINE = 1024; - int rank; - int validParam = 0; - int numParams; - int *speciesIndex = new int[MAXLINE]; - char *paramStr = new char[MAXLINE]; - char *paramName; - char *indexStr; - char message[MAXLINE]; - int offset; - double* paramPtr; - - // set dim to 0, we will always deal with scalars to circumvent lammps species - // indexing - dim = 0; - - // copy the input str into paramStr for parsing - strcpy(paramStr, str); - // get the name of the parameter (whatever is before ":") - paramName = strtok(paramStr, ":"); - if (0 == strcmp(paramName, str)) - paramName = (char*) str; - else - isIndexed = 1; - - // parse the rest of the string into tokens deliminated by "," and convert - // them to integers, saving them into speciesIndex - int count = -1; - if (isIndexed == 1) - { - while((indexStr = strtok(NULL, ",")) != NULL) - { - count++; - ier = sscanf(indexStr, "%d", &speciesIndex[count]); - if (ier != 1) - { - ier = -1; - break; - } - } - } - if (ier == -1) - { - delete [] speciesIndex, speciesIndex = 0; - delete [] paramStr, paramStr = 0; - kim_error(__LINE__,"error in PairKIM::extract(), invalid parameter-indicie format", KIM_STATUS_FAIL); - } - - // check to make sure that the requested parameter is a valid free parameter - - kimerror = pkim->get_num_params(&numParams, &dummyint); - kim_error(__LINE__, "get_num_free_params", kimerror); - char **freeParamNames = new char*[numParams]; - for (int k = 0; k < numParams; k++) - { - kimerror = pkim->get_free_parameter(k, (const char**) &freeParamNames[k]); - kim_error(__LINE__, "get_free_parameter", kimerror); - if (0 == strcmp(paramName, freeParamNames[k])) - { - validParam = 1; - break; - } - } - delete [] freeParamNames, freeParamNames = 0; - if (validParam == 0) - { - sprintf(message, "Invalid parameter to adapt: \"%s\" is not a FREE_PARAM", paramName); - delete [] speciesIndex, speciesIndex = 0; - delete [] paramStr, paramStr = 0; - kim_error(__LINE__, message, KIM_STATUS_FAIL); - } - - // get the parameter arry from pkim object - paramData = pkim->get_data(paramName, &kimerror); - if (kimerror == KIM_STATUS_FAIL) - { - delete [] speciesIndex, speciesIndex = 0; - delete [] paramStr, paramStr = 0; - } - kim_error(__LINE__,"get_data",kimerror); - - // get rank and shape of parameter - rank = (*pkim).get_rank(paramName, &kimerror); - if (kimerror == KIM_STATUS_FAIL) - { - delete [] speciesIndex, speciesIndex = 0; - delete [] paramStr, paramStr = 0; - } - kim_error(__LINE__,"get_rank",kimerror); - - int *shape = new int[MAXLINE]; - dummyint = (*pkim).get_shape(paramName, shape, &kimerror); - if (kimerror == KIM_STATUS_FAIL) - { - delete [] speciesIndex, speciesIndex = 0; - delete [] paramStr, paramStr = 0; - delete [] shape, shape = 0; - } - kim_error(__LINE__,"get_shape",kimerror); - - delete [] paramStr, paramStr = 0; - // check that number of inputs is rank, and that input indicies are less than - // their respective dimensions in shape - if ((count+1) != rank) - { - sprintf(message, "Number of input indicies not equal to rank of specified parameter (%d)", rank); - kimerror = KIM_STATUS_FAIL; - delete [] speciesIndex, speciesIndex = 0; - delete [] shape, shape = 0; - kim_error(__LINE__,message, kimerror); - } - if (isIndexed == 1) - { - for (int i=0; i <= count; i++) - { - if (shape[i] <= speciesIndex[i] || speciesIndex[i] < 0) - { - kimerror = KIM_STATUS_FAIL; - break; - } - } - } - delete [] shape, shape = 0; - if (kimerror == KIM_STATUS_FAIL) - { - sprintf(message, "One or more parameter indicies out of bounds"); - delete [] speciesIndex, speciesIndex = 0; - kim_error(__LINE__, message, kimerror); - } - - // Cast it to a double - paramPtr = static_cast(paramData); - - // If it is indexed (not just a scalar for the whole model), then get pointer - // corresponding to specified indicies by calculating the adress offset using - // specified indicies and the shape - if (isIndexed == 1) - { - offset = 0; - for (int i = 0; i < (rank-1); i++) - { - offset = (offset + speciesIndex[i]) * shape[i+1]; - } - offset = offset + speciesIndex[(rank - 1)]; - paramPtr = (paramPtr + offset); - } - delete [] speciesIndex, speciesIndex = 0; - - return ((void*) paramPtr); -} diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index fb4cda8af9..493aa9066a 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -18,8 +18,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the openkim-api-v1.5.0 package and for use with - the kim-api-v1.6.0 (and newer) package + Designed for use with the kim-api-v1.6.0 (and newer) package ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS @@ -49,11 +48,9 @@ namespace LAMMPS_NS { virtual void coeff(int, char**); virtual void init_style(); virtual double init_one(int, int); - virtual void reinit(); virtual int pack_reverse_comm(int, int, double*); virtual void unpack_reverse_comm(int, int*, double*); virtual double memory_usage(); - void *extract(const char *, int &); private: // (nearly) all bool flags are not initialized in constructor, but set @@ -80,9 +77,6 @@ namespace LAMMPS_NS { // values set in set_lmps_flags(), called from init_style() bool lmps_using_newton; bool lmps_using_molecular; - bool lmps_hybrid; // true if running with pair hybrid - bool lmps_support_cluster; // true if running in mode compat. - // with CLUSTER enum unit_sys {REAL, METAL, SI, CGS, ELECTRON}; unit_sys lmps_units; @@ -95,9 +89,6 @@ namespace LAMMPS_NS { // values set in kim_init(), after call to string_init(_) bool kim_init_ok; - bool kim_model_using_half; - bool kim_model_using_cluster; - bool kim_model_using_Rij; int kim_ind_coordinates; int kim_ind_numberOfParticles; int kim_ind_numberContributingParticles; @@ -125,16 +116,9 @@ namespace LAMMPS_NS { // values set in compute() int lmps_maxalloc; // max allocated memory value int* kim_particleSpecies; // array of KIM particle species - double** lmps_force_tmp; // temp storage for f, when running in - // hybrid mode needed to avoid resetting - // f to zero in each object int* lmps_stripped_neigh_list; // neighbors of one atom, used when LAMMPS // is in molecular mode - // values used in get_neigh() - int kim_iterator_position; //get_neigh iterator current position - double *Rij; - // KIM specific helper functions void kim_error(int, const char *, int); void kim_init(); @@ -199,19 +183,19 @@ Self-explanatory. Check the input script or data file. W: KIM Model does not provide `energy'; Potential energy will be zero -UNDOCUMENTED +Self-explanatory. W: KIM Model does not provide `forces'; Forces will be zero -UNDOCUMENTED +Self-explanatory. W: KIM Model does not provide `particleEnergy'; energy per atom will be zero -UNDOCUMENTED +Self-explanatory. W: KIM Model does not provide `particleVirial'; virial per atom will be zero -UNDOCUMENTED + E: Test_descriptor_string already allocated -- GitLab From 8bbba22867fd451d451875b72b3c462b79815c9d Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Fri, 22 Jun 2018 13:33:15 -0500 Subject: [PATCH 0006/1243] First working version of pair_kim with kim-api-v2 --- lib/kim/Install.py | 8 +- lib/kim/Makefile.lammps | 6 +- src/KIM/pair_kim.cpp | 685 ++++++++++++++++------------------------ src/KIM/pair_kim.h | 40 ++- 4 files changed, 293 insertions(+), 446 deletions(-) diff --git a/lib/kim/Install.py b/lib/kim/Install.py index d098250906..1bcaffd34a 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -21,7 +21,7 @@ Syntax from lib dir: python Install.py -b -v version -a kim-name specify one or more options, order does not matter -v = version of KIM API library to use - default = kim-api-v1.9.5 (current as of May 2018) + default = kim-api-v2.0.0-beta.0 (current as of June 2018) -b = download and build base KIM API library with example Models this will delete any previous installation in the current folder -n = do NOT download and build base KIM API library. @@ -109,7 +109,7 @@ nargs = len(args) if nargs == 0: error() thisdir = os.environ['PWD'] -version = "kim-api-v1.9.5" +version = "kim-api-v2.0.0-beta.0" buildflag = False everythingflag = False @@ -234,7 +234,7 @@ if buildflag: # add all OpenKIM models, if desired if everythingflag: print("Adding all OpenKIM models, this will take a while ...") - cmd = '%s/bin/kim-api-v1-collections-management install system OpenKIM' % (kimdir) + cmd = '%s/bin/kim-api-v2-collections-management install system OpenKIM' % (kimdir) txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) if verboseflag: print(txt.decode("UTF-8")) @@ -251,6 +251,6 @@ if addflag: error() # download single model - cmd = '%s/bin/kim-api-v1-collections-management install system %s' % (kimdir.decode("UTF-8"), addmodelname) + cmd = '%s/bin/kim-api-v2-collections-management install system %s' % (kimdir.decode("UTF-8"), addmodelname) txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) if verboseflag: print (txt.decode("UTF-8")) diff --git a/lib/kim/Makefile.lammps b/lib/kim/Makefile.lammps index d73891d1e2..c7c9d9fd2f 100644 --- a/lib/kim/Makefile.lammps +++ b/lib/kim/Makefile.lammps @@ -18,10 +18,10 @@ include ../../lib/kim/Makefile.KIM_DIR -ifeq ($(wildcard $(KIM_INSTALL_DIR)/bin/kim-api-v1-build-config),) - KIM_CONFIG_HELPER = kim-api-v1-build-config +ifeq ($(wildcard $(KIM_INSTALL_DIR)/bin/kim-api-v2-build-config),) + KIM_CONFIG_HELPER = kim-api-v2-build-config else - KIM_CONFIG_HELPER = $(KIM_INSTALL_DIR)/bin/kim-api-v1-build-config + KIM_CONFIG_HELPER = $(KIM_INSTALL_DIR)/bin/kim-api-v2-build-config endif ifeq ($(shell $(KIM_CONFIG_HELPER) --version 2> /dev/null),) $(error $(KIM_CONFIG_HELPER) utility is not available. Something is wrong with your KIM API package setup) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 8947bd6c3b..413c5303e1 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -37,10 +37,6 @@ #include "domain.h" #include "error.h" -// includes from KIM -#include "KIM_API.h" -#include "KIM_API_status.h" - using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ @@ -55,24 +51,15 @@ PairKIM::PairKIM(LAMMPS *lmp) : lmps_num_unique_elements(0), lmps_units(METAL), pkim(0), - kim_ind_coordinates(-1), - kim_ind_numberOfParticles(-1), - kim_ind_numberContributingParticles(-1), - kim_ind_numberOfSpecies(-1), - kim_ind_particleSpecies(-1), - kim_ind_get_neigh(-1), - kim_ind_neighObject(-1), - kim_ind_cutoff(-1), - kim_ind_energy(-1), - kim_ind_particleEnergy(-1), - kim_ind_forces(-1), - kim_ind_virial(-1), - kim_ind_particleVirial(-1), + pargs(0), kim_particle_codes(0), lmps_local_tot_num_atoms(0), - kim_global_cutoff(0.0), + kim_global_influence_distance(0.0), + kim_number_of_cutoffs(0), + kim_cutoff_values(0), lmps_maxalloc(0), kim_particleSpecies(0), + kim_particleContributing(0), lmps_stripped_neigh_list(0) { // Initialize Pair data members to appropriate values @@ -104,6 +91,7 @@ PairKIM::~PairKIM() // clean up local memory used to support KIM interface memory->destroy(kim_particleSpecies); + memory->destroy(kim_particleContributing); memory->destroy(lmps_stripped_neigh_list); // clean up allocated memory for standard Pair class usage @@ -131,13 +119,27 @@ void PairKIM::compute(int eflag , int vflag) else ev_unset(); - // grow kim_particleSpecies array if necessary + // grow kim_particleSpecies and kim_particleContributing array if necessary // needs to be atom->nmax in length if (atom->nmax > lmps_maxalloc) { memory->destroy(kim_particleSpecies); + memory->destroy(kim_particleContributing); lmps_maxalloc = atom->nmax; - memory->create(kim_particleSpecies,lmps_maxalloc,"pair:kim_particleSpecies"); + memory->create(kim_particleSpecies,lmps_maxalloc, + "pair:kim_particleSpecies"); + int kimerror = pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::particleSpeciesCodes, + kim_particleSpecies); + memory->create(kim_particleContributing,lmps_maxalloc, + "pair:kim_particleContributing"); + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::particleContributing, + kim_particleContributing); + if (kimerror) + error->all( + FLERR, + "Unable to set KIM particle species codes and/or contributing"); } // kim_particleSpecies = KIM atom species for each LAMMPS atom @@ -151,23 +153,17 @@ void PairKIM::compute(int eflag , int vflag) ielement = lmps_map_species_to_unique[species[i]]; ielement = MAX(ielement,0); kim_particleSpecies[i] = kim_particle_codes[ielement]; + + kim_particleContributing[i] = ( (inlocal) ? 1 : 0 ); } // pass current atom pointers to KIM set_volatiles(); - pkim->setm_compute_by_index(&kimerror,3*3, - kim_ind_particleEnergy, eflag_atom, - (int) kim_model_has_particleEnergy, - kim_ind_particleVirial, vflag_atom, - (int) kim_model_has_particleVirial, - kim_ind_virial, vflag_global!=0, - no_virial_fdotr_compute); - kim_error(__LINE__,"setm_compute_by_index",kimerror); - // compute via KIM model - kimerror = pkim->model_compute(); - kim_error(__LINE__,"PairKIM::pkim->model_compute() error",kimerror); + kimerror = pkim->Compute(pargs); + if (kimerror) error->all(FLERR,"KIM Compute returned error"); + // assemble force and particleVirial if needed if (!lmps_using_newton) comm->reverse_comm_pair(this); @@ -280,17 +276,6 @@ void PairKIM::settings(int narg, char **arg) kim_modelname = new char[nmlen+1]; strcpy(kim_modelname, arg[1]); - // set print_kim_file - // @@@ should be removed for v2; update docs - if ((2 == narg) || ('0' == *(arg[2]))) - { - print_kim_file = false; - } - else - { - print_kim_file = true; - } - return; } @@ -385,13 +370,6 @@ void PairKIM::init_style() if (!kim_init_ok) { kim_init(); - kimerror = pkim->model_init(); - if (kimerror != KIM_STATUS_OK) - kim_error(__LINE__, "KIM API:model_init() failed", kimerror); - else - { - kim_model_init_ok = true; - } } // make sure comm_reverse expects (at most) 9 values when newton is off @@ -418,7 +396,7 @@ double PairKIM::init_one(int i, int j) if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - return kim_global_cutoff; + return kim_global_influence_distance; } /* ---------------------------------------------------------------------- */ @@ -554,38 +532,31 @@ double PairKIM::memory_usage() KIM-specific interface ------------------------------------------------------------------------- */ -void PairKIM::kim_error(int ln, const char* msg, int errcode) +int PairKIM::get_neigh(void const * const dataObject, + int const numberOfCutoffs, double const * const cutoffs, + int const neighborListIndex, int const particleNumber, + int * const numberOfNeighbors, + int const ** const neighborsOfParticle) { - if (errcode == KIM_STATUS_OK) return; - KIM_API_model::report_error(ln,(char *) __FILE__, (char *) msg,errcode); - error->all(__FILE__,ln,"Internal KIM error"); + PairKIM const * const Model + = reinterpret_cast(dataObject); - return; -} + if ((numberOfCutoffs != 1) || (cutoffs[0] > Model->kim_cutoff_values[0])) + return true; -/* ---------------------------------------------------------------------- */ + if (neighborListIndex != 0) return true; -int PairKIM::get_neigh(void **kimmdl,int *mode,int *request, - int *atom, int *numnei, int **nei1atom, double **pRij) -{ - KIM_API_model *pkim = (KIM_API_model *) *kimmdl; + // initialize numNeigh + *numberOfNeighbors = 0; - int kimerror; - PairKIM *self = (PairKIM *) pkim->get_sim_buffer(&kimerror); - - // subvert KIM api by using direct access to self->list - // - // get neighObj from KIM API obj - // NeighList * neiobj = (NeighList * ) - // (*pkim).get_data_by_index(self->kim_ind_neighObject, &kimerror); - NeighList * neiobj = self->list; - - // subvert KIM api by using direct acces to self->lmps_local_tot_num_atoms - // - //int * pnAtoms = (int *) - // (*pkim).get_data_by_index(self->kim_ind_numberOfParticles, &kimerror); - //int nAtoms = *pnAtoms; - int nAtoms = self->lmps_local_tot_num_atoms; + if ((particleNumber >= Model->lmps_local_tot_num_atoms) || + (particleNumber < 0)) /* invalid id */ + { + return true; + } + + NeighList * neiobj = Model->list; + int nAtoms = Model->lmps_local_tot_num_atoms; int j, jj, inum, *ilist, *numneigh, **firstneigh; inum = neiobj->inum; //# of I atoms neighbors are stored for @@ -593,40 +564,21 @@ int PairKIM::get_neigh(void **kimmdl,int *mode,int *request, numneigh = neiobj->numneigh; // # of J neighbors for each I atom firstneigh = neiobj->firstneigh; // ptr to 1st J int value of each I atom - if (*mode==0){ //iterator mode - return KIM_STATUS_NEIGH_INVALID_MODE; //unsupported mode - } else if (*mode == 1){//locator mode - //... - if (*request < inum) { - *atom = *request; - *numnei = numneigh[*atom]; - - // strip off neighbor mask for molecular systems - if (!self->lmps_using_molecular) - *nei1atom = firstneigh[*atom]; - else - { - int n = *numnei; - int *ptr = firstneigh[*atom]; - int *lmps_stripped_neigh_list = self->lmps_stripped_neigh_list; - for (int i = 0; i < n; i++) - lmps_stripped_neigh_list[i] = *(ptr++) & NEIGHMASK; - *nei1atom = lmps_stripped_neigh_list; - } - - *pRij = NULL; - return KIM_STATUS_OK; //successful end - } - else if (*request >= nAtoms || inum < 0) - return KIM_STATUS_NEIGH_INVALID_REQUEST; - else if (*request >= inum) { - *atom = *request; - *numnei = 0; - return KIM_STATUS_OK; //successfull but no neighbors in the list - } - } else return KIM_STATUS_NEIGH_INVALID_MODE; //invalid mode + *numberOfNeighbors = numneigh[particleNumber]; - return -16; //should not get here: unspecified error + // strip off neighbor mask for molecular systems + if (!Model->lmps_using_molecular) + *neighborsOfParticle = firstneigh[particleNumber]; + else + { + int n = *numberOfNeighbors; + int *ptr = firstneigh[particleNumber]; + int *lmps_stripped_neigh_list = Model->lmps_stripped_neigh_list; + for (int i = 0; i < n; i++) + lmps_stripped_neigh_list[i] = *(ptr++) & NEIGHMASK; + *neighborsOfParticle = lmps_stripped_neigh_list; + } + return false; } /* ---------------------------------------------------------------------- */ @@ -637,19 +589,15 @@ void PairKIM::kim_free() if (kim_model_init_ok) { - kimerror = pkim->model_destroy(); - kim_model_init_ok = false; - } - if (kim_init_ok) - { - pkim->free(&kimerror); - kim_init_ok = false; - } - if (pkim != 0) - { - delete pkim; - pkim = 0; + int kimerror = pkim->ComputeArgumentsDestroy(&pargs); + if (kimerror) + error->all(FLERR,"Unable to destroy Compute Arguments Object"); + + KIM::Model::Destroy(&pkim); + kim_model_init_ok = false; } + kim_init_ok = false; + if (kim_particle_codes_ok) { delete [] kim_particle_codes; @@ -666,58 +614,47 @@ void PairKIM::kim_init() { int kimerror; - // determine KIM Model capabilities (used in this function below) - set_kim_model_has_flags(); - - // create appropriate KIM descriptor file - char* test_descriptor_string = 0; - // allocate memory for test_descriptor_string and write descriptor file - write_descriptor(&test_descriptor_string); - // print descriptor - if (print_kim_file) - { - error->message(FLERR, test_descriptor_string); - } - // initialize KIM model - pkim = new KIM_API_model(); - kimerror = pkim->string_init(test_descriptor_string, kim_modelname); - if (kimerror != KIM_STATUS_OK) - kim_error(__LINE__,"KIM initialization failed", kimerror); - else - { - kim_init_ok = true; - delete [] test_descriptor_string; - test_descriptor_string = 0; + int requestedUnitsAccepted; + kimerror = KIM::Model::Create( + KIM::NUMBERING::zeroBased, + lengthUnit, energyUnit, chargeUnit, temperatureUnit, timeUnit, + kim_modelname, + &requestedUnitsAccepted, + &pkim); + if (kimerror) + error->all(FLERR,"KIM ModelCreate failed"); + else { + if (!requestedUnitsAccepted) { + // @@@ error for now. Fix as needed + error->all(FLERR,"KIM Model did not accept the requested unit system"); + } + + kimerror = pkim->ComputeArgumentsCreate(&pargs); + if (kimerror) + error->all(FLERR,"KIM ComputeArgumentsCreate failed"); + else + kim_init_ok = true; } - // get correct index of each variable in kim_api object - pkim->getm_index(&kimerror, 3*12, - "coordinates", &kim_ind_coordinates, 1, - "cutoff", &kim_ind_cutoff, 1, - "numberOfParticles", &kim_ind_numberOfParticles, 1, - "numberOfSpecies", &kim_ind_numberOfSpecies, 1, - "particleSpecies", &kim_ind_particleSpecies, 1, - "particleEnergy", &kim_ind_particleEnergy, - (int) kim_model_has_particleEnergy, - "energy", &kim_ind_energy, (int) kim_model_has_energy, - "forces", &kim_ind_forces, (int) kim_model_has_forces, - "neighObject", &kim_ind_neighObject, 1, - "get_neigh", &kim_ind_get_neigh, 1, - "particleVirial", &kim_ind_particleVirial, - (int) kim_model_has_particleVirial, - "virial", &kim_ind_virial, no_virial_fdotr_compute); - kim_error(__LINE__,"getm_index",kimerror); + // determine KIM Model capabilities (used in this function below) + set_kim_model_has_flags(); // setup mapping between LAMMPS unique elements and KIM species codes kim_particle_codes = new int[lmps_num_unique_elements]; kim_particle_codes_ok = true; for(int i = 0; i < lmps_num_unique_elements; i++){ int kimerror; - kim_particle_codes[i] - = pkim->get_species_code(lmps_unique_elements[i], &kimerror); - kim_error(__LINE__, "create_kim_particle_codes: symbol not found ", - kimerror); + int supported; + int code; + kimerror = pkim->GetSpeciesSupportAndCode( + KIM::SpeciesName(lmps_unique_elements[i]), + &supported, + &code); + if (supported) + kim_particle_codes[i] = code; + else + error->all(FLERR,"create_kim_particle_codes: symbol not found "); } // set pointer values in KIM API object that will not change during run @@ -733,21 +670,26 @@ void PairKIM::set_statics() // set total number of atoms lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); - int kimerror; - pkim->setm_data_by_index(&kimerror, 4*5, - kim_ind_numberOfSpecies, 1, (void *) &(atom->ntypes), 1, - kim_ind_cutoff, 1, (void *) &(kim_global_cutoff), 1, - kim_ind_numberOfParticles, 1, (void *) &lmps_local_tot_num_atoms, 1, - kim_ind_energy, 1, (void *) &(eng_vdwl), (int) kim_model_has_energy, - kim_ind_virial, 1, (void *) &(virial[0]), no_virial_fdotr_compute); - kim_error(__LINE__, "setm_data_by_index", kimerror); + pkim->GetInfluenceDistance(&kim_global_influence_distance); + pkim->GetNeighborListCutoffsPointer(&kim_number_of_cutoffs, + &kim_cutoff_values); - kimerror = pkim->set_method_by_index(kim_ind_get_neigh, 1, - (func_ptr) &get_neigh); - kim_error(__LINE__, "set_method_by_index", kimerror); + int kimerror = pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, + &lmps_local_tot_num_atoms); + if (kim_model_has_energy) + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, + &(eng_vdwl)); - pkim->set_sim_buffer((void *)this, &kimerror); - kim_error(__LINE__, "set_sim_buffer", kimerror); + kimerror = pargs->SetCallbackPointer( + KIM::COMPUTE_CALLBACK_NAME::GetNeighborList, + KIM::LANGUAGE_NAME::cpp, + reinterpret_cast(get_neigh), + reinterpret_cast(this)); + + if (kimerror) + error->all(FLERR,"Unable to register KIM static pointers"); return; } @@ -758,56 +700,56 @@ void PairKIM::set_volatiles() { int kimerror; lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); - intptr_t nall = (intptr_t) lmps_local_tot_num_atoms; - pkim->setm_data_by_index(&kimerror, 4*2, - kim_ind_coordinates, 3*nall, (void*) &(atom->x[0][0]), 1, - kim_ind_particleSpecies, nall, (void*) kim_particleSpecies, 1); - kim_error(__LINE__, "setm_data_by_index", kimerror); + kimerror = pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::coordinates, + &(atom->x[0][0])); if (kim_model_has_particleEnergy && (eflag_atom == 1)) { - kimerror = pkim->set_data_by_index(kim_ind_particleEnergy, nall, - (void*) eatom); - kim_error(__LINE__, "set_data_by_index", kimerror); - } - - if (kim_model_has_particleVirial && (vflag_atom == 1)) - { - kimerror = pkim->set_data_by_index(kim_ind_particleVirial, 6*nall, - (void*) &(vatom[0][0])); - kim_error(__LINE__, "set_data_by_index", kimerror); + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialParticleEnergy, + eatom); } if (kim_model_has_forces) { - kimerror = pkim->set_data_by_index(kim_ind_forces, nall*3, - (void*) &(atom->f[0][0])); - kim_error(__LINE__, "set_data_by_index", kimerror); + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialForces, + &(atom->f[0][0])); } - // subvert the KIM api by direct access to this->list in get_neigh - // - //if (!kim_model_using_cluster) - // kimerror = pkim->set_data_by_index(kim_ind_neighObject, 1, - // (void*) this->list); - if (kim_model_has_particleVirial) { - if(vflag_atom != 1) { - pkim->set_compute_by_index(kim_ind_particleVirial, KIM_COMPUTE_FALSE, - &kimerror); - } else { - pkim->set_compute_by_index(kim_ind_particleVirial, KIM_COMPUTE_TRUE, - &kimerror); - } + if(vflag_atom != 1) { + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, + &(vatom[0][0])); + } else { + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, + reinterpret_cast(NULL)); + } } if (no_virial_fdotr_compute == 1) { - pkim->set_compute_by_index(kim_ind_virial, - ((vflag_global != 1) ? KIM_COMPUTE_FALSE : KIM_COMPUTE_TRUE), - &kimerror); + if (kim_model_has_virial) + { + if (vflag_global == 1) + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialVirial, + &(virial[0])); + else + kimerror = kimerror || pargs->SetArgumentPointer( + KIM::COMPUTE_ARGUMENT_NAME::partialVirial, + reinterpret_cast(NULL)); + } + } + + if (kimerror) + { + error->all(FLERR,"Unable to set KIM volatile pointers"); } return; @@ -835,20 +777,46 @@ void PairKIM::set_lmps_flags() } // determine unit system and set lmps_units flag - if ((strcmp(update->unit_style,"real")==0)) - lmps_units = REAL; - else if ((strcmp(update->unit_style,"metal")==0)) - lmps_units = METAL; - else if ((strcmp(update->unit_style,"si")==0)) - lmps_units = SI; - else if ((strcmp(update->unit_style,"cgs")==0)) - lmps_units = CGS; - else if ((strcmp(update->unit_style,"electron")==0)) - lmps_units = ELECTRON; - else if ((strcmp(update->unit_style,"lj")==0)) - error->all(FLERR,"LAMMPS unit_style lj not supported by KIM models"); - else - error->all(FLERR,"Unknown unit_style"); + if ((strcmp(update->unit_style,"real")==0)) { + lmps_units = REAL; + lengthUnit = KIM::LENGTH_UNIT::A; + energyUnit = KIM::ENERGY_UNIT::kcal_mol; + chargeUnit = KIM::CHARGE_UNIT::e; + temperatureUnit = KIM::TEMPERATURE_UNIT::K; + timeUnit = KIM::TIME_UNIT::fs; + } else if ((strcmp(update->unit_style,"metal")==0)) { + lmps_units = METAL; + lengthUnit = KIM::LENGTH_UNIT::A; + energyUnit = KIM::ENERGY_UNIT::eV; + chargeUnit = KIM::CHARGE_UNIT::e; + temperatureUnit = KIM::TEMPERATURE_UNIT::K; + timeUnit = KIM::TIME_UNIT::ps; + } else if ((strcmp(update->unit_style,"si")==0)) { + lmps_units = SI; + lengthUnit = KIM::LENGTH_UNIT::m; + energyUnit = KIM::ENERGY_UNIT::J; + chargeUnit = KIM::CHARGE_UNIT::C; + temperatureUnit = KIM::TEMPERATURE_UNIT::K; + timeUnit = KIM::TIME_UNIT::s; + } else if ((strcmp(update->unit_style,"cgs")==0)) { + lmps_units = CGS; + lengthUnit = KIM::LENGTH_UNIT::cm; + energyUnit = KIM::ENERGY_UNIT::erg; + chargeUnit = KIM::CHARGE_UNIT::statC; + temperatureUnit = KIM::TEMPERATURE_UNIT::K; + timeUnit = KIM::TIME_UNIT::s; + } else if ((strcmp(update->unit_style,"electron")==0)) { + lmps_units = ELECTRON; + lengthUnit = KIM::LENGTH_UNIT::Bohr; + energyUnit = KIM::ENERGY_UNIT::Hartree; + chargeUnit = KIM::CHARGE_UNIT::e; + temperatureUnit = KIM::TEMPERATURE_UNIT::K; + timeUnit = KIM::TIME_UNIT::fs; + } else if ((strcmp(update->unit_style,"lj")==0)) { + error->all(FLERR,"LAMMPS unit_style lj not supported by KIM models"); + } else { + error->all(FLERR,"Unknown unit_style"); + } return; } @@ -857,204 +825,85 @@ void PairKIM::set_lmps_flags() void PairKIM::set_kim_model_has_flags() { - KIM_API_model mdl; - + // @@ the procedure below should be improved to be more comprehensive + // @@ and ensure that there are no additions/changes to the kim-api + // @@ that could cause a problem. This should be done using the + // @@ "discoverability" features of the kim-api int kimerror; - - // get KIM API object representing the KIM Model only - kimerror = mdl.model_info(kim_modelname); - kim_error(__LINE__,"KIM initialization failed", kimerror); - - // determine if the KIM Model can compute the total energy - mdl.get_index((char*) "energy", &kimerror); - kim_model_has_energy = (kimerror == KIM_STATUS_OK); - if (!kim_model_has_energy) - error->warning(FLERR,"KIM Model does not provide `energy'; " + KIM::SupportStatus supportStatus; + + // determine if the KIM Model can compute the total partialEnergy + + // determine if the KIM Model can compute the energy + kimerror = pargs->GetArgumentSupportStatus( + KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, + &supportStatus); + if (kimerror) + error->all(FLERR,"Unable to get KIM Support Status"); + if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { + kim_model_has_energy = false; + error->warning(FLERR,"KIM Model does not provide `partialEnergy'; " "Potential energy will be zero"); - - // determine if the KIM Model can compute the forces - mdl.get_index((char*) "forces", &kimerror); - kim_model_has_forces = (kimerror == KIM_STATUS_OK); - if (!kim_model_has_forces) - error->warning(FLERR,"KIM Model does not provide `forces'; " + } else { + kim_model_has_energy = true; + } + + // determine if the KIM Model can compute the partialForces + kimerror = pargs->GetArgumentSupportStatus( + KIM::COMPUTE_ARGUMENT_NAME::partialForces, + &supportStatus); + if (kimerror) + error->all(FLERR,"Unable to get KIM Support Status"); + if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { + kim_model_has_forces = false; + error->warning(FLERR,"KIM Model does not provide `partialForce'; " "Forces will be zero"); - - // determine if the KIM Model can compute the particleEnergy - mdl.get_index((char*) "particleEnergy", &kimerror); - kim_model_has_particleEnergy = (kimerror == KIM_STATUS_OK); - if (!kim_model_has_particleEnergy) - error->warning(FLERR,"KIM Model does not provide `particleEnergy'; " + } else { + kim_model_has_forces = true; + } + + // determine if the KIM Model can compute the partialVirial + kimerror = pargs->GetArgumentSupportStatus( + KIM::COMPUTE_ARGUMENT_NAME::partialVirial, + &supportStatus); + if (kimerror) + error->all(FLERR,"Unable to get KIM Support Status"); + if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { + kim_model_has_virial = false; + error->warning(FLERR,"KIM Model does not provide `partialVirial'. " + "pair_kim now using `LAMMPSvirial' option."); + no_virial_fdotr_compute = 0; + } else { + kim_model_has_virial = true; + } + + // determine if the KIM Model can compute the partialParticleEnergy + kimerror = pargs->GetArgumentSupportStatus( + KIM::COMPUTE_ARGUMENT_NAME::partialParticleEnergy, + &supportStatus); + if (kimerror) + error->all(FLERR,"Unable to get KIM Support Status"); + if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { + kim_model_has_particleEnergy = false; + error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; " "energy per atom will be zero"); - - // determine if the KIM Model can compute the particleVerial - mdl.get_index((char*) "particleVirial", &kimerror); - kim_model_has_particleVirial = (kimerror == KIM_STATUS_OK); - mdl.get_index((char*) "process_dEdr", &kimerror); - kim_model_has_particleVirial = kim_model_has_particleVirial || - (kimerror == KIM_STATUS_OK); - if (!kim_model_has_particleVirial) - error->warning(FLERR,"KIM Model does not provide `particleVirial'; " + } else { + kim_model_has_particleEnergy = true; + } + + // determine if the KIM Model can compute the partialParticleVirial + kimerror = pargs->GetArgumentSupportStatus( + KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, + &supportStatus); + if (kimerror) + error->all(FLERR,"Unable to get KIM Support Status"); + if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { + kim_model_has_particleVirial = false; + error->warning(FLERR,"KIM Model does not provide `partialParticleVirial'; " "virial per atom will be zero"); - - // tear down KIM API object - mdl.free(&kimerror); - // now destructor will do the remaining tear down for mdl - - return; -} - -/* ---------------------------------------------------------------------- */ - -void PairKIM::write_descriptor(char** test_descriptor_string) -{ - // allocate memory - if (*test_descriptor_string != 0) - error->all(FLERR, "Test_descriptor_string already allocated"); - // assuming 75 lines at 100 characters each (should be plenty) - *test_descriptor_string = new char[100*75]; - // initialize - strcpy(*test_descriptor_string, ""); - - // Write Test name and units - strcat(*test_descriptor_string, - "#\n" - "# BEGINNING OF KIM DESCRIPTOR FILE\n" - "#\n" - "# This file is automatically generated from LAMMPS pair_style " - "kim command\n"); - strcat(*test_descriptor_string, - "\n" - "# The call number is (pair_style).(init_style): "); - char tmp_num[100]; - sprintf(tmp_num, "%i.%i\n", settings_call_count, init_style_call_count); - strcat(*test_descriptor_string, tmp_num); - strcat(*test_descriptor_string, - "#\n" - "\n" -#if KIM_API_VERSION_MAJOR == 1 && KIM_API_VERSION_MINOR == 5 -#else - "KIM_API_Version := 1.6.0\n\n" -#endif - "# Base units\n"); - switch (lmps_units) - { - case REAL: - strcat(*test_descriptor_string, - "Unit_length := A\n" - "Unit_energy := kcal/mol\n" - "Unit_charge := e\n" - "Unit_temperature := K\n" - "Unit_time := fs\n\n"); - break; - case METAL: - strcat(*test_descriptor_string, - "Unit_length := A\n" - "Unit_energy := eV\n" - "Unit_charge := e\n" - "Unit_temperature := K\n" - "Unit_time := ps\n\n"); - break; - case SI: - strcat(*test_descriptor_string, - "Unit_length := m\n" - "Unit_energy := J\n" - "Unit_charge := C\n" - "Unit_temperature := K\n" - "Unit_time := s\n\n"); - break; - case CGS: - strcat(*test_descriptor_string, - "Unit_length := cm\n" - "Unit_energy := erg\n" - "Unit_charge := statC\n" - "Unit_temperature := K\n" - "Unit_time := s\n\n"); - break; - case ELECTRON: - strcat(*test_descriptor_string, - "Unit_length := Bohr\n" - "Unit_energy := Hartree\n" - "Unit_charge := e\n" - "Unit_temperature := K\n" - "Unit_time := fs\n\n"); - break; - } - - // Write Supported species section - strcat(*test_descriptor_string, - "\n" -#if KIM_API_VERSION_MAJOR == 1 && KIM_API_VERSON_MINOR == 5 - "SUPPORTED_ATOM/PARTICLES_TYPES:\n" -#else - "PARTICLE_SPECIES:\n" -#endif - "# Symbol/name Type code\n"); - int code=1; - char* tmp_line = 0; - tmp_line = new char[100]; - for (int i=0; i < lmps_num_unique_elements; i++){ - sprintf(tmp_line, "%-24s%-16s%-3i\n", lmps_unique_elements[i], - "spec", code++); - strcat(*test_descriptor_string, tmp_line); + } else { + kim_model_has_particleVirial = true; } - delete [] tmp_line; - tmp_line = 0; - strcat(*test_descriptor_string, "\n"); - - // Write conventions section - strcat(*test_descriptor_string, - "\n" - "CONVENTIONS:\n" - "# Name Type\n" - "ZeroBasedLists flag\n" - "Neigh_LocaAccess flag\n" - "NEIGH_PURE_F flag\n\n"); - - // Write input section - strcat(*test_descriptor_string, - "\n" - "MODEL_INPUT:\n" - "# Name Type Unit Shape\n" - "numberOfParticles integer none []\n" - "numberOfSpecies integer none []\n" - "particleSpecies integer none " - "[numberOfParticles]\n" - "coordinates double length " - "[numberOfParticles,3]\n" - "neighObject pointer none []\n" - "get_neigh method none []\n"); - - // Write output section - strcat(*test_descriptor_string, - "\n" - "MODEL_OUPUT:\n" - "# Name Type Unit Shape\n" - "compute method none []\n" - "destroy method none []\n" - "cutoff double length []\n"); - if (!kim_model_has_energy) strcat(*test_descriptor_string,"# "); - strcat(*test_descriptor_string, - "energy double energy []\n"); - if (!kim_model_has_forces) strcat(*test_descriptor_string, "# "); - strcat(*test_descriptor_string, - "forces double force " - "[numberOfParticles,3]\n"); - if (!kim_model_has_particleEnergy) strcat(*test_descriptor_string, "# "); - strcat(*test_descriptor_string, - "particleEnergy double energy " - "[numberOfParticles]\n"); - if (no_virial_fdotr_compute != 1) strcat(*test_descriptor_string, "# "); - strcat(*test_descriptor_string, - "virial double energy [6]\n"); - if (!kim_model_has_particleVirial) strcat(*test_descriptor_string, "# "); - strcat(*test_descriptor_string, - "particleVirial double energy " - "[numberOfParticles,6]\n" - "\n"); - strcat(*test_descriptor_string, - "#\n" - "# END OF KIM DESCRIPTOR FILE\n" - "#\n"); return; } diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 493aa9066a..07790fb44b 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -33,6 +33,7 @@ PairStyle(kim,PairKIM) // includes from KIM & LAMMPS class KIM_API_model; #include "pair.h" +#include "KIM_SimulatorHeaders.hpp" namespace LAMMPS_NS { @@ -61,7 +62,6 @@ namespace LAMMPS_NS { // values set in settings() char* kim_modelname; - bool print_kim_file; // values set in coeff() @@ -79,29 +79,23 @@ namespace LAMMPS_NS { bool lmps_using_molecular; enum unit_sys {REAL, METAL, SI, CGS, ELECTRON}; unit_sys lmps_units; + KIM::LengthUnit lengthUnit; + KIM::EnergyUnit energyUnit; + KIM::ChargeUnit chargeUnit; + KIM::TemperatureUnit temperatureUnit; + KIM::TimeUnit timeUnit; // values set in set_kim_model_has_flags(), called by kim_init() - KIM_API_model* pkim; + KIM::Model * pkim; + KIM::ComputeArguments * pargs; bool kim_model_has_energy; bool kim_model_has_forces; + bool kim_model_has_virial; bool kim_model_has_particleEnergy; bool kim_model_has_particleVirial; // values set in kim_init(), after call to string_init(_) bool kim_init_ok; - int kim_ind_coordinates; - int kim_ind_numberOfParticles; - int kim_ind_numberContributingParticles; - int kim_ind_numberOfSpecies; - int kim_ind_particleSpecies; - int kim_ind_get_neigh; - int kim_ind_neighObject; - int kim_ind_cutoff; - int kim_ind_energy; - int kim_ind_particleEnergy; - int kim_ind_forces; - int kim_ind_virial; - int kim_ind_particleVirial; // values set in init_style(), after calling pkim->model_init() bool kim_model_init_ok; @@ -111,27 +105,31 @@ namespace LAMMPS_NS { // values set in set_statics(), called at end of kim_init(), // then again in set_volatiles(), called in compute() int lmps_local_tot_num_atoms; - double kim_global_cutoff; // KIM Model cutoff value + double kim_global_influence_distance; // KIM Model cutoff value + int kim_number_of_cutoffs; + double const * kim_cutoff_values; // values set in compute() int lmps_maxalloc; // max allocated memory value int* kim_particleSpecies; // array of KIM particle species + int* kim_particleContributing; // array of KIM particle contributing int* lmps_stripped_neigh_list; // neighbors of one atom, used when LAMMPS // is in molecular mode // KIM specific helper functions - void kim_error(int, const char *, int); void kim_init(); void kim_free(); void set_statics(); void set_volatiles(); void set_lmps_flags(); void set_kim_model_has_flags(); - void write_descriptor(char** test_descriptor_string); // static methods used as callbacks from KIM - static int get_neigh(void** kimmdl, int* mode, int* request, - int* atom, int* numnei, int** nei1atom, - double** pRij); + static int get_neigh( + void const * const dataObject, + int const numberOfCutoffs, double const * const cutoffs, + int const neighborListIndex, int const particleNumber, + int * const numberOfNeighbors, + int const ** const neighborsOfParticle); }; } -- GitLab From 906a12353c97a4a7ba47bd97e708109e957fd908 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sun, 24 Jun 2018 08:28:34 -0500 Subject: [PATCH 0007/1243] Fixup neighbor list settings for pair_kim --- src/KIM/pair_kim.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 413c5303e1..34deca3862 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -379,8 +379,7 @@ void PairKIM::init_style() int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; - // make sure full lists also include local-ghost pairs - if (lmps_using_newton) neighbor->requests[irequest]->newton = 0; + neighbor->requests[irequest]->ghost = 1; return; } -- GitLab From da9441471a373ca3c7bf1c6d5525a1ce20d01540 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sun, 24 Jun 2018 08:44:28 -0500 Subject: [PATCH 0008/1243] Fixup partialVirial bug in pair_kim --- src/KIM/pair_kim.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 34deca3862..040c90b42b 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -723,11 +723,11 @@ void PairKIM::set_volatiles() if(vflag_atom != 1) { kimerror = kimerror || pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, - &(vatom[0][0])); + reinterpret_cast(NULL)); } else { kimerror = kimerror || pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, - reinterpret_cast(NULL)); + &(vatom[0][0])); } } -- GitLab From 8a8b968d55c715f87d7ff57df75796de3ad28251 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sun, 24 Jun 2018 15:23:25 -0500 Subject: [PATCH 0009/1243] Fixup the pressure/virial computation in pair_kim --- src/KIM/pair_kim.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 040c90b42b..d1f5887341 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -735,14 +735,18 @@ void PairKIM::set_volatiles() { if (kim_model_has_virial) { - if (vflag_global == 1) + if (vflag_global == 0) + { kimerror = kimerror || pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::partialVirial, - &(virial[0])); + reinterpret_cast(NULL)); + } else + { kimerror = kimerror || pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::partialVirial, - reinterpret_cast(NULL)); + &(virial[0])); + } } } -- GitLab From 5958b24edc01d60b20c26b0e6a3b62a294505f0e Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 27 Jun 2018 11:06:18 -0500 Subject: [PATCH 0010/1243] Adjust some internal pair_kim things --- src/KIM/pair_kim.cpp | 24 ++++++++---------------- src/KIM/pair_kim.h | 23 +++++++++++------------ 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index d1f5887341..3fc94944fc 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -52,11 +52,11 @@ PairKIM::PairKIM(LAMMPS *lmp) : lmps_units(METAL), pkim(0), pargs(0), - kim_particle_codes(0), lmps_local_tot_num_atoms(0), kim_global_influence_distance(0.0), kim_number_of_cutoffs(0), kim_cutoff_values(0), + kim_particle_codes(0), lmps_maxalloc(0), kim_particleSpecies(0), kim_particleContributing(0), @@ -119,6 +119,8 @@ void PairKIM::compute(int eflag , int vflag) else ev_unset(); + // @@@@ can we strip the neighbor list here (like pair_meamc does)? + // grow kim_particleSpecies and kim_particleContributing array if necessary // needs to be atom->nmax in length if (atom->nmax > lmps_maxalloc) { @@ -158,7 +160,7 @@ void PairKIM::compute(int eflag , int vflag) } // pass current atom pointers to KIM - set_volatiles(); + set_argument_pointers(); // compute via KIM model kimerror = pkim->Compute(pargs); @@ -656,16 +658,6 @@ void PairKIM::kim_init() error->all(FLERR,"create_kim_particle_codes: symbol not found "); } - // set pointer values in KIM API object that will not change during run - set_statics(); - - return; -} - -/* ---------------------------------------------------------------------- */ - -void PairKIM::set_statics() -{ // set total number of atoms lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); @@ -673,7 +665,7 @@ void PairKIM::set_statics() pkim->GetNeighborListCutoffsPointer(&kim_number_of_cutoffs, &kim_cutoff_values); - int kimerror = pargs->SetArgumentPointer( + kimerror = pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, &lmps_local_tot_num_atoms); if (kim_model_has_energy) @@ -688,14 +680,14 @@ void PairKIM::set_statics() reinterpret_cast(this)); if (kimerror) - error->all(FLERR,"Unable to register KIM static pointers"); + error->all(FLERR,"Unable to register KIM pointers"); return; } /* ---------------------------------------------------------------------- */ -void PairKIM::set_volatiles() +void PairKIM::set_argument_pointers() { int kimerror; lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); @@ -752,7 +744,7 @@ void PairKIM::set_volatiles() if (kimerror) { - error->all(FLERR,"Unable to set KIM volatile pointers"); + error->all(FLERR,"Unable to set KIM argument pointers"); } return; diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 07790fb44b..37807ebfbc 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -48,6 +48,7 @@ namespace LAMMPS_NS { virtual void settings(int, char**); virtual void coeff(int, char**); virtual void init_style(); + //virtual void init_list(int id, NeighList *ptr); virtual double init_one(int, int); virtual int pack_reverse_comm(int, int, double*); virtual void unpack_reverse_comm(int, int*, double*); @@ -85,30 +86,29 @@ namespace LAMMPS_NS { KIM::TemperatureUnit temperatureUnit; KIM::TimeUnit timeUnit; - // values set in set_kim_model_has_flags(), called by kim_init() + KIM::Model * pkim; KIM::ComputeArguments * pargs; + + // values set in set_kim_model_has_flags(), called by kim_init() bool kim_model_has_energy; bool kim_model_has_forces; bool kim_model_has_virial; bool kim_model_has_particleEnergy; bool kim_model_has_particleVirial; - // values set in kim_init(), after call to string_init(_) + // values set in kim_init() bool kim_init_ok; - - // values set in init_style(), after calling pkim->model_init() - bool kim_model_init_ok; - bool kim_particle_codes_ok; - int *kim_particle_codes; - - // values set in set_statics(), called at end of kim_init(), - // then again in set_volatiles(), called in compute() int lmps_local_tot_num_atoms; double kim_global_influence_distance; // KIM Model cutoff value int kim_number_of_cutoffs; double const * kim_cutoff_values; + // values set in init_style() + bool kim_model_init_ok; + bool kim_particle_codes_ok; + int *kim_particle_codes; + // values set in compute() int lmps_maxalloc; // max allocated memory value int* kim_particleSpecies; // array of KIM particle species @@ -119,8 +119,7 @@ namespace LAMMPS_NS { // KIM specific helper functions void kim_init(); void kim_free(); - void set_statics(); - void set_volatiles(); + void set_argument_pointers(); void set_lmps_flags(); void set_kim_model_has_flags(); // static methods used as callbacks from KIM -- GitLab From cb077829356450d8a64161c67428adc3110b4d6a Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 27 Jun 2018 12:46:13 -0500 Subject: [PATCH 0011/1243] Multiple neig lists working in pair_kim --- src/KIM/pair_kim.cpp | 57 ++++++++++++++++++++++++++++++++------------ src/KIM/pair_kim.h | 3 ++- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 3fc94944fc..afc4a89675 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -56,6 +56,7 @@ PairKIM::PairKIM(LAMMPS *lmp) : kim_global_influence_distance(0.0), kim_number_of_cutoffs(0), kim_cutoff_values(0), + neighborLists(0), kim_particle_codes(0), lmps_maxalloc(0), kim_particleSpecies(0), @@ -102,6 +103,13 @@ PairKIM::~PairKIM() delete [] lmps_map_species_to_unique; } + // clean up neighborlist pointers + if (neighborLists) + { + delete [] neighborLists; + neighborLists = 0; + } + // clean up KIM interface (if necessary) kim_free(); @@ -378,14 +386,30 @@ void PairKIM::init_style() if (!lmps_using_newton) comm_reverse_off = 9; // request full neighbor list - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->ghost = 1; + for (int i = 0; i < kim_number_of_cutoffs; ++i) + { + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->id = i; + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + neighbor->requests[irequest]->ghost = 1; + neighbor->requests[irequest]->cut = 1; + neighbor->requests[irequest]->cutoff = kim_cutoff_values[i]; + } return; } +/* ---------------------------------------------------------------------- + neighbor callback to inform pair style of neighbor list to use + half or full +------------------------------------------------------------------------- */ + +void PairKIM::init_list(int id, NeighList *ptr) +{ + neighborLists[id] = ptr; +} + /* ---------------------------------------------------------------------- init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ @@ -525,7 +549,7 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) double PairKIM::memory_usage() { - double bytes = lmps_maxalloc * sizeof(int); + double bytes = 2 * lmps_maxalloc * sizeof(int); return bytes; } @@ -542,21 +566,18 @@ int PairKIM::get_neigh(void const * const dataObject, PairKIM const * const Model = reinterpret_cast(dataObject); - if ((numberOfCutoffs != 1) || (cutoffs[0] > Model->kim_cutoff_values[0])) - return true; + if (numberOfCutoffs != Model->kim_number_of_cutoffs) return true; + for (int i = 0; i < numberOfCutoffs; ++i) + { + if (Model->kim_cutoff_values[i] < cutoffs[i]) return true; + } - if (neighborListIndex != 0) return true; + // neighborListIndex and particleNumber are validated by KIM API // initialize numNeigh *numberOfNeighbors = 0; - if ((particleNumber >= Model->lmps_local_tot_num_atoms) || - (particleNumber < 0)) /* invalid id */ - { - return true; - } - - NeighList * neiobj = Model->list; + NeighList * neiobj = Model->neighborLists[neighborListIndex]; int nAtoms = Model->lmps_local_tot_num_atoms; int j, jj, inum, *ilist, *numneigh, **firstneigh; @@ -664,6 +685,12 @@ void PairKIM::kim_init() pkim->GetInfluenceDistance(&kim_global_influence_distance); pkim->GetNeighborListCutoffsPointer(&kim_number_of_cutoffs, &kim_cutoff_values); + if (neighborLists) + { + delete [] neighborLists; + neighborLists = 0; + } + neighborLists = new NeighList*[kim_number_of_cutoffs]; kimerror = pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 37807ebfbc..4542b656b7 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -48,7 +48,7 @@ namespace LAMMPS_NS { virtual void settings(int, char**); virtual void coeff(int, char**); virtual void init_style(); - //virtual void init_list(int id, NeighList *ptr); + virtual void init_list(int id, NeighList *ptr); virtual double init_one(int, int); virtual int pack_reverse_comm(int, int, double*); virtual void unpack_reverse_comm(int, int*, double*); @@ -103,6 +103,7 @@ namespace LAMMPS_NS { double kim_global_influence_distance; // KIM Model cutoff value int kim_number_of_cutoffs; double const * kim_cutoff_values; + class NeighList ** neighborLists; // values set in init_style() bool kim_model_init_ok; -- GitLab From f1f140dd5f9bfe9bed2dcb42fb5dce990ea445b9 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 27 Jun 2018 15:13:48 -0500 Subject: [PATCH 0012/1243] remove unnecessary code in pair_kim.cpp --- src/KIM/pair_kim.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index afc4a89675..658e8cb483 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -679,9 +679,6 @@ void PairKIM::kim_init() error->all(FLERR,"create_kim_particle_codes: symbol not found "); } - // set total number of atoms - lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); - pkim->GetInfluenceDistance(&kim_global_influence_distance); pkim->GetNeighborListCutoffsPointer(&kim_number_of_cutoffs, &kim_cutoff_values); -- GitLab From a7e3ccd8c4e039baf9060ebecf512a29bb35e0b8 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 27 Jun 2018 15:50:50 -0500 Subject: [PATCH 0013/1243] Finish off multi-neighbor list support for pair_kim --- src/KIM/pair_kim.cpp | 39 ++++++++++++++++++++++++++++----------- src/KIM/pair_kim.h | 1 + 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 658e8cb483..e41cc94ea0 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -61,6 +61,7 @@ PairKIM::PairKIM(LAMMPS *lmp) : lmps_maxalloc(0), kim_particleSpecies(0), kim_particleContributing(0), + lmps_stripped_neigh_ptr(0), lmps_stripped_neigh_list(0) { // Initialize Pair data members to appropriate values @@ -94,6 +95,12 @@ PairKIM::~PairKIM() memory->destroy(kim_particleSpecies); memory->destroy(kim_particleContributing); memory->destroy(lmps_stripped_neigh_list); + // clean up lmps_stripped_neigh_ptr + if (lmps_stripped_neigh_ptr) + { + delete [] lmps_stripped_neigh_ptr; + lmps_stripped_neigh_ptr = 0; + } // clean up allocated memory for standard Pair class usage // also, we allocate lmps_map_species_to_uniuqe in the allocate() function @@ -241,10 +248,11 @@ void PairKIM::settings(int narg, char **arg) ++settings_call_count; init_style_call_count = 0; - if (narg < 2) error->all(FLERR,"Illegal pair_style command"); + if (narg != 2) error->all(FLERR,"Illegal pair_style command"); // arg[0] is the virial handling option: "LAMMPSvirial" or "KIMvirial" // arg[1] is the KIM Model name - // arg[2] is the print-kim-file flag: 0/1 do-not/do print (default 0) + + lmps_using_molecular = (atom->molecular > 0); // ensure we are in a clean state for KIM (needed on repeated call) // first time called will do nothing... @@ -382,6 +390,22 @@ void PairKIM::init_style() kim_init(); } + // setup lmps_stripped_neigh_list for neighbors of one atom, if needed + if (lmps_using_molecular) { + memory->destroy(lmps_stripped_neigh_list); + memory->create(lmps_stripped_neigh_list, + kim_number_of_cutoffs*neighbor->oneatom, + "pair:lmps_stripped_neigh_list"); + delete [] lmps_stripped_neigh_ptr; + lmps_stripped_neigh_ptr = new int*[kim_number_of_cutoffs]; + for (int i = 0; i < kim_number_of_cutoffs; ++i) + { + lmps_stripped_neigh_ptr[0] + = &(lmps_stripped_neigh_list[(i-1)*(neighbor->oneatom)]); + } + + } + // make sure comm_reverse expects (at most) 9 values when newton is off if (!lmps_using_newton) comm_reverse_off = 9; @@ -595,7 +619,8 @@ int PairKIM::get_neigh(void const * const dataObject, { int n = *numberOfNeighbors; int *ptr = firstneigh[particleNumber]; - int *lmps_stripped_neigh_list = Model->lmps_stripped_neigh_list; + int *lmps_stripped_neigh_list + = Model->lmps_stripped_neigh_ptr[neighborListIndex]; for (int i = 0; i < n; i++) lmps_stripped_neigh_list[i] = *(ptr++) & NEIGHMASK; *neighborsOfParticle = lmps_stripped_neigh_list; @@ -781,14 +806,6 @@ void PairKIM::set_lmps_flags() // determint if newton is on or off lmps_using_newton = (force->newton_pair == 1); - // setup lmps_stripped_neigh_list for neighbors of one atom, if needed - lmps_using_molecular = (atom->molecular > 0); - if (lmps_using_molecular) { - memory->destroy(lmps_stripped_neigh_list); - memory->create(lmps_stripped_neigh_list,neighbor->oneatom, - "pair:lmps_stripped_neigh_list"); - } - // determine if running with pair hybrid if (force->pair_match("hybrid",0)) { diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 4542b656b7..a22bf1492f 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -116,6 +116,7 @@ namespace LAMMPS_NS { int* kim_particleContributing; // array of KIM particle contributing int* lmps_stripped_neigh_list; // neighbors of one atom, used when LAMMPS // is in molecular mode + int** lmps_stripped_neigh_ptr; // pointer into lists // KIM specific helper functions void kim_init(); -- GitLab From 199a01714864964e317208b90dcfb9c433182351 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Thu, 28 Jun 2018 09:32:28 -0500 Subject: [PATCH 0014/1243] Some cleanup in pair_kim --- src/KIM/pair_kim.cpp | 20 +++++++++++--------- src/KIM/pair_kim.h | 1 - 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index e41cc94ea0..2785d5793a 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -50,6 +50,11 @@ PairKIM::PairKIM(LAMMPS *lmp) : lmps_unique_elements(0), lmps_num_unique_elements(0), lmps_units(METAL), + lengthUnit(KIM::LENGTH_UNIT::unused), + energyUnit(KIM::ENERGY_UNIT::unused), + chargeUnit(KIM::CHARGE_UNIT::unused), + temperatureUnit(KIM::TEMPERATURE_UNIT::unused), + timeUnit(KIM::TIME_UNIT::unused), pkim(0), pargs(0), lmps_local_tot_num_atoms(0), @@ -61,8 +66,8 @@ PairKIM::PairKIM(LAMMPS *lmp) : lmps_maxalloc(0), kim_particleSpecies(0), kim_particleContributing(0), - lmps_stripped_neigh_ptr(0), - lmps_stripped_neigh_list(0) + lmps_stripped_neigh_list(0), + lmps_stripped_neigh_ptr(0) { // Initialize Pair data members to appropriate values single_enable = 0; // We do not provide the Single() function @@ -134,8 +139,6 @@ void PairKIM::compute(int eflag , int vflag) else ev_unset(); - // @@@@ can we strip the neighbor list here (like pair_meamc does)? - // grow kim_particleSpecies and kim_particleContributing array if necessary // needs to be atom->nmax in length if (atom->nmax > lmps_maxalloc) { @@ -160,7 +163,6 @@ void PairKIM::compute(int eflag , int vflag) } // kim_particleSpecies = KIM atom species for each LAMMPS atom - // set ielement to valid 0 if lmps_map_species_to_unique[] stores an un-used -1 int *species = atom->type; int nall = atom->nlocal + atom->nghost; @@ -168,7 +170,6 @@ void PairKIM::compute(int eflag , int vflag) for (int i = 0; i < nall; i++) { ielement = lmps_map_species_to_unique[species[i]]; - ielement = MAX(ielement,0); kim_particleSpecies[i] = kim_particle_codes[ielement]; kim_particleContributing[i] = ( (inlocal) ? 1 : 0 ); @@ -177,6 +178,9 @@ void PairKIM::compute(int eflag , int vflag) // pass current atom pointers to KIM set_argument_pointers(); + // set number of particles + lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); + // compute via KIM model kimerror = pkim->Compute(pargs); if (kimerror) error->all(FLERR,"KIM Compute returned error"); @@ -409,7 +413,7 @@ void PairKIM::init_style() // make sure comm_reverse expects (at most) 9 values when newton is off if (!lmps_using_newton) comm_reverse_off = 9; - // request full neighbor list + // request full neighbor lists for (int i = 0; i < kim_number_of_cutoffs; ++i) { int irequest = neighbor->request(this,instance_me); @@ -739,8 +743,6 @@ void PairKIM::kim_init() void PairKIM::set_argument_pointers() { int kimerror; - lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); - kimerror = pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::coordinates, &(atom->x[0][0])); diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index a22bf1492f..0c017e75ed 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -86,7 +86,6 @@ namespace LAMMPS_NS { KIM::TemperatureUnit temperatureUnit; KIM::TimeUnit timeUnit; - KIM::Model * pkim; KIM::ComputeArguments * pargs; -- GitLab From cb21051eb82f8f1e7337827bfbff1df2a9e0055a Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Thu, 28 Jun 2018 19:59:39 -0500 Subject: [PATCH 0015/1243] Update KIM Model matching code in pair_kim.cpp --- src/KIM/pair_kim.cpp | 355 ++++++++++++++++++++++++------------------- src/KIM/pair_kim.h | 11 +- 2 files changed, 207 insertions(+), 159 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 2785d5793a..5f123de45d 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -57,6 +57,11 @@ PairKIM::PairKIM(LAMMPS *lmp) : timeUnit(KIM::TIME_UNIT::unused), pkim(0), pargs(0), + kim_model_support_for_energy(KIM::SUPPORT_STATUS::notSupported), + kim_model_support_for_forces(KIM::SUPPORT_STATUS::notSupported), + kim_model_support_for_virial(KIM::SUPPORT_STATUS::notSupported), + kim_model_support_for_particleEnergy(KIM::SUPPORT_STATUS::notSupported), + kim_model_support_for_particleVirial(KIM::SUPPORT_STATUS::notSupported), lmps_local_tot_num_atoms(0), kim_global_influence_distance(0.0), kim_number_of_cutoffs(0), @@ -76,8 +81,8 @@ PairKIM::PairKIM(LAMMPS *lmp) : // BEGIN: initial values that determine the KIM state // (used by kim_free(), etc.) - kim_model_init_ok = false; kim_init_ok = false; + kim_particle_codes_ok = false; // END return; @@ -201,7 +206,9 @@ void PairKIM::compute(int eflag , int vflag) if (vflag_fdotr) virial_fdotr_compute(); } - if ((kim_model_has_particleVirial) && (vflag_atom)) + if ((kim_model_support_for_particleVirial != + KIM::SUPPORT_STATUS::notSupported) && + (vflag_atom)) { // flip sign and order of virial if KIM is computing it double tmp; for (int i = 0; i < nall; ++i) @@ -456,14 +463,17 @@ double PairKIM::init_one(int i, int j) int PairKIM::pack_reverse_comm(int n, int first, double *buf) { + using namespace KIM::SUPPORT_STATUS; + int i,m,last; double *fp; fp = &(atom->f[0][0]); m = 0; last = first + n; - if ((kim_model_has_forces) && ((vflag_atom == 0) || - (!kim_model_has_particleVirial))) + if ((kim_model_support_for_forces != notSupported) && + ((vflag_atom == 0) || + (kim_model_support_for_particleVirial == notSupported))) { for (i = first; i < last; i++) { @@ -473,8 +483,9 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) } return m; } - else if ((kim_model_has_forces) && (vflag_atom == 1) && - (kim_model_has_particleVirial)) + else if ((kim_model_support_for_forces != notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) { double *va=&(vatom[0][0]); for (i = first; i < last; i++) @@ -492,8 +503,9 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) } return m; } - else if ((!kim_model_has_forces) && (vflag_atom == 1) && - (kim_model_has_particleVirial)) + else if ((kim_model_support_for_forces == notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) { double *va=&(vatom[0][0]); for (i = first; i < last; i++) @@ -515,13 +527,16 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) { + using namespace KIM::SUPPORT_STATUS; + int i,j,m; double *fp; fp = &(atom->f[0][0]); m = 0; - if ((kim_model_has_forces) && ((vflag_atom == 0) || - (!kim_model_has_particleVirial))) + if ((kim_model_support_for_forces != notSupported) && + ((vflag_atom == 0) || + (kim_model_support_for_particleVirial == notSupported))) { for (i = 0; i < n; i++) { @@ -531,8 +546,9 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) fp[3*j+2]+= buf[m++]; } } - else if ((kim_model_has_forces) && (vflag_atom == 1) && - (kim_model_has_particleVirial)) + else if ((kim_model_support_for_forces != notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) { double *va=&(vatom[0][0]); for (i = 0; i < n; i++) @@ -550,8 +566,9 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) va[j*6+5]+=buf[m++]; } } - else if ((!kim_model_has_forces) && (vflag_atom == 1) && - (kim_model_has_particleVirial)) + else if ((kim_model_support_for_forces == notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) { double *va=&(vatom[0][0]); for (i = 0; i < n; i++) @@ -638,14 +655,13 @@ void PairKIM::kim_free() { int kimerror; - if (kim_model_init_ok) + if (kim_init_ok) { int kimerror = pkim->ComputeArgumentsDestroy(&pargs); if (kimerror) error->all(FLERR,"Unable to destroy Compute Arguments Object"); KIM::Model::Destroy(&pkim); - kim_model_init_ok = false; } kim_init_ok = false; @@ -683,9 +699,14 @@ void PairKIM::kim_init() kimerror = pkim->ComputeArgumentsCreate(&pargs); if (kimerror) + { + KIM::Model::Destroy(&pkim); error->all(FLERR,"KIM ComputeArgumentsCreate failed"); + } else + { kim_init_ok = true; + } } // determine KIM Model capabilities (used in this function below) @@ -721,7 +742,7 @@ void PairKIM::kim_init() kimerror = pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, &lmps_local_tot_num_atoms); - if (kim_model_has_energy) + if (kim_model_support_for_energy != KIM::SUPPORT_STATUS::notSupported) kimerror = kimerror || pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, &(eng_vdwl)); @@ -742,63 +763,98 @@ void PairKIM::kim_init() void PairKIM::set_argument_pointers() { - int kimerror; - kimerror = pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::coordinates, - &(atom->x[0][0])); - - if (kim_model_has_particleEnergy && (eflag_atom == 1)) - { - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialParticleEnergy, - eatom); - } - - if (kim_model_has_forces) - { - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialForces, - &(atom->f[0][0])); - } - - if (kim_model_has_particleVirial) - { - if(vflag_atom != 1) { - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, - reinterpret_cast(NULL)); - } else { - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, - &(vatom[0][0])); - } - } - - if (no_virial_fdotr_compute == 1) - { - if (kim_model_has_virial) - { - if (vflag_global == 0) - { - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialVirial, - reinterpret_cast(NULL)); - } - else - { - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialVirial, - &(virial[0])); - } - } - } - - if (kimerror) - { - error->all(FLERR,"Unable to set KIM argument pointers"); - } - - return; + using namespace KIM::COMPUTE_ARGUMENT_NAME; + using namespace KIM::SUPPORT_STATUS; + + int kimerror; + kimerror = pargs->SetArgumentPointer(coordinates, &(atom->x[0][0])); + + // Set KIM pointer appropriately for particalEnergy + if ((kim_model_support_for_particleEnergy == required) && (eflag_atom != 1)) + { + // reallocate per-atom energy array if necessary + if (atom->nmax > maxeatom) + { + maxeatom = atom->nmax; + memory->destroy(eatom); + memory->create(eatom,comm->nthreads*maxeatom,"pair:eatom"); + } + } + if ((kim_model_support_for_particleEnergy == optional) && (eflag_atom != 1)) + { + kimerror = kimerror || pargs->SetArgumentPointer( + partialParticleEnergy, + reinterpret_cast(NULL)); + } + else if (kim_model_support_for_particleEnergy != notSupported) + { + kimerror = kimerror || pargs->SetArgumentPointer(partialParticleEnergy, + eatom); + } + + // Set KIM pointer appropriately for forces + if (kim_model_support_for_forces == notSupported) + { + kimerror = kimerror || pargs->SetArgumentPointer( + partialForces, + reinterpret_cast(NULL)); + } + else + { + kimerror = kimerror || pargs->SetArgumentPointer(partialForces, + &(atom->f[0][0])); + } + + // Set KIM pointer appropriately for particleVirial + if ((kim_model_support_for_particleVirial == required) && (vflag_atom != 1)) + { + // reallocate per-atom virial array if necessary + if (atom->nmax > maxeatom) + { + maxvatom = atom->nmax; + memory->destroy(vatom); + memory->create(vatom,comm->nthreads*maxvatom,6,"pair:vatom"); + } + } + if ((kim_model_support_for_particleVirial == optional) && (vflag_atom != 1)) + { + kimerror = kimerror || pargs->SetArgumentPointer( + partialParticleVirial, + reinterpret_cast(NULL)); + } + else if (kim_model_support_for_particleVirial != notSupported) + { + kimerror = kimerror || pargs->SetArgumentPointer(partialParticleEnergy, + &(vatom[0][0])); + } + + // Set KIM pointer appropriately for virial + + if (kim_model_support_for_virial == required) + { + kimerror = kimerror || pargs->SetArgumentPointer(partialVirial, + &(virial[0])); + } + else if ((kim_model_support_for_virial == optional) && + (no_virial_fdotr_compute == 1) && + (vflag_global)) + { + kimerror = kimerror || pargs->SetArgumentPointer(partialVirial, + &(virial[0])); + } + else if (kim_model_support_for_virial == optional) + { + kimerror = kimerror || pargs->SetArgumentPointer( + partialVirial, + reinterpret_cast(NULL)); + } + + if (kimerror) + { + error->all(FLERR,"Unable to set KIM argument pointers"); + } + + return; } /* ---------------------------------------------------------------------- */ @@ -863,85 +919,78 @@ void PairKIM::set_lmps_flags() void PairKIM::set_kim_model_has_flags() { - // @@ the procedure below should be improved to be more comprehensive - // @@ and ensure that there are no additions/changes to the kim-api - // @@ that could cause a problem. This should be done using the - // @@ "discoverability" features of the kim-api - int kimerror; - KIM::SupportStatus supportStatus; - - // determine if the KIM Model can compute the total partialEnergy - - // determine if the KIM Model can compute the energy - kimerror = pargs->GetArgumentSupportStatus( - KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, - &supportStatus); - if (kimerror) - error->all(FLERR,"Unable to get KIM Support Status"); - if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { - kim_model_has_energy = false; - error->warning(FLERR,"KIM Model does not provide `partialEnergy'; " - "Potential energy will be zero"); - } else { - kim_model_has_energy = true; - } - - // determine if the KIM Model can compute the partialForces - kimerror = pargs->GetArgumentSupportStatus( - KIM::COMPUTE_ARGUMENT_NAME::partialForces, - &supportStatus); - if (kimerror) - error->all(FLERR,"Unable to get KIM Support Status"); - if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { - kim_model_has_forces = false; - error->warning(FLERR,"KIM Model does not provide `partialForce'; " - "Forces will be zero"); - } else { - kim_model_has_forces = true; - } - - // determine if the KIM Model can compute the partialVirial - kimerror = pargs->GetArgumentSupportStatus( - KIM::COMPUTE_ARGUMENT_NAME::partialVirial, - &supportStatus); - if (kimerror) - error->all(FLERR,"Unable to get KIM Support Status"); - if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { - kim_model_has_virial = false; - error->warning(FLERR,"KIM Model does not provide `partialVirial'. " - "pair_kim now using `LAMMPSvirial' option."); - no_virial_fdotr_compute = 0; - } else { - kim_model_has_virial = true; - } - - // determine if the KIM Model can compute the partialParticleEnergy - kimerror = pargs->GetArgumentSupportStatus( - KIM::COMPUTE_ARGUMENT_NAME::partialParticleEnergy, - &supportStatus); - if (kimerror) - error->all(FLERR,"Unable to get KIM Support Status"); - if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { - kim_model_has_particleEnergy = false; - error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; " - "energy per atom will be zero"); - } else { - kim_model_has_particleEnergy = true; - } - - // determine if the KIM Model can compute the partialParticleVirial - kimerror = pargs->GetArgumentSupportStatus( - KIM::COMPUTE_ARGUMENT_NAME::partialParticleVirial, - &supportStatus); - if (kimerror) - error->all(FLERR,"Unable to get KIM Support Status"); - if (KIM::SUPPORT_STATUS::notSupported == supportStatus) { - kim_model_has_particleVirial = false; - error->warning(FLERR,"KIM Model does not provide `partialParticleVirial'; " - "virial per atom will be zero"); - } else { - kim_model_has_particleVirial = true; - } + { // BEGIN enclosing scope for using directives + using namespace KIM::COMPUTE_ARGUMENT_NAME; + using namespace KIM::SUPPORT_STATUS; + + int numberOfComputeArgumentNames; + GetNumberOfComputeArgumentNames(&numberOfComputeArgumentNames); + for (int i = 0; i < numberOfComputeArgumentNames; ++i) + { + KIM::ComputeArgumentName computeArgumentName; + int kimerror = GetComputeArgumentName(i, &computeArgumentName); + KIM::SupportStatus supportStatus; + kimerror = pargs->GetArgumentSupportStatus(computeArgumentName, + &supportStatus); + + if (computeArgumentName == partialEnergy) + kim_model_support_for_energy = supportStatus; + else if (computeArgumentName == partialForces) + kim_model_support_for_forces = supportStatus; + else if (computeArgumentName == partialVirial) + kim_model_support_for_virial = supportStatus; + else if (computeArgumentName == partialParticleEnergy) + kim_model_support_for_particleEnergy = supportStatus; + else if (computeArgumentName == partialParticleVirial) + kim_model_support_for_particleVirial = supportStatus; + else if (supportStatus == required) + { + error->all(FLERR,"KIM Model requires unsupported compute argument"); + } + } + + if (kim_model_support_for_energy == notSupported) + error->warning(FLERR,"KIM Model does not provide `partialEnergy'; " + "Potential energy will be zero"); + + if (kim_model_support_for_forces == notSupported) + error->warning(FLERR,"KIM Model does not provide `partialForce'; " + "Forces will be zero"); + + if (kim_model_support_for_virial == notSupported) + error->warning(FLERR,"KIM Model does not provide `partialVirial'. " + "pair_kim now using `LAMMPSvirial' option."); + + if (kim_model_support_for_particleEnergy == notSupported) + error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; " + "energy per atom will be zero"); + + if (kim_model_support_for_particleVirial == notSupported) + error->warning(FLERR,"KIM Model does not provide `partialParticleVirial'; " + "virial per atom will be zero"); + } // END enclosing scope for using directives + + + { // BEGIN enclosing scope for using directives + using namespace KIM::COMPUTE_CALLBACK_NAME; + using namespace KIM::SUPPORT_STATUS; + + int numberOfComputeCallbackNames; + GetNumberOfComputeCallbackNames(&numberOfComputeCallbackNames); + for (int i = 0; i < numberOfComputeCallbackNames; ++i) + { + KIM::ComputeCallbackName computeCallbackName; + int kimerror = GetComputeCallbackName(i, &computeCallbackName); + KIM::SupportStatus supportStatus; + kimerror = pargs->GetCallbackSupportStatus(computeCallbackName, + &supportStatus); + + if (supportStatus == required) + { + error->all(FLERR,"KIM Model requires unsupported compute callback"); + } + } + } // END enclosing scope for using directives return; } diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 0c017e75ed..a236a3f87a 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -90,11 +90,11 @@ namespace LAMMPS_NS { KIM::ComputeArguments * pargs; // values set in set_kim_model_has_flags(), called by kim_init() - bool kim_model_has_energy; - bool kim_model_has_forces; - bool kim_model_has_virial; - bool kim_model_has_particleEnergy; - bool kim_model_has_particleVirial; + KIM::SupportStatus kim_model_support_for_energy; + KIM::SupportStatus kim_model_support_for_forces; + KIM::SupportStatus kim_model_support_for_virial; + KIM::SupportStatus kim_model_support_for_particleEnergy; + KIM::SupportStatus kim_model_support_for_particleVirial; // values set in kim_init() bool kim_init_ok; @@ -105,7 +105,6 @@ namespace LAMMPS_NS { class NeighList ** neighborLists; // values set in init_style() - bool kim_model_init_ok; bool kim_particle_codes_ok; int *kim_particle_codes; -- GitLab From 955fe583d8e24ae4e054b74410e60db256ac0f60 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Fri, 29 Jun 2018 10:53:19 -0500 Subject: [PATCH 0016/1243] Updated docs for new pair_kim --- cmake/CMakeLists.txt | 20 +++++++++---------- cmake/Modules/FindKIM.cmake | 4 ++-- doc/src/Section_packages.txt | 37 ++++++++++++++++++------------------ doc/src/fix_adapt.txt | 9 +-------- doc/src/pair_kim.txt | 22 +++++---------------- examples/kim/in.kim.lj | 10 +++++----- examples/kim/in.kim.lj.lmp | 10 +++++----- lib/kim/Install.py | 8 ++++---- lib/kim/README | 4 ++-- src/KIM/README | 3 +-- 10 files changed, 53 insertions(+), 74 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index bf57398c71..4672b4a3db 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -309,7 +309,7 @@ if(PKG_VORONOI) ExternalProject_Add(voro_build URL http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz URL_MD5 2338b824c3b7b25590e18e8df5d68af9 - CONFIGURE_COMMAND "" BUILD_IN_SOURCE 1 INSTALL_COMMAND "" + CONFIGURE_COMMAND "" BUILD_IN_SOURCE 1 INSTALL_COMMAND "" ) ExternalProject_get_property(voro_build SOURCE_DIR) set(VORO_LIBRARIES ${SOURCE_DIR}/src/libvoro++.a) @@ -367,7 +367,7 @@ if(PKG_USER-SMD) if(DOWNLOAD_Eigen3) include(ExternalProject) ExternalProject_Add(Eigen3_build - URL http://bitbucket.org/eigen/eigen/get/3.3.4.tar.gz + URL http://bitbucket.org/eigen/eigen/get/3.3.4.tar.gz URL_MD5 1a47e78efe365a97de0c022d127607c3 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) @@ -407,14 +407,14 @@ if(PKG_KIM) if(DOWNLOAD_KIM) include(ExternalProject) ExternalProject_Add(kim_build - URL https://github.com/openkim/kim-api/archive/v1.9.5.tar.gz - URL_MD5 9f66efc128da33039e30659f36fc6d00 + URL https://github.com/openkim/kim-api/archive/v2.0.0-beta.0.tar.gz + URL_MD5 2c099fe2603fda9a6904fc50d626f71b BUILD_IN_SOURCE 1 CONFIGURE_COMMAND /configure --prefix= ) ExternalProject_get_property(kim_build INSTALL_DIR) - set(KIM_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v1) - set(KIM_LIBRARIES ${INSTALL_DIR}/lib/libkim-api-v1.so) + set(KIM_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) + set(KIM_LIBRARIES ${INSTALL_DIR}/lib/libkim-api-v2.so) list(APPEND LAMMPS_DEPS kim_build) else() find_package(KIM) @@ -706,7 +706,7 @@ if(PKG_USER-INTEL) endif() if(PKG_GPU) - if (CMAKE_VERSION VERSION_LESS "3.1") + if (CMAKE_VERSION VERSION_LESS "3.1") message(FATAL_ERROR "For the GPU package you need at least cmake-3.1") endif() set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) @@ -892,7 +892,7 @@ if(BUILD_EXE) add_dependencies(lmp ${LAMMPS_DEPS}) endif() endif() - + set_target_properties(lmp PROPERTIES OUTPUT_NAME lmp${LAMMPS_MACHINE}) install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) if(ENABLE_TESTING) @@ -954,14 +954,14 @@ message(STATUS "<<< Build configuration >>> get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) list (FIND LANGUAGES "Fortran" _index) if (${_index} GREATER -1) - message(STATUS "Fortran Compiler ${CMAKE_Fortran_COMPILER} + message(STATUS "Fortran Compiler ${CMAKE_Fortran_COMPILER} Type ${CMAKE_Fortran_COMPILER_ID} Version ${CMAKE_Fortran_COMPILER_VERSION} Fortran Flags ${CMAKE_Fortran_FLAGS} ${CMAKE_Fortran_FLAGS_${BTYPE}}") endif() list (FIND LANGUAGES "C" _index) if (${_index} GREATER -1) - message(STATUS "C Compiler ${CMAKE_C_COMPILER} + message(STATUS "C Compiler ${CMAKE_C_COMPILER} Type ${CMAKE_C_COMPILER_ID} Version ${CMAKE_C_COMPILER_VERSION} C Flags ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BTYPE}}") diff --git a/cmake/Modules/FindKIM.cmake b/cmake/Modules/FindKIM.cmake index a01f817cf6..e29f26e01d 100644 --- a/cmake/Modules/FindKIM.cmake +++ b/cmake/Modules/FindKIM.cmake @@ -6,9 +6,9 @@ # KIM_FOUND - True if kim found. # -find_path(KIM_INCLUDE_DIR KIM_API.h PATH_SUFFIXES kim-api-v1) +find_path(KIM_INCLUDE_DIR KIM_SimulatorHeaders.hpp PATH_SUFFIXES kim-api-v2) -find_library(KIM_LIBRARY NAMES kim-api-v1) +find_library(KIM_LIBRARY NAMES kim-api-v2) set(KIM_LIBRARIES ${KIM_LIBRARY}) set(KIM_INCLUDE_DIRS ${KIM_INCLUDE_DIR}) diff --git a/doc/src/Section_packages.txt b/doc/src/Section_packages.txt index 218866e271..839a02b4b6 100644 --- a/doc/src/Section_packages.txt +++ b/doc/src/Section_packages.txt @@ -516,8 +516,7 @@ Elliott (U Minnesota) and James Sethna (Cornell U). [Authors:] Ryan Elliott (U Minnesota) is the main developer for the KIM API which the "pair_style kim"_pair_kim.html command uses. He -developed the pair style in collaboration with Valeriu Smirichinski (U -Minnesota). +developed the pair style. [Install or un-install:] @@ -530,11 +529,11 @@ lib/kim/Install.py script with the specified args. make lib-kim # print help message make lib-kim args="-b " # (re-)install KIM API lib with only example models -make lib-kim args="-b -a Glue_Ercolessi_Adams_Al__MO_324507536345_001" # ditto plus one model +make lib-kim args="-b -a Glue_Ercolessi_Adams_Al__MO_324507536345_002" # ditto plus one model make lib-kim args="-b -a everything" # install KIM API lib with all models -make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # add one model or model driver -make lib-kim args="-p /usr/local/kim-api" # use an existing KIM API installation at the provided location -make lib-kim args="-p /usr/local/kim-api -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # ditto but add one model or driver :pre +make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_003" # add one model or model driver +make lib-kim args="-p /usr/local/lib/kim-api-v2" # use an existing KIM API installation at the provided location +make lib-kim args="-p /usr/local/lib/kim-api-v2 -a EAM_Dynamo_Ackland_W__MO_141627196590_003" # ditto but add one model or driver :pre Note that in LAMMPS lingo, a KIM model driver is a pair style (e.g. EAM or Tersoff). A KIM model is a pair style for a particular @@ -730,13 +729,13 @@ args: make lib-latte # print help message make lib-latte args="-b" # download and build in lib/latte/LATTE-master make lib-latte args="-p $HOME/latte" # use existing LATTE installation in $HOME/latte -make lib-latte args="-b -m gfortran" # download and build in lib/latte and +make lib-latte args="-b -m gfortran" # download and build in lib/latte and # copy Makefile.lammps.gfortran to Makefile.lammps :pre Note that 3 symbolic (soft) links, "includelink" and "liblink" and "filelink.o", are created in lib/latte to point into the LATTE home dir. -When LAMMPS builds in src it will use these links. You should +When LAMMPS builds in src it will use these links. You should also check that the Makefile.lammps file you create is appropriate for the compiler you use on your system to build LATTE. @@ -1667,7 +1666,7 @@ This package provides "fix bocs"_fix_bocs.html, a modified version of "fix npt"_fix_nh.html which includes the pressure correction to the barostat as outlined in: -N. J. H. Dunn and W. G. Noid, "Bottom-up coarse-grained models that +N. J. H. Dunn and W. G. Noid, "Bottom-up coarse-grained models that accurately describe the structure, pressure, and compressibility of molecular liquids," J. Chem. Phys. 143, 243148 (2015). @@ -2279,13 +2278,13 @@ based on the Fortran version of Greg Wagner (Northwestern U) while at Sandia. [Install or un-install:] - + make yes-user-meamc make machine :pre - + make no-user-meamc make machine :pre - + [Supporting info:] src/USER-MEAMC: filenames -> commands @@ -2310,13 +2309,13 @@ algorithm. [Author:] Zhen Li (Division of Applied Mathematics, Brown University) [Install or un-install:] - + make yes-user-meso make machine :pre - + make no-user-meso make machine :pre - + [Supporting info:] src/USER-MESO: filenames -> commands @@ -2336,17 +2335,17 @@ USER-MOFFF package :link(USER-MOFFF),h4 [Contents:] Pair, angle and improper styles needed to employ the MOF-FF -force field by Schmid and coworkers with LAMMPS. +force field by Schmid and coworkers with LAMMPS. MOF-FF is a first principles derived force field with the primary aim -to simulate MOFs and related porous framework materials, using spherical +to simulate MOFs and related porous framework materials, using spherical Gaussian charges. It is described in S. Bureekaew et al., Phys. Stat. Sol. B 2013, 250, 1128-1141. -For the usage of MOF-FF see the example in the example directory as +For the usage of MOF-FF see the example in the example directory as well as the "MOF+"_MOFplus website. :link(MOFplus,https://www.mofplus.org/content/show/MOF-FF) -[Author:] Hendrik Heenen (Technical U of Munich), +[Author:] Hendrik Heenen (Technical U of Munich), Rochus Schmid (Ruhr-University Bochum). [Install or un-install:] diff --git a/doc/src/fix_adapt.txt b/doc/src/fix_adapt.txt index 7a34f2ff44..939a664501 100644 --- a/doc/src/fix_adapt.txt +++ b/doc/src/fix_adapt.txt @@ -123,8 +123,7 @@ meaning of these parameters: "lubricate"_pair_lubricate.html: mu: global: "gauss"_pair_gauss.html: a: type pairs: "morse"_pair_morse.html: d0,r0,alpha: type pairs: -"soft"_pair_soft.html: a: type pairs: -"kim"_pair_kim.html: PARAM_FREE_*:i,j,...: global :tb(c=3,s=:) +"soft"_pair_soft.html: a: type pairs: :tb(c=3,s=:) NOTE: It is easy to add new pairwise potentials and their parameters to this list. All it typically takes is adding an extract() method to @@ -132,12 +131,6 @@ the pair_*.cpp file associated with the potential. Some parameters are global settings for the pair style, e.g. the viscosity setting "mu" for "pair_style lubricate"_pair_lubricate.html. -For "pair_kim"_pair_kim.html, all free parameters supported by the -KIM Model are available (e.g., PARAM_FREE_sigmas provided by the -LennardJones612_Universal__MO_826355984548_001 Model). If the free -parameter corresponds to an array, then the particular array element -to be adapted must be specified (e.g., "PARAM_FREE_sigmas:10", to -adapt the tenth entry of the sigmas array). Other parameters apply to atom type pairs within the pair style, e.g. the prefactor "a" for "pair_style soft"_pair_soft.html. diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index c5d910e27c..3d105e2226 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -10,18 +10,14 @@ pair_style kim command :h3 [Syntax:] -pair_style kim virialmode model printflag :pre +pair_style kim virialmode model :pre virialmode = KIMvirial or LAMMPSvirial model = name of KIM model (potential) -printflag = 1/0 do or do not print KIM descriptor file, optional :ul [Examples:] -pair_style kim KIMvirial model_Ar_P_Morse -pair_coeff * * Ar Ar :pre - -pair_style kim KIMvirial model_Ar_P_Morse 1 +pair_style kim KIMvirial ex_model_Ar_P_LJ pair_coeff * * Ar Ar :pre [Description:] @@ -66,10 +62,6 @@ potential as KIM defines it. In principle, LAMMPS can invoke any KIM model. You should get an error or warning message from either LAMMPS or KIM if there is an incompatibility. -The argument {printflag} is optional. If it is set to a non-zero -value then a KIM descriptor file is printed when KIM is invoked. This -can be useful for debugging. The default is to not print this file. - Only a single pair_coeff command is used with the {kim} style which specifies the mapping of LAMMPS atom types to KIM elements. This is done by specifying N additional arguments after the * * in the @@ -86,18 +78,14 @@ pair_coeff * * Si Si Si C :pre The 1st 2 arguments must be * * so as to span all LAMMPS atom types. The first three Si arguments map LAMMPS atom types 1,2,3 to Si as defined within KIM. The final C argument maps LAMMPS atom type 4 to C -as defined within KIM. If a mapping value is specified as NULL, the -mapping is not performed. This can only be used when a {kim} -potential is used as part of the {hybrid} pair style. The NULL values -are placeholders for atom types that will be used with other -potentials. +as defined within KIM. :line In addition to the usual LAMMPS error messages, the KIM library itself may generate errors, which should be printed to the screen. In this case it is also useful to check the kim.log file for additional error -information. This file kim.log should be generated in the same +information. The file kim.log should be generated in the same directory where LAMMPS is running. To download, build, and install the KIM library on your system, see @@ -130,7 +118,7 @@ LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. This current version of pair_style kim is compatible with the -kim-api package version 1.6.0 and higher. +kim-api package version 2.0.0-beta.0 and higher. [Related commands:] diff --git a/examples/kim/in.kim.lj b/examples/kim/in.kim.lj index f33b258be8..a8e2b9616b 100644 --- a/examples/kim/in.kim.lj +++ b/examples/kim/in.kim.lj @@ -16,14 +16,14 @@ region box block 0 ${xx} 0 ${yy} 0 ${zz} create_box 1 box create_atoms 1 box -#pair_style lj/cut 8.1500 -#pair_coeff 1 1 0.0031 2.7400 +#pair_style lj/cut 7.5548200 +#pair_coeff 1 1 0.0123529 1.8887100 #pair_modify shift yes -pair_style kim KIMvirial ex_model_Ne_P_fastLJ -pair_coeff * * Ne +pair_style kim KIMvirial LennardJones612_Ar +pair_coeff * * Ar -mass 1 20.18 +mass 1 39.95 velocity all create 200.0 232345 loop geom neighbor 0.3 bin diff --git a/examples/kim/in.kim.lj.lmp b/examples/kim/in.kim.lj.lmp index 8879024590..ddb7624945 100644 --- a/examples/kim/in.kim.lj.lmp +++ b/examples/kim/in.kim.lj.lmp @@ -16,14 +16,14 @@ region box block 0 ${xx} 0 ${yy} 0 ${zz} create_box 1 box create_atoms 1 box -pair_style lj/cut 8.1500 -pair_coeff 1 1 0.0031 2.7400 +pair_style lj/cut 7.5548200 +pair_coeff 1 1 0.0123529 1.8887100 pair_modify shift yes -#pair_style kim KIMvirial ex_model_Ne_P_fastLJ -#pair_coeff * * Ne +#pair_style kim KIMvirial LennardJones612_Ar +#pair_coeff * * Ar -mass 1 20.18 +mass 1 39.95 velocity all create 200.0 232345 loop geom neighbor 0.3 bin diff --git a/lib/kim/Install.py b/lib/kim/Install.py index 1bcaffd34a..f9eb1c5eed 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -12,11 +12,11 @@ help = """ Syntax from src dir: make lib-kim args="-b -v version -a kim-name" or: make lib-kim args="-b -a everything" or: make lib-kim args="-n -a kim-name" - or: make lib-kim args="-p /usr/local/open-kim -a kim-name" + or: make lib-kim args="-p /usr/local/lib/kim-api-v2 -a kim-name" Syntax from lib dir: python Install.py -b -v version -a kim-name or: python Install.py -b -a everything or: python Install.py -n -a kim-name - or: python Install.py -p /usr/local/open-kim -a kim-name + or: python Install.py -p /usr/local/lib/kim-api-v2 -a kim-name specify one or more options, order does not matter @@ -36,9 +36,9 @@ specify one or more options, order does not matter Examples: make lib-kim args="-b" # install KIM API lib with only example models -make lib-kim args="-a Glue_Ercolessi_Adams_Al__MO_324507536345_001" # Ditto plus one model +make lib-kim args="-a Glue_Ercolessi_Adams_Al__MO_324507536345_002" # Ditto plus one model make lib-kim args="-b -a everything" # install KIM API lib with all models -make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # only add one model or model driver +make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_003" # only add one model or model driver See the list of KIM model drivers here: https://openkim.org/kim-items/model-drivers/alphabetical diff --git a/lib/kim/README b/lib/kim/README index ce4ea1bdff..80d77d3332 100644 --- a/lib/kim/README +++ b/lib/kim/README @@ -46,8 +46,8 @@ $ rm -rf kim-api-vX.Y.Z.txz 5. To add items do the following (replace the kim item name with your desired value) -$ source ${PWD}/kim-api-vX.Y.Z/bin/kim-api-v1-activate -$ kim-api-v1-collections-management install system Pair_Johnson_Fe__MO_857282754307_002 +$ source ${PWD}/kim-api-vX.Y.Z/bin/kim-api-vX-activate +$ kim-api-vX-collections-management install system Pair_Johnson_Fe__MO_857282754307_002 ----------------- diff --git a/src/KIM/README b/src/KIM/README index 496db92cf2..a69206596f 100644 --- a/src/KIM/README +++ b/src/KIM/README @@ -26,5 +26,4 @@ library you can test it using an input file from the examples dir: ./lmp_serial < lammps/examples/kim/in.kim.lj -This pair_style was written by Valeriu Smirichinski and Ryan -S. Elliott (U Minn). +This pair_style was written by Ryan S. Elliott (U Minn). -- GitLab From 68ec8822ee4b09476d4496eb56522f5d2478a3ec Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Fri, 29 Jun 2018 16:24:15 -0500 Subject: [PATCH 0017/1243] Update example/kim/log.* --- examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.1 | 33 ---------- examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.4 | 33 ---------- examples/kim/log.28Jun15.kim.lj.ubuntu.1 | 33 ---------- examples/kim/log.28Jun15.kim.lj.ubuntu.4 | 33 ---------- examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 | 66 +++++++++++++++++++ examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 | 66 +++++++++++++++++++ examples/kim/log.29Jun18.kim.lj.ubuntu.1 | 68 ++++++++++++++++++++ examples/kim/log.29Jun18.kim.lj.ubuntu.4 | 68 ++++++++++++++++++++ 8 files changed, 268 insertions(+), 132 deletions(-) delete mode 100644 examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.1 delete mode 100644 examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.4 delete mode 100644 examples/kim/log.28Jun15.kim.lj.ubuntu.1 delete mode 100644 examples/kim/log.28Jun15.kim.lj.ubuntu.4 create mode 100644 examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 create mode 100644 examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 create mode 100644 examples/kim/log.29Jun18.kim.lj.ubuntu.1 create mode 100644 examples/kim/log.29Jun18.kim.lj.ubuntu.4 diff --git a/examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.1 b/examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.1 deleted file mode 100644 index efae0587a1..0000000000 --- a/examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.1 +++ /dev/null @@ -1,33 +0,0 @@ -LAMMPS (15 May 2015) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 1 by 1 MPI processor grid -Created 32000 atoms -Neighbor list info ... - 1 neighbor list requests - update every 1 steps, delay 0 steps, check yes - master list distance cutoff = 8.45 -Setting up run ... -Memory usage per processor = 9.18789 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 -741.55469 0 85.684388 -34.939092 - 100 108.37517 -362.56658 0 85.694308 3963.7892 -Loop time of 2.95205 on 1 procs for 100 steps with 32000 atoms - -Pair time (%) = 2.52074 (85.3894) -Neigh time (%) = 0.347949 (11.7867) -Comm time (%) = 0.0228171 (0.772925) -Outpt time (%) = 0.000188828 (0.00639649) -Other time (%) = 0.0603588 (2.04464) - -Nlocal: 32000 ave 32000 max 32000 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 20131 ave 20131 max 20131 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 1.88909e+06 ave 1.88909e+06 max 1.88909e+06 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 1889091 -Ave neighs/atom = 59.0341 -Neighbor list builds = 5 -Dangerous builds = 0 diff --git a/examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.4 b/examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.4 deleted file mode 100644 index 12c1c76695..0000000000 --- a/examples/kim/log.28Jun15.kim.lj.lmp.ubuntu.4 +++ /dev/null @@ -1,33 +0,0 @@ -LAMMPS (15 May 2015) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 2 by 2 MPI processor grid -Created 32000 atoms -Neighbor list info ... - 1 neighbor list requests - update every 1 steps, delay 0 steps, check yes - master list distance cutoff = 8.45 -Setting up run ... -Memory usage per processor = 4.58461 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 -741.55469 0 85.684388 -34.939092 - 100 108.37517 -362.56658 0 85.694308 3963.7892 -Loop time of 6.15911 on 4 procs for 100 steps with 32000 atoms - -Pair time (%) = 1.76201 (28.6083) -Neigh time (%) = 0.265002 (4.30261) -Comm time (%) = 3.64452 (59.1729) -Outpt time (%) = 0.0169877 (0.275815) -Other time (%) = 0.470582 (7.64042) - -Nlocal: 8000 ave 8010 max 7989 min -Histogram: 1 0 0 0 0 2 0 0 0 1 -Nghost: 9240.25 ave 9249 max 9228 min -Histogram: 1 0 0 0 1 0 0 0 0 2 -Neighs: 472273 ave 473390 max 471652 min -Histogram: 2 0 0 1 0 0 0 0 0 1 - -Total # of neighbors = 1889091 -Ave neighs/atom = 59.0341 -Neighbor list builds = 5 -Dangerous builds = 0 diff --git a/examples/kim/log.28Jun15.kim.lj.ubuntu.1 b/examples/kim/log.28Jun15.kim.lj.ubuntu.1 deleted file mode 100644 index 95284453b1..0000000000 --- a/examples/kim/log.28Jun15.kim.lj.ubuntu.1 +++ /dev/null @@ -1,33 +0,0 @@ -LAMMPS (15 May 2015) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 1 by 1 MPI processor grid -Created 32000 atoms -Neighbor list info ... - 1 neighbor list requests - update every 1 steps, delay 0 steps, check yes - master list distance cutoff = 8.45 -Setting up run ... -Memory usage per processor = 9.43789 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 -741.55469 0 85.684388 -34.939092 - 100 108.37517 -362.56658 0 85.694308 3963.7892 -Loop time of 3.79746 on 1 procs for 100 steps with 32000 atoms - -Pair time (%) = 3.18686 (83.9207) -Neigh time (%) = 0.524724 (13.8178) -Comm time (%) = 0.0244031 (0.642616) -Outpt time (%) = 0.000174046 (0.00458321) -Other time (%) = 0.061305 (1.61437) - -Nlocal: 32000 ave 32000 max 32000 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 20131 ave 20131 max 20131 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 2.09236e+06 ave 2.09236e+06 max 2.09236e+06 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 2092355 -Ave neighs/atom = 65.3861 -Neighbor list builds = 5 -Dangerous builds = 0 diff --git a/examples/kim/log.28Jun15.kim.lj.ubuntu.4 b/examples/kim/log.28Jun15.kim.lj.ubuntu.4 deleted file mode 100644 index 7eaf58aad4..0000000000 --- a/examples/kim/log.28Jun15.kim.lj.ubuntu.4 +++ /dev/null @@ -1,33 +0,0 @@ -LAMMPS (15 May 2015) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 2 by 2 MPI processor grid -Created 32000 atoms -Neighbor list info ... - 1 neighbor list requests - update every 1 steps, delay 0 steps, check yes - master list distance cutoff = 8.45 -Setting up run ... -Memory usage per processor = 4.70961 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 -741.55469 0 85.684388 -34.939092 - 100 108.37517 -362.56658 0 85.694308 3963.7892 -Loop time of 7.25305 on 4 procs for 100 steps with 32000 atoms - -Pair time (%) = 2.52571 (34.8227) -Neigh time (%) = 0.500287 (6.8976) -Comm time (%) = 3.70236 (51.0456) -Outpt time (%) = 0.00146681 (0.0202234) -Other time (%) = 0.523229 (7.21391) - -Nlocal: 8000 ave 8010 max 7989 min -Histogram: 1 0 0 0 0 2 0 0 0 1 -Nghost: 9240.25 ave 9249 max 9228 min -Histogram: 1 0 0 0 1 0 0 0 0 2 -Neighs: 555266 ave 555920 max 554805 min -Histogram: 2 0 0 0 0 1 0 0 0 1 - -Total # of neighbors = 2221065 -Ave neighs/atom = 69.4083 -Neighbor list builds = 5 -Dangerous builds = 0 diff --git a/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 b/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 new file mode 100644 index 0000000000..76106e009f --- /dev/null +++ b/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 @@ -0,0 +1,66 @@ +-------------------------------------------------------------------------- +[[30970,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 1 by 1 MPI processor grid +Created 32000 atoms + Time spent = 0.0031676 secs +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 7.85482 + ghost atom cutoff = 7.85482 + binsize = 3.92741, bins = 23 23 23 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d/newton + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 16.58 | 16.58 | 16.58 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 -495.29247 0 331.94661 -978.84224 + 100 212.66365 -547.67175 0 331.94665 -1054.2086 +Loop time of 1.40245 on 1 procs for 100 steps with 32000 atoms + +Performance: 6.161 ns/day, 3.896 hours/ns, 71.304 timesteps/s +100.0% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.2556 | 1.2556 | 1.2556 | 0.0 | 89.53 +Neigh | 0.098976 | 0.098976 | 0.098976 | 0.0 | 7.06 +Comm | 0.011525 | 0.011525 | 0.011525 | 0.0 | 0.82 +Output | 0.00021903 | 0.00021903 | 0.00021903 | 0.0 | 0.02 +Modify | 0.023739 | 0.023739 | 0.023739 | 0.0 | 1.69 +Other | | 0.01244 | | | 0.89 + +Nlocal: 32000 ave 32000 max 32000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19911 ave 19911 max 19911 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 1.36493e+06 ave 1.36493e+06 max 1.36493e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 1364931 +Ave neighs/atom = 42.6541 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:01 diff --git a/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 b/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 new file mode 100644 index 0000000000..634c038efd --- /dev/null +++ b/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 @@ -0,0 +1,66 @@ +-------------------------------------------------------------------------- +[[30962,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.00143054 secs +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 7.85482 + ghost atom cutoff = 7.85482 + binsize = 3.92741, bins = 23 23 23 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d/newton + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 6.875 | 6.875 | 6.875 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 -495.29247 0 331.94661 -978.84224 + 100 212.66365 -547.67175 0 331.94665 -1054.2086 +Loop time of 1.55473 on 4 procs for 100 steps with 32000 atoms + +Performance: 5.557 ns/day, 4.319 hours/ns, 64.320 timesteps/s +23.8% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.47168 | 0.51922 | 0.58923 | 6.2 | 33.40 +Neigh | 0.061309 | 0.077009 | 0.10276 | 5.7 | 4.95 +Comm | 0.87185 | 0.92596 | 0.95327 | 3.4 | 59.56 +Output | 0.00035269 | 0.00047555 | 0.00055331 | 0.0 | 0.03 +Modify | 0.0060711 | 0.00616 | 0.0062612 | 0.1 | 0.40 +Other | | 0.0259 | | | 1.67 + +Nlocal: 8000 ave 8014 max 7988 min +Histogram: 1 0 0 1 1 0 0 0 0 1 +Nghost: 9131 ave 9143 max 9117 min +Histogram: 1 0 0 0 0 1 1 0 0 1 +Neighs: 341233 ave 341715 max 340679 min +Histogram: 1 0 0 0 1 0 0 1 0 1 + +Total # of neighbors = 1364931 +Ave neighs/atom = 42.6541 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:01 diff --git a/examples/kim/log.29Jun18.kim.lj.ubuntu.1 b/examples/kim/log.29Jun18.kim.lj.ubuntu.1 new file mode 100644 index 0000000000..c1875916db --- /dev/null +++ b/examples/kim/log.29Jun18.kim.lj.ubuntu.1 @@ -0,0 +1,68 @@ +-------------------------------------------------------------------------- +[[30495,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 1 by 1 MPI processor grid +Created 32000 atoms + Time spent = 0.00259765 secs +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 7.85482 + ghost atom cutoff = 7.85482 + binsize = 3.92741, bins = 23 23 23 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: full, newton on, ghost, cut 7.55482 + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 27.14 | 27.14 | 27.14 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 -495.29247 0 331.94661 -978.84224 + 100 212.65961 -547.66877 0 331.93294 -1053.7732 +Loop time of 2.12331 on 1 procs for 100 steps with 32000 atoms + +Performance: 4.069 ns/day, 5.898 hours/ns, 47.096 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.7197 | 1.7197 | 1.7197 | 0.0 | 80.99 +Neigh | 0.35501 | 0.35501 | 0.35501 | 0.0 | 16.72 +Comm | 0.012289 | 0.012289 | 0.012289 | 0.0 | 0.58 +Output | 0.00021102 | 0.00021102 | 0.00021102 | 0.0 | 0.01 +Modify | 0.023484 | 0.023484 | 0.023484 | 0.0 | 1.11 +Other | | 0.01266 | | | 0.60 + +Nlocal: 32000 ave 32000 max 32000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19911 ave 19911 max 19911 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 2.569e+06 ave 2.569e+06 max 2.569e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2568996 +Ave neighs/atom = 80.2811 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:02 diff --git a/examples/kim/log.29Jun18.kim.lj.ubuntu.4 b/examples/kim/log.29Jun18.kim.lj.ubuntu.4 new file mode 100644 index 0000000000..5ef352a667 --- /dev/null +++ b/examples/kim/log.29Jun18.kim.lj.ubuntu.4 @@ -0,0 +1,68 @@ +-------------------------------------------------------------------------- +[[30487,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.00128874 secs +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 7.85482 + ghost atom cutoff = 7.85482 + binsize = 3.92741, bins = 23 23 23 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: full, newton on, ghost, cut 7.55482 + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 10.82 | 10.82 | 10.82 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 -495.29247 0 331.94661 -978.84224 + 100 212.65961 -547.66877 0 331.93294 -1053.7732 +Loop time of 2.58934 on 4 procs for 100 steps with 32000 atoms + +Performance: 3.337 ns/day, 7.193 hours/ns, 38.620 timesteps/s +24.3% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.85344 | 0.94031 | 1.0212 | 7.2 | 36.31 +Neigh | 0.40159 | 0.42603 | 0.43728 | 2.2 | 16.45 +Comm | 1.1013 | 1.1823 | 1.2796 | 6.9 | 45.66 +Output | 0.00041301 | 0.00056702 | 0.00081648 | 0.0 | 0.02 +Modify | 0.0062882 | 0.0063459 | 0.0064657 | 0.1 | 0.25 +Other | | 0.03375 | | | 1.30 + +Nlocal: 8000 ave 8014 max 7988 min +Histogram: 1 0 0 1 1 0 0 0 0 1 +Nghost: 9131 ave 9143 max 9117 min +Histogram: 1 0 0 0 0 1 1 0 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 642249 ave 643365 max 641215 min +Histogram: 1 0 0 0 2 0 0 0 0 1 + +Total # of neighbors = 2568996 +Ave neighs/atom = 80.2811 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 -- GitLab From 5bdc29533123fa6f1d0ef487215ad2496c3bc6cd Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sun, 1 Jul 2018 16:23:17 -0500 Subject: [PATCH 0018/1243] Add skin to pair_kim neigh-list cutoffs & update docs --- doc/src/pair_kim.txt | 7 +++++-- examples/kim/in.kim.lj | 6 ++++++ lib/kim/README | 12 +++++++++--- src/KIM/pair_kim.cpp | 3 ++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index 3d105e2226..4599779ca8 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -47,8 +47,11 @@ section of Section packages"_Section_packages.html#KIM has instructions on how to do this with a simple make command, when building LAMMPS. -See the examples/kim dir for an input script that uses a KIM model -(potential) for Lennard-Jones. +See the examples/kim dir for an input script that uses a KIM model (potential) +for Lennard-Jones. Note, for this example input script, the example models +shipped with with kim-api package must be installed. See the "Making +LAMMPS"_Section_start.html#start_3 section and the ./lib/kim/README for details +on how to build LAMMSPS with the kim-api and how to install the example models. :line diff --git a/examples/kim/in.kim.lj b/examples/kim/in.kim.lj index a8e2b9616b..4ce7af97c4 100644 --- a/examples/kim/in.kim.lj +++ b/examples/kim/in.kim.lj @@ -1,4 +1,10 @@ # 3d Lennard-Jones melt +# +# This example requires that the example models provided with +# the kim-api package are installed. see the ./lib/kim/README or +# ./lib/kim/Install.py files for details on how to install these +# example models. +# variable x index 1 variable y index 1 diff --git a/lib/kim/README b/lib/kim/README index 80d77d3332..6bcad18ce0 100644 --- a/lib/kim/README +++ b/lib/kim/README @@ -36,14 +36,20 @@ $ ./configure --prefix=${PWD}/../installed-kim-api-vX.Y.Z $ make $ make install -$ cd .. -4. Remove source and build files +4. To install the example models shipped with the kim-api + +$ cd examples +$ make model-drivers-all-system +$ make models-all-system +$ cd ../.. + +5. Remove source and build files $ rm -rf kim-api-vX.Y.Z $ rm -rf kim-api-vX.Y.Z.txz -5. To add items do the following (replace the kim item name with your +6. To add items do the following (replace the kim item name with your desired value) $ source ${PWD}/kim-api-vX.Y.Z/bin/kim-api-vX-activate diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 5f123de45d..79ced5b9e9 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -429,7 +429,8 @@ void PairKIM::init_style() neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->ghost = 1; neighbor->requests[irequest]->cut = 1; - neighbor->requests[irequest]->cutoff = kim_cutoff_values[i]; + neighbor->requests[irequest]->cutoff + = kim_cutoff_values[i] + neighbor->skin; } return; -- GitLab From 0fbc6bebf545c2d53a2acefc14f5289bfd08b365 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 2 Jul 2018 21:48:47 -0500 Subject: [PATCH 0019/1243] Fix no-virial support -> LAMMPSvirial in pair_kim --- src/KIM/pair_kim.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 79ced5b9e9..ee9bac000d 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -958,9 +958,13 @@ void PairKIM::set_kim_model_has_flags() error->warning(FLERR,"KIM Model does not provide `partialForce'; " "Forces will be zero"); - if (kim_model_support_for_virial == notSupported) + if ((no_virial_fdotr_compute == 1) && + (kim_model_support_for_virial == notSupported)) + { error->warning(FLERR,"KIM Model does not provide `partialVirial'. " "pair_kim now using `LAMMPSvirial' option."); + no_virial_fdotr_compute = 0; + } if (kim_model_support_for_particleEnergy == notSupported) error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; " -- GitLab From 0264e044e2d7db5635fae76f74c09bd71b6b392d Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 2 Jul 2018 21:51:05 -0500 Subject: [PATCH 0020/1243] Update example/kim input files --- examples/kim/in.kim.lj | 8 ++++---- examples/kim/in.kim.lj.lmp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/kim/in.kim.lj b/examples/kim/in.kim.lj index 4ce7af97c4..851243bed8 100644 --- a/examples/kim/in.kim.lj +++ b/examples/kim/in.kim.lj @@ -22,11 +22,11 @@ region box block 0 ${xx} 0 ${yy} 0 ${zz} create_box 1 box create_atoms 1 box -#pair_style lj/cut 7.5548200 -#pair_coeff 1 1 0.0123529 1.8887100 -#pair_modify shift yes +#pair_style lj/cut 8.1500 +#pair_coeff 1 1 0.0104 3.4000 +#pair_modify shift no -pair_style kim KIMvirial LennardJones612_Ar +pair_style kim LAMMPSvirial LennardJones_Ar pair_coeff * * Ar mass 1 39.95 diff --git a/examples/kim/in.kim.lj.lmp b/examples/kim/in.kim.lj.lmp index ddb7624945..aa6dbcad6f 100644 --- a/examples/kim/in.kim.lj.lmp +++ b/examples/kim/in.kim.lj.lmp @@ -16,11 +16,11 @@ region box block 0 ${xx} 0 ${yy} 0 ${zz} create_box 1 box create_atoms 1 box -pair_style lj/cut 7.5548200 -pair_coeff 1 1 0.0123529 1.8887100 -pair_modify shift yes +pair_style lj/cut 8.1500 +pair_coeff 1 1 0.0104 3.4000 +pair_modify shift no -#pair_style kim KIMvirial LennardJones612_Ar +#pair_style kim KIMvirial LennardJones_Ar #pair_coeff * * Ar mass 1 39.95 -- GitLab From 7eeb96f1afdc3aa1a37cd5429727e3549b8ebcc0 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Tue, 3 Jul 2018 23:37:54 -0500 Subject: [PATCH 0021/1243] Update pair_kim to work with new neig. list Hints --- examples/kim/in.kim.lj | 4 +- examples/kim/in.kim.lj.lmp | 2 +- examples/kim/in.kim.lj.lmp.newton-on | 35 ++++ ...g.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1} | 42 ++-- ...g.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4} | 52 ++--- ...tu.1 => log.04Jul2018.kim.lj.lmp.ubuntu.1} | 48 +++-- .../kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 | 66 ++++++ examples/kim/log.04Jul2018.kim.lj.ubuntu.1 | 69 +++++++ examples/kim/log.04Jul2018.kim.lj.ubuntu.4 | 78 ++++++++ examples/kim/log.29Jun18.kim.lj.ubuntu.4 | 68 ------- src/KIM/pair_kim.cpp | 188 ++++++++++-------- src/KIM/pair_kim.h | 10 +- 12 files changed, 433 insertions(+), 229 deletions(-) create mode 100644 examples/kim/in.kim.lj.lmp.newton-on rename examples/kim/{log.29Jun18.kim.lj.lmp.ubuntu.1 => log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1} (56%) rename examples/kim/{log.29Jun18.kim.lj.lmp.ubuntu.4 => log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4} (50%) rename examples/kim/{log.29Jun18.kim.lj.ubuntu.1 => log.04Jul2018.kim.lj.lmp.ubuntu.1} (52%) create mode 100644 examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 create mode 100644 examples/kim/log.04Jul2018.kim.lj.ubuntu.1 create mode 100644 examples/kim/log.04Jul2018.kim.lj.ubuntu.4 delete mode 100644 examples/kim/log.29Jun18.kim.lj.ubuntu.4 diff --git a/examples/kim/in.kim.lj b/examples/kim/in.kim.lj index 851243bed8..a17ec982da 100644 --- a/examples/kim/in.kim.lj +++ b/examples/kim/in.kim.lj @@ -16,6 +16,7 @@ variable zz equal 20*$z units metal atom_style atomic +newton off lattice fcc 4.4300 region box block 0 ${xx} 0 ${yy} 0 ${zz} @@ -24,9 +25,8 @@ create_atoms 1 box #pair_style lj/cut 8.1500 #pair_coeff 1 1 0.0104 3.4000 -#pair_modify shift no -pair_style kim LAMMPSvirial LennardJones_Ar +pair_style kim KIMvirial LennardJones_Ar pair_coeff * * Ar mass 1 39.95 diff --git a/examples/kim/in.kim.lj.lmp b/examples/kim/in.kim.lj.lmp index aa6dbcad6f..a10e3e2e90 100644 --- a/examples/kim/in.kim.lj.lmp +++ b/examples/kim/in.kim.lj.lmp @@ -10,6 +10,7 @@ variable zz equal 20*$z units metal atom_style atomic +newton off lattice fcc 4.4300 region box block 0 ${xx} 0 ${yy} 0 ${zz} @@ -18,7 +19,6 @@ create_atoms 1 box pair_style lj/cut 8.1500 pair_coeff 1 1 0.0104 3.4000 -pair_modify shift no #pair_style kim KIMvirial LennardJones_Ar #pair_coeff * * Ar diff --git a/examples/kim/in.kim.lj.lmp.newton-on b/examples/kim/in.kim.lj.lmp.newton-on new file mode 100644 index 0000000000..d17bc14984 --- /dev/null +++ b/examples/kim/in.kim.lj.lmp.newton-on @@ -0,0 +1,35 @@ +# 3d Lennard-Jones melt + +variable x index 1 +variable y index 1 +variable z index 1 + +variable xx equal 20*$x +variable yy equal 20*$y +variable zz equal 20*$z + +units metal +atom_style atomic +newton on + +lattice fcc 4.4300 +region box block 0 ${xx} 0 ${yy} 0 ${zz} +create_box 1 box +create_atoms 1 box + +pair_style lj/cut 8.1500 +pair_coeff 1 1 0.0104 3.4000 + +#pair_style kim KIMvirial LennardJones_Ar +#pair_coeff * * Ar + +mass 1 39.95 +velocity all create 200.0 232345 loop geom + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 1 all nve +#fix 1 all npt temp 1.0 1.0 1.0 iso 1.0 1.0 3.0 + +run 100 diff --git a/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 b/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 similarity index 56% rename from examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 rename to examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 index 76106e009f..70eae36a48 100644 --- a/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.1 +++ b/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[30970,1],0]: A high-performance Open MPI point-to-point messaging module +[[19053,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,13 +16,13 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.0031676 secs + Time spent = 0.00270113 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 7.85482 - ghost atom cutoff = 7.85482 - binsize = 3.92741, bins = 23 23 23 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 1 neighbor lists, perpetual/occasional/extra = 1 0 0 (1) pair lj/cut, perpetual attributes: half, newton on @@ -33,34 +33,34 @@ Setting up Verlet run ... Unit style : metal Current step : 0 Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 16.58 | 16.58 | 16.58 Mbytes +Per MPI rank memory allocation (min/avg/max) = 19.23 | 19.23 | 19.23 Mbytes Step Temp E_pair E_mol TotEng Press - 0 200 -495.29247 0 331.94661 -978.84224 - 100 212.66365 -547.67175 0 331.94665 -1054.2086 -Loop time of 1.40245 on 1 procs for 100 steps with 32000 atoms + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.18554 on 1 procs for 100 steps with 32000 atoms -Performance: 6.161 ns/day, 3.896 hours/ns, 71.304 timesteps/s -100.0% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 3.953 ns/day, 6.071 hours/ns, 45.755 timesteps/s +99.6% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 1.2556 | 1.2556 | 1.2556 | 0.0 | 89.53 -Neigh | 0.098976 | 0.098976 | 0.098976 | 0.0 | 7.06 -Comm | 0.011525 | 0.011525 | 0.011525 | 0.0 | 0.82 -Output | 0.00021903 | 0.00021903 | 0.00021903 | 0.0 | 0.02 -Modify | 0.023739 | 0.023739 | 0.023739 | 0.0 | 1.69 -Other | | 0.01244 | | | 0.89 +Pair | 2.0006 | 2.0006 | 2.0006 | 0.0 | 91.54 +Neigh | 0.13933 | 0.13933 | 0.13933 | 0.0 | 6.38 +Comm | 0.011122 | 0.011122 | 0.011122 | 0.0 | 0.51 +Output | 0.00020978 | 0.00020978 | 0.00020978 | 0.0 | 0.01 +Modify | 0.022358 | 0.022358 | 0.022358 | 0.0 | 1.02 +Other | | 0.01188 | | | 0.54 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 Nghost: 19911 ave 19911 max 19911 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 1.36493e+06 ave 1.36493e+06 max 1.36493e+06 min +Neighs: 2.12688e+06 ave 2.12688e+06 max 2.12688e+06 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Total # of neighbors = 1364931 -Ave neighs/atom = 42.6541 +Total # of neighbors = 2126875 +Ave neighs/atom = 66.4648 Neighbor list builds = 3 Dangerous builds = 0 -Total wall time: 0:00:01 +Total wall time: 0:00:02 diff --git a/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 b/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 similarity index 50% rename from examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 rename to examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 index 634c038efd..e7157c11b8 100644 --- a/examples/kim/log.29Jun18.kim.lj.lmp.ubuntu.4 +++ b/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[30962,1],0]: A high-performance Open MPI point-to-point messaging module +[[19045,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,13 +16,13 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00143054 secs + Time spent = 0.00117056 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 7.85482 - ghost atom cutoff = 7.85482 - binsize = 3.92741, bins = 23 23 23 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 1 neighbor lists, perpetual/occasional/extra = 1 0 0 (1) pair lj/cut, perpetual attributes: half, newton on @@ -33,34 +33,34 @@ Setting up Verlet run ... Unit style : metal Current step : 0 Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 6.875 | 6.875 | 6.875 Mbytes +Per MPI rank memory allocation (min/avg/max) = 7.632 | 7.632 | 7.632 Mbytes Step Temp E_pair E_mol TotEng Press - 0 200 -495.29247 0 331.94661 -978.84224 - 100 212.66365 -547.67175 0 331.94665 -1054.2086 -Loop time of 1.55473 on 4 procs for 100 steps with 32000 atoms + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.34104 on 4 procs for 100 steps with 32000 atoms -Performance: 5.557 ns/day, 4.319 hours/ns, 64.320 timesteps/s -23.8% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 3.691 ns/day, 6.503 hours/ns, 42.716 timesteps/s +24.0% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.47168 | 0.51922 | 0.58923 | 6.2 | 33.40 -Neigh | 0.061309 | 0.077009 | 0.10276 | 5.7 | 4.95 -Comm | 0.87185 | 0.92596 | 0.95327 | 3.4 | 59.56 -Output | 0.00035269 | 0.00047555 | 0.00055331 | 0.0 | 0.03 -Modify | 0.0060711 | 0.00616 | 0.0062612 | 0.1 | 0.40 -Other | | 0.0259 | | | 1.67 +Pair | 0.91499 | 0.96396 | 1.0567 | 5.6 | 41.18 +Neigh | 0.092245 | 0.11781 | 0.14572 | 6.0 | 5.03 +Comm | 1.1264 | 1.2287 | 1.2906 | 5.6 | 52.49 +Output | 0.00045199 | 0.00051154 | 0.00060273 | 0.0 | 0.02 +Modify | 0.0058738 | 0.0059629 | 0.0061675 | 0.2 | 0.25 +Other | | 0.02406 | | | 1.03 -Nlocal: 8000 ave 8014 max 7988 min -Histogram: 1 0 0 1 1 0 0 0 0 1 -Nghost: 9131 ave 9143 max 9117 min -Histogram: 1 0 0 0 0 1 1 0 0 1 -Neighs: 341233 ave 341715 max 340679 min -Histogram: 1 0 0 0 1 0 0 1 0 1 +Nlocal: 8000 ave 8018 max 7967 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Nghost: 9131 ave 9164 max 9113 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Neighs: 531719 ave 533273 max 529395 min +Histogram: 1 0 0 0 1 0 0 0 0 2 -Total # of neighbors = 1364931 -Ave neighs/atom = 42.6541 +Total # of neighbors = 2126875 +Ave neighs/atom = 66.4648 Neighbor list builds = 3 Dangerous builds = 0 -Total wall time: 0:00:01 +Total wall time: 0:00:02 diff --git a/examples/kim/log.29Jun18.kim.lj.ubuntu.1 b/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.1 similarity index 52% rename from examples/kim/log.29Jun18.kim.lj.ubuntu.1 rename to examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.1 index c1875916db..217568072c 100644 --- a/examples/kim/log.29Jun18.kim.lj.ubuntu.1 +++ b/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.1 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[30495,1],0]: A high-performance Open MPI point-to-point messaging module +[[19074,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,53 +16,51 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00259765 secs + Time spent = 0.00251478 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 7.85482 - ghost atom cutoff = 7.85482 - binsize = 3.92741, bins = 23 23 23 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair kim, perpetual - attributes: full, newton on, ghost, cut 7.55482 - pair build: full/bin/ghost - stencil: full/ghost/bin/3d + (1) pair lj/cut, perpetual + attributes: half, newton off + pair build: half/bin/newtoff + stencil: half/bin/3d/newtoff bin: standard Setting up Verlet run ... Unit style : metal Current step : 0 Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 27.14 | 27.14 | 27.14 Mbytes +Per MPI rank memory allocation (min/avg/max) = 20.37 | 20.37 | 20.37 Mbytes Step Temp E_pair E_mol TotEng Press - 0 200 -495.29247 0 331.94661 -978.84224 - 100 212.65961 -547.66877 0 331.93294 -1053.7732 -Loop time of 2.12331 on 1 procs for 100 steps with 32000 atoms + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.6218 on 1 procs for 100 steps with 32000 atoms -Performance: 4.069 ns/day, 5.898 hours/ns, 47.096 timesteps/s +Performance: 3.295 ns/day, 7.283 hours/ns, 38.142 timesteps/s 99.9% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 1.7197 | 1.7197 | 1.7197 | 0.0 | 80.99 -Neigh | 0.35501 | 0.35501 | 0.35501 | 0.0 | 16.72 -Comm | 0.012289 | 0.012289 | 0.012289 | 0.0 | 0.58 -Output | 0.00021102 | 0.00021102 | 0.00021102 | 0.0 | 0.01 -Modify | 0.023484 | 0.023484 | 0.023484 | 0.0 | 1.11 -Other | | 0.01266 | | | 0.60 +Pair | 2.2623 | 2.2623 | 2.2623 | 0.0 | 86.29 +Neigh | 0.31859 | 0.31859 | 0.31859 | 0.0 | 12.15 +Comm | 0.005914 | 0.005914 | 0.005914 | 0.0 | 0.23 +Output | 0.00033105 | 0.00033105 | 0.00033105 | 0.0 | 0.01 +Modify | 0.023461 | 0.023461 | 0.023461 | 0.0 | 0.89 +Other | | 0.01123 | | | 0.43 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 Nghost: 19911 ave 19911 max 19911 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 0 ave 0 max 0 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -FullNghs: 2.569e+06 ave 2.569e+06 max 2.569e+06 min +Neighs: 2.3705e+06 ave 2.3705e+06 max 2.3705e+06 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Total # of neighbors = 2568996 -Ave neighs/atom = 80.2811 +Total # of neighbors = 2370499 +Ave neighs/atom = 74.0781 Neighbor list builds = 3 Dangerous builds = 0 Total wall time: 0:00:02 diff --git a/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 b/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 new file mode 100644 index 0000000000..806c674efb --- /dev/null +++ b/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 @@ -0,0 +1,66 @@ +-------------------------------------------------------------------------- +[[19098,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.00123697 secs +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton off + pair build: half/bin/newtoff + stencil: half/bin/3d/newtoff + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 8.013 | 8.013 | 8.013 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.88232 on 4 procs for 100 steps with 32000 atoms + +Performance: 2.998 ns/day, 8.006 hours/ns, 34.694 timesteps/s +24.6% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.3577 | 1.415 | 1.467 | 3.7 | 49.09 +Neigh | 0.25761 | 0.28189 | 0.29894 | 3.2 | 9.78 +Comm | 0.58287 | 0.73218 | 0.85561 | 11.5 | 25.40 +Output | 0.00082721 | 0.0029034 | 0.0051877 | 3.1 | 0.10 +Modify | 0.0058569 | 0.015767 | 0.033242 | 8.6 | 0.55 +Other | | 0.4346 | | | 15.08 + +Nlocal: 8000 ave 8018 max 7967 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Nghost: 9131 ave 9164 max 9113 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Neighs: 630904 ave 632094 max 628209 min +Histogram: 1 0 0 0 0 0 0 1 0 2 + +Total # of neighbors = 2523614 +Ave neighs/atom = 78.8629 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/kim/log.04Jul2018.kim.lj.ubuntu.1 b/examples/kim/log.04Jul2018.kim.lj.ubuntu.1 new file mode 100644 index 0000000000..3832bd060a --- /dev/null +++ b/examples/kim/log.04Jul2018.kim.lj.ubuntu.1 @@ -0,0 +1,69 @@ +-------------------------------------------------------------------------- +[[19111,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 1 by 1 MPI processor grid +Created 32000 atoms + Time spent = 0.00257231 secs +WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: half, newton off, cut 8.45 + pair build: half/bin/newtoff + stencil: half/bin/3d/newtoff + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 21.26 | 21.26 | 21.26 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 1270.4248 + 100 95.179725 6718.814 0 7112.496 604.59343 +Loop time of 3.22934 on 1 procs for 100 steps with 32000 atoms + +Performance: 2.675 ns/day, 8.970 hours/ns, 30.966 timesteps/s +99.9% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.821 | 2.821 | 2.821 | 0.0 | 87.36 +Neigh | 0.35198 | 0.35198 | 0.35198 | 0.0 | 10.90 +Comm | 0.0081757 | 0.0081757 | 0.0081757 | 0.0 | 0.25 +Output | 0.00030922 | 0.00030922 | 0.00030922 | 0.0 | 0.01 +Modify | 0.032856 | 0.032856 | 0.032856 | 0.0 | 1.02 +Other | | 0.01501 | | | 0.46 + +Nlocal: 32000 ave 32000 max 32000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19911 ave 19911 max 19911 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 2.3705e+06 ave 2.3705e+06 max 2.3705e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2370499 +Ave neighs/atom = 74.0781 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/kim/log.04Jul2018.kim.lj.ubuntu.4 b/examples/kim/log.04Jul2018.kim.lj.ubuntu.4 new file mode 100644 index 0000000000..70b2f82812 --- /dev/null +++ b/examples/kim/log.04Jul2018.kim.lj.ubuntu.4 @@ -0,0 +1,78 @@ +-------------------------------------------------------------------------- +[[19135,1],1]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.00154417 secs +WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) +WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) +WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) +WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: half, newton off, cut 8.45 + pair build: half/bin/newtoff + stencil: half/bin/3d/newtoff + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 8.528 | 8.528 | 8.528 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 1270.4248 + 100 95.179725 6718.814 0 7112.496 604.59343 +Loop time of 3.17877 on 4 procs for 100 steps with 32000 atoms + +Performance: 2.718 ns/day, 8.830 hours/ns, 31.459 timesteps/s +24.3% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.0514 | 2.1009 | 2.1859 | 3.6 | 66.09 +Neigh | 0.29304 | 0.31706 | 0.33568 | 2.7 | 9.97 +Comm | 0.61926 | 0.72709 | 0.77083 | 7.3 | 22.87 +Output | 0.00035457 | 0.00043741 | 0.000547 | 0.0 | 0.01 +Modify | 0.0066107 | 0.0067653 | 0.0069097 | 0.1 | 0.21 +Other | | 0.02653 | | | 0.83 + +Nlocal: 8000 ave 8018 max 7967 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Nghost: 9131 ave 9164 max 9113 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Neighs: 630904 ave 632094 max 628209 min +Histogram: 1 0 0 0 0 0 0 1 0 2 + +Total # of neighbors = 2523614 +Ave neighs/atom = 78.8629 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/kim/log.29Jun18.kim.lj.ubuntu.4 b/examples/kim/log.29Jun18.kim.lj.ubuntu.4 deleted file mode 100644 index 5ef352a667..0000000000 --- a/examples/kim/log.29Jun18.kim.lj.ubuntu.4 +++ /dev/null @@ -1,68 +0,0 @@ --------------------------------------------------------------------------- -[[30487,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 2 by 2 MPI processor grid -Created 32000 atoms - Time spent = 0.00128874 secs -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 7.85482 - ghost atom cutoff = 7.85482 - binsize = 3.92741, bins = 23 23 23 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair kim, perpetual - attributes: full, newton on, ghost, cut 7.55482 - pair build: full/bin/ghost - stencil: full/ghost/bin/3d - bin: standard -Setting up Verlet run ... - Unit style : metal - Current step : 0 - Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 10.82 | 10.82 | 10.82 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 -495.29247 0 331.94661 -978.84224 - 100 212.65961 -547.66877 0 331.93294 -1053.7732 -Loop time of 2.58934 on 4 procs for 100 steps with 32000 atoms - -Performance: 3.337 ns/day, 7.193 hours/ns, 38.620 timesteps/s -24.3% CPU use with 4 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.85344 | 0.94031 | 1.0212 | 7.2 | 36.31 -Neigh | 0.40159 | 0.42603 | 0.43728 | 2.2 | 16.45 -Comm | 1.1013 | 1.1823 | 1.2796 | 6.9 | 45.66 -Output | 0.00041301 | 0.00056702 | 0.00081648 | 0.0 | 0.02 -Modify | 0.0062882 | 0.0063459 | 0.0064657 | 0.1 | 0.25 -Other | | 0.03375 | | | 1.30 - -Nlocal: 8000 ave 8014 max 7988 min -Histogram: 1 0 0 1 1 0 0 0 0 1 -Nghost: 9131 ave 9143 max 9117 min -Histogram: 1 0 0 0 0 1 1 0 0 1 -Neighs: 0 ave 0 max 0 min -Histogram: 4 0 0 0 0 0 0 0 0 0 -FullNghs: 642249 ave 643365 max 641215 min -Histogram: 1 0 0 0 2 0 0 0 0 1 - -Total # of neighbors = 2568996 -Ave neighs/atom = 80.2811 -Neighbor list builds = 3 -Dangerous builds = 0 -Total wall time: 0:00:03 diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index ee9bac000d..ca39b5601e 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -12,13 +12,11 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing authors: Ryan S. Elliott, - Valeriu Smirichinski, - Ellad Tadmor + Contributing authors: Ryan S. Elliott (UMinn) ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v1.6.0 (and newer) package + Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package ------------------------------------------------------------------------- */ #include @@ -45,9 +43,9 @@ PairKIM::PairKIM(LAMMPS *lmp) : Pair(lmp), settings_call_count(0), init_style_call_count(0), - kim_modelname(0), - lmps_map_species_to_unique(0), - lmps_unique_elements(0), + kim_modelname(NULL), + lmps_map_species_to_unique(NULL), + lmps_unique_elements(NULL), lmps_num_unique_elements(0), lmps_units(METAL), lengthUnit(KIM::LENGTH_UNIT::unused), @@ -55,8 +53,8 @@ PairKIM::PairKIM(LAMMPS *lmp) : chargeUnit(KIM::CHARGE_UNIT::unused), temperatureUnit(KIM::TEMPERATURE_UNIT::unused), timeUnit(KIM::TIME_UNIT::unused), - pkim(0), - pargs(0), + pkim(NULL), + pargs(NULL), kim_model_support_for_energy(KIM::SUPPORT_STATUS::notSupported), kim_model_support_for_forces(KIM::SUPPORT_STATUS::notSupported), kim_model_support_for_virial(KIM::SUPPORT_STATUS::notSupported), @@ -64,15 +62,17 @@ PairKIM::PairKIM(LAMMPS *lmp) : kim_model_support_for_particleVirial(KIM::SUPPORT_STATUS::notSupported), lmps_local_tot_num_atoms(0), kim_global_influence_distance(0.0), - kim_number_of_cutoffs(0), - kim_cutoff_values(0), - neighborLists(0), - kim_particle_codes(0), + kim_number_of_neighbor_lists(0), + kim_cutoff_values(NULL), + padding_neighbor_hints(NULL), + half_list_hints(NULL), + neighborLists(NULL), + kim_particle_codes(NULL), lmps_maxalloc(0), - kim_particleSpecies(0), - kim_particleContributing(0), - lmps_stripped_neigh_list(0), - lmps_stripped_neigh_ptr(0) + kim_particleSpecies(NULL), + kim_particleContributing(NULL), + lmps_stripped_neigh_list(NULL), + lmps_stripped_neigh_ptr(NULL) { // Initialize Pair data members to appropriate values single_enable = 0; // We do not provide the Single() function @@ -101,6 +101,13 @@ PairKIM::~PairKIM() delete [] lmps_unique_elements[i]; delete [] lmps_unique_elements; + if (kim_particle_codes_ok) + { + delete [] kim_particle_codes; + kim_particle_codes = NULL; + kim_particle_codes_ok = false; + } + // clean up local memory used to support KIM interface memory->destroy(kim_particleSpecies); memory->destroy(kim_particleContributing); @@ -281,20 +288,6 @@ void PairKIM::settings(int narg, char **arg) // set lmps_* bool flags set_lmps_flags(); - // set virial handling - if (strcmp(arg[0],"LAMMPSvirial") == 0) - { - no_virial_fdotr_compute = 0; - } - else if (strcmp(arg[0],"KIMvirial") == 0) - { - no_virial_fdotr_compute = 1; - } - else - { - error->all(FLERR,"Unrecognized virial argument in pair_style command"); - } - // set KIM Model name int nmlen = strlen(arg[1]); if (kim_modelname != 0) @@ -305,6 +298,26 @@ void PairKIM::settings(int narg, char **arg) kim_modelname = new char[nmlen+1]; strcpy(kim_modelname, arg[1]); + // initialize KIM Model + kim_init(); + + // set virial handling + if (strcmp(arg[0],"KIMvirial") == 0) + { + if (kim_model_support_for_virial == KIM::SUPPORT_STATUS::notSupported) + no_virial_fdotr_compute = 0; + else + no_virial_fdotr_compute = 1; + } + else if (strcmp(arg[0],"LAMMPSvirial") == 0) + { + no_virial_fdotr_compute = 0; + } + else + { + error->all(FLERR,"Unrecognized virial argument in pair_style command"); + } + return; } @@ -351,7 +364,7 @@ void PairKIM::coeff(int narg, char **arg) // Assume all species arguments are valid - // errors will be detected by kim_api_init() matching + // errors will be detected by below lmps_num_unique_elements = 0; for (i = 2; i < narg; i++) { for (j = 0; j < lmps_num_unique_elements; j++) @@ -378,6 +391,29 @@ void PairKIM::coeff(int narg, char **arg) if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); + // setup mapping between LAMMPS unique elements and KIM species codes + if (kim_particle_codes_ok) + { + delete [] kim_particle_codes; + kim_particle_codes = NULL; + kim_particle_codes_ok = false; + } + kim_particle_codes = new int[lmps_num_unique_elements]; + kim_particle_codes_ok = true; + for(int i = 0; i < lmps_num_unique_elements; i++){ + int kimerror; + int supported; + int code; + kimerror = pkim->GetSpeciesSupportAndCode( + KIM::SpeciesName(lmps_unique_elements[i]), + &supported, + &code); + if (supported) + kim_particle_codes[i] = code; + else + error->all(FLERR,"create_kim_particle_codes: symbol not found "); + } + return; } @@ -394,22 +430,16 @@ void PairKIM::init_style() error->all(FLERR,"PairKIM only works with 3D problems"); int kimerror; - // KIM and Model initialization (only once) - // also sets kim_ind_* and kim_* bool flags - if (!kim_init_ok) - { - kim_init(); - } // setup lmps_stripped_neigh_list for neighbors of one atom, if needed if (lmps_using_molecular) { memory->destroy(lmps_stripped_neigh_list); memory->create(lmps_stripped_neigh_list, - kim_number_of_cutoffs*neighbor->oneatom, + kim_number_of_neighbor_lists*neighbor->oneatom, "pair:lmps_stripped_neigh_list"); delete [] lmps_stripped_neigh_ptr; - lmps_stripped_neigh_ptr = new int*[kim_number_of_cutoffs]; - for (int i = 0; i < kim_number_of_cutoffs; ++i) + lmps_stripped_neigh_ptr = new int*[kim_number_of_neighbor_lists]; + for (int i = 0; i < kim_number_of_neighbor_lists; ++i) { lmps_stripped_neigh_ptr[0] = &(lmps_stripped_neigh_list[(i-1)*(neighbor->oneatom)]); @@ -420,14 +450,32 @@ void PairKIM::init_style() // make sure comm_reverse expects (at most) 9 values when newton is off if (!lmps_using_newton) comm_reverse_off = 9; - // request full neighbor lists - for (int i = 0; i < kim_number_of_cutoffs; ++i) + // request full neighbor lists (unless hints allow for better alternatives) + for (int i = 0; i < kim_number_of_neighbor_lists; ++i) { int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->id = i; - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->ghost = 1; + if (half_list_hints[i]) + { + neighbor->requests[irequest]->half = 1; + if (! lmps_using_newton) neighbor->requests[irequest]->newton = 2; + neighbor->requests[irequest]->full = 0; + } + else + { + neighbor->requests[irequest]->half = 0; + if (! lmps_using_newton) neighbor->requests[irequest]->newton = 0; + neighbor->requests[irequest]->full = 1; + } + if (padding_neighbor_hints[i]) + { + neighbor->requests[irequest]->ghost = 0; + } + else + { + neighbor->requests[irequest]->ghost = 1; + + } neighbor->requests[irequest]->cut = 1; neighbor->requests[irequest]->cutoff = kim_cutoff_values[i] + neighbor->skin; @@ -604,7 +652,8 @@ double PairKIM::memory_usage() ------------------------------------------------------------------------- */ int PairKIM::get_neigh(void const * const dataObject, - int const numberOfCutoffs, double const * const cutoffs, + int const numberOfNeighborLists, + double const * const cutoffs, int const neighborListIndex, int const particleNumber, int * const numberOfNeighbors, int const ** const neighborsOfParticle) @@ -612,8 +661,9 @@ int PairKIM::get_neigh(void const * const dataObject, PairKIM const * const Model = reinterpret_cast(dataObject); - if (numberOfCutoffs != Model->kim_number_of_cutoffs) return true; - for (int i = 0; i < numberOfCutoffs; ++i) + if (numberOfNeighborLists != Model->kim_number_of_neighbor_lists) + return true; + for (int i = 0; i < numberOfNeighborLists; ++i) { if (Model->kim_cutoff_values[i] < cutoffs[i]) return true; } @@ -666,13 +716,6 @@ void PairKIM::kim_free() } kim_init_ok = false; - if (kim_particle_codes_ok) - { - delete [] kim_particle_codes; - kim_particle_codes = 0; - kim_particle_codes_ok = false; - } - return; } @@ -713,32 +756,17 @@ void PairKIM::kim_init() // determine KIM Model capabilities (used in this function below) set_kim_model_has_flags(); - // setup mapping between LAMMPS unique elements and KIM species codes - kim_particle_codes = new int[lmps_num_unique_elements]; - kim_particle_codes_ok = true; - for(int i = 0; i < lmps_num_unique_elements; i++){ - int kimerror; - int supported; - int code; - kimerror = pkim->GetSpeciesSupportAndCode( - KIM::SpeciesName(lmps_unique_elements[i]), - &supported, - &code); - if (supported) - kim_particle_codes[i] = code; - else - error->all(FLERR,"create_kim_particle_codes: symbol not found "); - } - pkim->GetInfluenceDistance(&kim_global_influence_distance); - pkim->GetNeighborListCutoffsPointer(&kim_number_of_cutoffs, - &kim_cutoff_values); + pkim->GetNeighborListPointers(&kim_number_of_neighbor_lists, + &kim_cutoff_values, + &padding_neighbor_hints, + &half_list_hints); if (neighborLists) { delete [] neighborLists; neighborLists = 0; } - neighborLists = new NeighList*[kim_number_of_cutoffs]; + neighborLists = new NeighList*[kim_number_of_neighbor_lists]; kimerror = pargs->SetArgumentPointer( KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, @@ -932,7 +960,7 @@ void PairKIM::set_kim_model_has_flags() int kimerror = GetComputeArgumentName(i, &computeArgumentName); KIM::SupportStatus supportStatus; kimerror = pargs->GetArgumentSupportStatus(computeArgumentName, - &supportStatus); + &supportStatus); if (computeArgumentName == partialEnergy) kim_model_support_for_energy = supportStatus; @@ -958,12 +986,10 @@ void PairKIM::set_kim_model_has_flags() error->warning(FLERR,"KIM Model does not provide `partialForce'; " "Forces will be zero"); - if ((no_virial_fdotr_compute == 1) && - (kim_model_support_for_virial == notSupported)) + if (kim_model_support_for_virial == notSupported) { error->warning(FLERR,"KIM Model does not provide `partialVirial'. " - "pair_kim now using `LAMMPSvirial' option."); - no_virial_fdotr_compute = 0; + "pair_kim will always use `LAMMPSvirial' option."); } if (kim_model_support_for_particleEnergy == notSupported) diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index a236a3f87a..8929fd2b75 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -12,13 +12,11 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing authors: Ryan S. Elliott, - Valeriu Smirichinski, - Ellad Tadmor (U Minn) + Contributing authors: Ryan S. Elliott (UMinn) ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v1.6.0 (and newer) package + Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS @@ -100,8 +98,10 @@ namespace LAMMPS_NS { bool kim_init_ok; int lmps_local_tot_num_atoms; double kim_global_influence_distance; // KIM Model cutoff value - int kim_number_of_cutoffs; + int kim_number_of_neighbor_lists; double const * kim_cutoff_values; + int const * padding_neighbor_hints; + int const * half_list_hints; class NeighList ** neighborLists; // values set in init_style() -- GitLab From 90a9b7ccd12c1a54daa29f1383cc23a32c8c910b Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 11 Jul 2018 10:29:45 -0700 Subject: [PATCH 0022/1243] Remove pair_kim support for partialVirial - do it w/fdotr --- src/KIM/pair_kim.cpp | 98 ++++++++++++-------------------------------- src/KIM/pair_kim.h | 2 +- 2 files changed, 27 insertions(+), 73 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index ca39b5601e..404e4f9cf0 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -57,7 +57,6 @@ PairKIM::PairKIM(LAMMPS *lmp) : pargs(NULL), kim_model_support_for_energy(KIM::SUPPORT_STATUS::notSupported), kim_model_support_for_forces(KIM::SUPPORT_STATUS::notSupported), - kim_model_support_for_virial(KIM::SUPPORT_STATUS::notSupported), kim_model_support_for_particleEnergy(KIM::SUPPORT_STATUS::notSupported), kim_model_support_for_particleVirial(KIM::SUPPORT_STATUS::notSupported), lmps_local_tot_num_atoms(0), @@ -78,6 +77,9 @@ PairKIM::PairKIM(LAMMPS *lmp) : single_enable = 0; // We do not provide the Single() function restartinfo = 0; // We do not write any restart info one_coeff = 1; // We only allow one coeff * * call + // set to 1, regardless use of fdotr, to avoid ev_set()'s futzing with + // vflag_global + no_virial_fdotr_compute = 1; // BEGIN: initial values that determine the KIM state // (used by kim_free(), etc.) @@ -197,25 +199,21 @@ void PairKIM::compute(int eflag , int vflag) kimerror = pkim->Compute(pargs); if (kimerror) error->all(FLERR,"KIM Compute returned error"); - // assemble force and particleVirial if needed - if (!lmps_using_newton) comm->reverse_comm_pair(this); - - if ((no_virial_fdotr_compute == 1) && (vflag_global)) - { // flip sign and order of virial if KIM is computing it - for (int i = 0; i < 3; ++i) virial[i] = -1.0*virial[i]; - double tmp = virial[3]; - virial[3] = -virial[5]; - virial[4] = -virial[4]; - virial[5] = -tmp; + // compute virial before reverse comm! + if (vflag_global) + { + virial_fdotr_compute(); } - else - { // compute virial via LAMMPS fdotr mechanism - if (vflag_fdotr) virial_fdotr_compute(); + + // if newton is off, perform reverse comm + if (!lmps_using_newton) + { + comm->reverse_comm_pair(this); } - if ((kim_model_support_for_particleVirial != - KIM::SUPPORT_STATUS::notSupported) && - (vflag_atom)) + if ((vflag_atom) && + (kim_model_support_for_particleVirial != + KIM::SUPPORT_STATUS::notSupported)) { // flip sign and order of virial if KIM is computing it double tmp; for (int i = 0; i < nall; ++i) @@ -266,9 +264,8 @@ void PairKIM::settings(int narg, char **arg) ++settings_call_count; init_style_call_count = 0; - if (narg != 2) error->all(FLERR,"Illegal pair_style command"); - // arg[0] is the virial handling option: "LAMMPSvirial" or "KIMvirial" - // arg[1] is the KIM Model name + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + // arg[0] is the KIM Model name lmps_using_molecular = (atom->molecular > 0); @@ -289,35 +286,18 @@ void PairKIM::settings(int narg, char **arg) set_lmps_flags(); // set KIM Model name - int nmlen = strlen(arg[1]); + int nmlen = strlen(arg[0]); if (kim_modelname != 0) { delete [] kim_modelname; kim_modelname = 0; } kim_modelname = new char[nmlen+1]; - strcpy(kim_modelname, arg[1]); + strcpy(kim_modelname, arg[0]); // initialize KIM Model kim_init(); - // set virial handling - if (strcmp(arg[0],"KIMvirial") == 0) - { - if (kim_model_support_for_virial == KIM::SUPPORT_STATUS::notSupported) - no_virial_fdotr_compute = 0; - else - no_virial_fdotr_compute = 1; - } - else if (strcmp(arg[0],"LAMMPSvirial") == 0) - { - no_virial_fdotr_compute = 0; - } - else - { - error->all(FLERR,"Unrecognized virial argument in pair_style command"); - } - return; } @@ -458,13 +438,11 @@ void PairKIM::init_style() if (half_list_hints[i]) { neighbor->requests[irequest]->half = 1; - if (! lmps_using_newton) neighbor->requests[irequest]->newton = 2; neighbor->requests[irequest]->full = 0; } else { neighbor->requests[irequest]->half = 0; - if (! lmps_using_newton) neighbor->requests[irequest]->newton = 0; neighbor->requests[irequest]->full = 1; } if (padding_neighbor_hints[i]) @@ -476,6 +454,9 @@ void PairKIM::init_style() neighbor->requests[irequest]->ghost = 1; } + // always want all owned/ghost pairs + neighbor->requests[irequest]->newton = 2; + // set cutoff neighbor->requests[irequest]->cut = 1; neighbor->requests[irequest]->cutoff = kim_cutoff_values[i] + neighbor->skin; @@ -737,7 +718,6 @@ void PairKIM::kim_init() error->all(FLERR,"KIM ModelCreate failed"); else { if (!requestedUnitsAccepted) { - // @@@ error for now. Fix as needed error->all(FLERR,"KIM Model did not accept the requested unit system"); } @@ -857,27 +837,6 @@ void PairKIM::set_argument_pointers() &(vatom[0][0])); } - // Set KIM pointer appropriately for virial - - if (kim_model_support_for_virial == required) - { - kimerror = kimerror || pargs->SetArgumentPointer(partialVirial, - &(virial[0])); - } - else if ((kim_model_support_for_virial == optional) && - (no_virial_fdotr_compute == 1) && - (vflag_global)) - { - kimerror = kimerror || pargs->SetArgumentPointer(partialVirial, - &(virial[0])); - } - else if (kim_model_support_for_virial == optional) - { - kimerror = kimerror || pargs->SetArgumentPointer( - partialVirial, - reinterpret_cast(NULL)); - } - if (kimerror) { error->all(FLERR,"Unable to set KIM argument pointers"); @@ -966,15 +925,16 @@ void PairKIM::set_kim_model_has_flags() kim_model_support_for_energy = supportStatus; else if (computeArgumentName == partialForces) kim_model_support_for_forces = supportStatus; - else if (computeArgumentName == partialVirial) - kim_model_support_for_virial = supportStatus; else if (computeArgumentName == partialParticleEnergy) kim_model_support_for_particleEnergy = supportStatus; else if (computeArgumentName == partialParticleVirial) kim_model_support_for_particleVirial = supportStatus; else if (supportStatus == required) { - error->all(FLERR,"KIM Model requires unsupported compute argument"); + std::stringstream msg; + msg << "KIM Model requires unsupported compute argument: " + << computeArgumentName.String(); + error->all(FLERR, msg.str().c_str()); } } @@ -986,12 +946,6 @@ void PairKIM::set_kim_model_has_flags() error->warning(FLERR,"KIM Model does not provide `partialForce'; " "Forces will be zero"); - if (kim_model_support_for_virial == notSupported) - { - error->warning(FLERR,"KIM Model does not provide `partialVirial'. " - "pair_kim will always use `LAMMPSvirial' option."); - } - if (kim_model_support_for_particleEnergy == notSupported) error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; " "energy per atom will be zero"); diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 8929fd2b75..afba20651d 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -32,6 +32,7 @@ PairStyle(kim,PairKIM) class KIM_API_model; #include "pair.h" #include "KIM_SimulatorHeaders.hpp" +#include namespace LAMMPS_NS { @@ -90,7 +91,6 @@ namespace LAMMPS_NS { // values set in set_kim_model_has_flags(), called by kim_init() KIM::SupportStatus kim_model_support_for_energy; KIM::SupportStatus kim_model_support_for_forces; - KIM::SupportStatus kim_model_support_for_virial; KIM::SupportStatus kim_model_support_for_particleEnergy; KIM::SupportStatus kim_model_support_for_particleVirial; -- GitLab From fcec1498e31bb98313ae10d4afa8802ad72d82fd Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 11 Jul 2018 10:34:07 -0700 Subject: [PATCH 0023/1243] update input example scripts for pair_kim --- ...in.kim.lj.lmp => in.kim.lj.lmp.newton-off} | 2 +- examples/kim/in.kim.lj.lmp.newton-on | 2 +- .../kim/{in.kim.lj => in.kim.lj.newton-off} | 2 +- examples/kim/in.kim.lj.newton-on | 41 +++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) rename examples/kim/{in.kim.lj.lmp => in.kim.lj.lmp.newton-off} (92%) rename examples/kim/{in.kim.lj => in.kim.lj.newton-off} (94%) create mode 100644 examples/kim/in.kim.lj.newton-on diff --git a/examples/kim/in.kim.lj.lmp b/examples/kim/in.kim.lj.lmp.newton-off similarity index 92% rename from examples/kim/in.kim.lj.lmp rename to examples/kim/in.kim.lj.lmp.newton-off index a10e3e2e90..197755294a 100644 --- a/examples/kim/in.kim.lj.lmp +++ b/examples/kim/in.kim.lj.lmp.newton-off @@ -20,7 +20,7 @@ create_atoms 1 box pair_style lj/cut 8.1500 pair_coeff 1 1 0.0104 3.4000 -#pair_style kim KIMvirial LennardJones_Ar +#pair_style kim LennardJones_Ar #pair_coeff * * Ar mass 1 39.95 diff --git a/examples/kim/in.kim.lj.lmp.newton-on b/examples/kim/in.kim.lj.lmp.newton-on index d17bc14984..f9f79e2bb2 100644 --- a/examples/kim/in.kim.lj.lmp.newton-on +++ b/examples/kim/in.kim.lj.lmp.newton-on @@ -20,7 +20,7 @@ create_atoms 1 box pair_style lj/cut 8.1500 pair_coeff 1 1 0.0104 3.4000 -#pair_style kim KIMvirial LennardJones_Ar +#pair_style kim LennardJones_Ar #pair_coeff * * Ar mass 1 39.95 diff --git a/examples/kim/in.kim.lj b/examples/kim/in.kim.lj.newton-off similarity index 94% rename from examples/kim/in.kim.lj rename to examples/kim/in.kim.lj.newton-off index a17ec982da..82cf5ba602 100644 --- a/examples/kim/in.kim.lj +++ b/examples/kim/in.kim.lj.newton-off @@ -26,7 +26,7 @@ create_atoms 1 box #pair_style lj/cut 8.1500 #pair_coeff 1 1 0.0104 3.4000 -pair_style kim KIMvirial LennardJones_Ar +pair_style kim LennardJones_Ar pair_coeff * * Ar mass 1 39.95 diff --git a/examples/kim/in.kim.lj.newton-on b/examples/kim/in.kim.lj.newton-on new file mode 100644 index 0000000000..3a95f1dbb0 --- /dev/null +++ b/examples/kim/in.kim.lj.newton-on @@ -0,0 +1,41 @@ +# 3d Lennard-Jones melt +# +# This example requires that the example models provided with +# the kim-api package are installed. see the ./lib/kim/README or +# ./lib/kim/Install.py files for details on how to install these +# example models. +# + +variable x index 1 +variable y index 1 +variable z index 1 + +variable xx equal 20*$x +variable yy equal 20*$y +variable zz equal 20*$z + +units metal +atom_style atomic +newton on + +lattice fcc 4.4300 +region box block 0 ${xx} 0 ${yy} 0 ${zz} +create_box 1 box +create_atoms 1 box + +#pair_style lj/cut 8.1500 +#pair_coeff 1 1 0.0104 3.4000 + +pair_style kim LennardJones_Ar +pair_coeff * * Ar + +mass 1 39.95 +velocity all create 200.0 232345 loop geom + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 1 all nve +#fix 1 all npt temp 1.0 1.0 1.0 iso 1.0 1.0 3.0 + +run 100 -- GitLab From af42251142914046b1b2d2f5bb4983704d3ee648 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 11 Jul 2018 13:42:26 -0700 Subject: [PATCH 0024/1243] Update doc/src/pair_kim.txt --- doc/src/pair_kim.txt | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index 4599779ca8..a53de79abf 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -10,14 +10,13 @@ pair_style kim command :h3 [Syntax:] -pair_style kim virialmode model :pre +pair_style kim model :pre -virialmode = KIMvirial or LAMMPSvirial model = name of KIM model (potential) [Examples:] -pair_style kim KIMvirial ex_model_Ar_P_LJ +pair_style kim ex_model_Ar_P_LJ pair_coeff * * Ar Ar :pre [Description:] @@ -55,11 +54,6 @@ on how to build LAMMSPS with the kim-api and how to install the example models. :line -The argument {virialmode} determines how the global virial is -calculated. If {KIMvirial} is specified, the KIM model performs the -global virial calculation (if it knows how). If {LAMMPSvirial} is -specified, LAMMPS computes the global virial using its fdotr mechanism. - The argument {model} is the name of the KIM model for a specific potential as KIM defines it. In principle, LAMMPS can invoke any KIM model. You should get an error or warning message from either LAMMPS @@ -121,7 +115,7 @@ LAMMPS was built with that package. See the "Making LAMMPS"_Section_start.html#start_3 section for more info. This current version of pair_style kim is compatible with the -kim-api package version 2.0.0-beta.0 and higher. +kim-api package version 2.0.0-beta.1 and higher. [Related commands:] -- GitLab From 81e33f5f7893bd0ab799fb92a8f12a81f38bc8aa Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 11 Jul 2018 14:25:35 -0700 Subject: [PATCH 0025/1243] Minor fixes & Error message updates in pair_kim.h --- src/KIM/pair_kim.cpp | 13 +++++--- src/KIM/pair_kim.h | 73 ++++++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 404e4f9cf0..88f576bad2 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -193,7 +193,7 @@ void PairKIM::compute(int eflag , int vflag) set_argument_pointers(); // set number of particles - lmps_local_tot_num_atoms = (int) (atom->nghost + atom->nlocal); + lmps_local_tot_num_atoms = (int) nall; // compute via KIM model kimerror = pkim->Compute(pargs); @@ -391,7 +391,12 @@ void PairKIM::coeff(int narg, char **arg) if (supported) kim_particle_codes[i] = code; else - error->all(FLERR,"create_kim_particle_codes: symbol not found "); + { + std::stringstream msg; + msg << "create_kim_particle_codes: symbol not found: " + << lmps_unique_elements[i]; + error->all(FLERR, msg.str().c_str()); + } } return; @@ -421,7 +426,7 @@ void PairKIM::init_style() lmps_stripped_neigh_ptr = new int*[kim_number_of_neighbor_lists]; for (int i = 0; i < kim_number_of_neighbor_lists; ++i) { - lmps_stripped_neigh_ptr[0] + lmps_stripped_neigh_ptr[i] = &(lmps_stripped_neigh_list[(i-1)*(neighbor->oneatom)]); } @@ -855,7 +860,7 @@ void PairKIM::set_lmps_flags() // determine if running with pair hybrid if (force->pair_match("hybrid",0)) { - error->all(FLERR,"pair_kim does not support hybrid."); + error->all(FLERR,"pair_kim does not support hybrid"); } // determine unit system and set lmps_units flag diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index afba20651d..bdebfbcad0 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -137,81 +137,88 @@ namespace LAMMPS_NS { /* ERROR/WARNING messages: -E: Illegal ... command +E: Unable to set KIM particle species codes and/or contributing -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. +A low-level kim-api error has occurred. -E: Unrecognized virial argument in pair_style command +E: KIM Compute returned error -Only two options are supported: LAMMPSvirial and KIMvirial +The KIM model was unable, for some reason, to complete the computation. + +E: Illegal pair_style command + +Self-explanatory. E: Incorrect args for pair coefficients -Self-explanatory. Check the input script or data file. +Self-explanatory. -E: Invalid args for non-hybrid pair coefficients +E: create_kim_particle_codes: symbol not found: XX -"NULL" is only supported in pair_coeff calls when using pair hybrid +The KIM model specified does not support the atomic species symbol E: PairKIM only works with 3D problems -This is a current limitation. +Self-explanatory. 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. +Self-explanatory. -E: KIM neighbor iterator exceeded range +E: Unable to destroy Compute Arguments Object -This should not happen. It likely indicates a bug -in the KIM implementation of the interatomic potential -where it is requesting neighbors incorrectly. +A low-level kim-api error has occurred. -E: LAMMPS unit_style lj not supported by KIM models +E: KIM ModelCreate failed -Self-explanatory. Check the input script or data file. +The kim-api was not able to create a model object for the specified model. -E: Unknown unit_style +E: KIM Model did not accept the requested unit system -Self-explanatory. Check the input script or data file. +The KIM Model does not support the specified LAMMPS unit system -W: KIM Model does not provide `energy'; Potential energy will be zero +E: KIM ComputeArgumentsCreate failed -Self-explanatory. +A low-level kim-api error has occurred. -W: KIM Model does not provide `forces'; Forces will be zero +E: Unable to register KIM pointers -Self-explanatory. +A low-level kim-api error has occurred. -W: KIM Model does not provide `particleEnergy'; energy per atom will be zero +E: Unable to set KIM argument pointers -Self-explanatory. +A low-level kim-api error has occurred. -W: KIM Model does not provide `particleVirial'; virial per atom will be zero +E: pair_kim does not support hybrid +Self-explanatory. +E: LAMMPS unit_style lj not suppored by KIM models -E: Test_descriptor_string already allocated +Self-explanatory. -This is an internal error. Contact the developers. +E: KIM Model requires unsupported compute argument: XXX -U: KIM Model does not provide 'energy'; Potential energy will be zero +A low-level kim-api error has occurred. + +W: KIM Model does not provide `partialEnergy'; Potential energy will be zero Self-explanatory. -U: KIM Model does not provide 'forces'; Forces will be zero +W: KIM Model does not provide `partialForce'; Forces will be zero Self-explanatory. -U: KIM Model does not provide 'particleEnergy'; energy per atom will be zero +W: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero Self-explanatory. -U: KIM Model does not provide 'particleVirial'; virial per atom will be zero +W: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero Self-explanatory. +E: KIM Model requires unsupported compute callback + +A low-level kim-api error has occurred. + */ -- GitLab From 3e734186016e9ecc8f1ec1a2235fe0ffda904bd1 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 11 Jul 2018 14:57:02 -0700 Subject: [PATCH 0026/1243] Updated example/kim log files --- ....11Jul2018.kim.lj.lmp.newton-off.ubuntu.1} | 22 +++--- ....11Jul2018.kim.lj.lmp.newton-off.ubuntu.4} | 22 +++--- ...g.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1} | 22 +++--- ...g.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4} | 22 +++--- ... log.11Jul2018.kim.lj.newton-off.ubuntu.1} | 33 ++++----- ... log.11Jul2018.kim.lj.newton-off.ubuntu.4} | 46 ++++++------ .../log.11Jul2018.kim.lj.newton-on.ubuntu.1 | 68 +++++++++++++++++ .../log.11Jul2018.kim.lj.newton-on.ubuntu.4 | 74 +++++++++++++++++++ 8 files changed, 223 insertions(+), 86 deletions(-) rename examples/kim/{log.04Jul2018.kim.lj.lmp.ubuntu.1 => log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1} (74%) rename examples/kim/{log.04Jul2018.kim.lj.lmp.ubuntu.4 => log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4} (74%) rename examples/kim/{log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 => log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1} (74%) rename examples/kim/{log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 => log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4} (74%) rename examples/kim/{log.04Jul2018.kim.lj.ubuntu.1 => log.11Jul2018.kim.lj.newton-off.ubuntu.1} (68%) rename examples/kim/{log.04Jul2018.kim.lj.ubuntu.4 => log.11Jul2018.kim.lj.newton-off.ubuntu.4} (60%) create mode 100644 examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 create mode 100644 examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 diff --git a/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.1 b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 similarity index 74% rename from examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.1 rename to examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 index 217568072c..bf5864cb08 100644 --- a/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.1 +++ b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[19074,1],0]: A high-performance Open MPI point-to-point messaging module +[[6124,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,7 +16,7 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00251478 secs + Time spent = 0.00263722 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +37,20 @@ Per MPI rank memory allocation (min/avg/max) = 20.37 | 20.37 | 20.37 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.6218 on 1 procs for 100 steps with 32000 atoms +Loop time of 2.59913 on 1 procs for 100 steps with 32000 atoms -Performance: 3.295 ns/day, 7.283 hours/ns, 38.142 timesteps/s -99.9% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 3.324 ns/day, 7.220 hours/ns, 38.474 timesteps/s +99.4% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.2623 | 2.2623 | 2.2623 | 0.0 | 86.29 -Neigh | 0.31859 | 0.31859 | 0.31859 | 0.0 | 12.15 -Comm | 0.005914 | 0.005914 | 0.005914 | 0.0 | 0.23 -Output | 0.00033105 | 0.00033105 | 0.00033105 | 0.0 | 0.01 -Modify | 0.023461 | 0.023461 | 0.023461 | 0.0 | 0.89 -Other | | 0.01123 | | | 0.43 +Pair | 2.2753 | 2.2753 | 2.2753 | 0.0 | 87.54 +Neigh | 0.28456 | 0.28456 | 0.28456 | 0.0 | 10.95 +Comm | 0.0055908 | 0.0055908 | 0.0055908 | 0.0 | 0.22 +Output | 0.00034594 | 0.00034594 | 0.00034594 | 0.0 | 0.01 +Modify | 0.023011 | 0.023011 | 0.023011 | 0.0 | 0.89 +Other | | 0.01037 | | | 0.40 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 similarity index 74% rename from examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 rename to examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 index 806c674efb..7f51d447fd 100644 --- a/examples/kim/log.04Jul2018.kim.lj.lmp.ubuntu.4 +++ b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[19098,1],0]: A high-performance Open MPI point-to-point messaging module +[[6116,1],1]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,7 +16,7 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00123697 secs + Time spent = 0.00125703 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +37,20 @@ Per MPI rank memory allocation (min/avg/max) = 8.013 | 8.013 | 8.013 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.88232 on 4 procs for 100 steps with 32000 atoms +Loop time of 2.99901 on 4 procs for 100 steps with 32000 atoms -Performance: 2.998 ns/day, 8.006 hours/ns, 34.694 timesteps/s -24.6% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 2.881 ns/day, 8.331 hours/ns, 33.344 timesteps/s +24.4% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 1.3577 | 1.415 | 1.467 | 3.7 | 49.09 -Neigh | 0.25761 | 0.28189 | 0.29894 | 3.2 | 9.78 -Comm | 0.58287 | 0.73218 | 0.85561 | 11.5 | 25.40 -Output | 0.00082721 | 0.0029034 | 0.0051877 | 3.1 | 0.10 -Modify | 0.0058569 | 0.015767 | 0.033242 | 8.6 | 0.55 -Other | | 0.4346 | | | 15.08 +Pair | 1.3704 | 1.4012 | 1.439 | 2.3 | 46.72 +Neigh | 0.252 | 0.27028 | 0.28236 | 2.2 | 9.01 +Comm | 0.66355 | 0.73942 | 0.82223 | 6.5 | 24.66 +Output | 0.0037821 | 0.0090774 | 0.016142 | 5.1 | 0.30 +Modify | 0.0058855 | 0.019317 | 0.044855 | 11.4 | 0.64 +Other | | 0.5597 | | | 18.66 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 diff --git a/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 similarity index 74% rename from examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 rename to examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 index 70eae36a48..7be22a7f60 100644 --- a/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.1 +++ b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[19053,1],0]: A high-performance Open MPI point-to-point messaging module +[[5635,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,7 +16,7 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00270113 secs + Time spent = 0.00226572 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +37,20 @@ Per MPI rank memory allocation (min/avg/max) = 19.23 | 19.23 | 19.23 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.18554 on 1 procs for 100 steps with 32000 atoms +Loop time of 2.26274 on 1 procs for 100 steps with 32000 atoms -Performance: 3.953 ns/day, 6.071 hours/ns, 45.755 timesteps/s -99.6% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 3.818 ns/day, 6.285 hours/ns, 44.194 timesteps/s +99.0% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.0006 | 2.0006 | 2.0006 | 0.0 | 91.54 -Neigh | 0.13933 | 0.13933 | 0.13933 | 0.0 | 6.38 -Comm | 0.011122 | 0.011122 | 0.011122 | 0.0 | 0.51 -Output | 0.00020978 | 0.00020978 | 0.00020978 | 0.0 | 0.01 -Modify | 0.022358 | 0.022358 | 0.022358 | 0.0 | 1.02 -Other | | 0.01188 | | | 0.54 +Pair | 2.0589 | 2.0589 | 2.0589 | 0.0 | 90.99 +Neigh | 0.15362 | 0.15362 | 0.15362 | 0.0 | 6.79 +Comm | 0.012277 | 0.012277 | 0.012277 | 0.0 | 0.54 +Output | 0.0003387 | 0.0003387 | 0.0003387 | 0.0 | 0.01 +Modify | 0.02416 | 0.02416 | 0.02416 | 0.0 | 1.07 +Other | | 0.01346 | | | 0.59 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 similarity index 74% rename from examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 rename to examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 index e7157c11b8..d910afbbc2 100644 --- a/examples/kim/log.04Jul2018.kim.lj.lmp.newton-on.ubuntu.4 +++ b/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[19045,1],0]: A high-performance Open MPI point-to-point messaging module +[[5659,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,7 +16,7 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00117056 secs + Time spent = 0.00213171 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +37,20 @@ Per MPI rank memory allocation (min/avg/max) = 7.632 | 7.632 | 7.632 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.34104 on 4 procs for 100 steps with 32000 atoms +Loop time of 2.44628 on 4 procs for 100 steps with 32000 atoms -Performance: 3.691 ns/day, 6.503 hours/ns, 42.716 timesteps/s -24.0% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 3.532 ns/day, 6.795 hours/ns, 40.878 timesteps/s +24.2% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.91499 | 0.96396 | 1.0567 | 5.6 | 41.18 -Neigh | 0.092245 | 0.11781 | 0.14572 | 6.0 | 5.03 -Comm | 1.1264 | 1.2287 | 1.2906 | 5.6 | 52.49 -Output | 0.00045199 | 0.00051154 | 0.00060273 | 0.0 | 0.02 -Modify | 0.0058738 | 0.0059629 | 0.0061675 | 0.2 | 0.25 -Other | | 0.02406 | | | 1.03 +Pair | 0.98717 | 1.0434 | 1.1582 | 6.6 | 42.65 +Neigh | 0.10195 | 0.12588 | 0.15258 | 5.2 | 5.15 +Comm | 1.1525 | 1.2449 | 1.3061 | 5.1 | 50.89 +Output | 0.0005828 | 0.00075188 | 0.00087256 | 0.0 | 0.03 +Modify | 0.0057955 | 0.0059132 | 0.006044 | 0.1 | 0.24 +Other | | 0.02542 | | | 1.04 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 diff --git a/examples/kim/log.04Jul2018.kim.lj.ubuntu.1 b/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 similarity index 68% rename from examples/kim/log.04Jul2018.kim.lj.ubuntu.1 rename to examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 index 3832bd060a..c8c1919de5 100644 --- a/examples/kim/log.04Jul2018.kim.lj.ubuntu.1 +++ b/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[19111,1],0]: A high-performance Open MPI point-to-point messaging module +[[5713,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,10 +16,9 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00257231 secs -WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) + Time spent = 0.00256546 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -38,22 +37,22 @@ Setting up Verlet run ... Time step : 0.001 Per MPI rank memory allocation (min/avg/max) = 21.26 | 21.26 | 21.26 Mbytes Step Temp E_pair E_mol TotEng Press - 0 200 6290.8194 0 7118.0584 1270.4248 - 100 95.179725 6718.814 0 7112.496 604.59343 -Loop time of 3.22934 on 1 procs for 100 steps with 32000 atoms + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.69522 on 1 procs for 100 steps with 32000 atoms -Performance: 2.675 ns/day, 8.970 hours/ns, 30.966 timesteps/s -99.9% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 3.206 ns/day, 7.487 hours/ns, 37.103 timesteps/s +99.8% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.821 | 2.821 | 2.821 | 0.0 | 87.36 -Neigh | 0.35198 | 0.35198 | 0.35198 | 0.0 | 10.90 -Comm | 0.0081757 | 0.0081757 | 0.0081757 | 0.0 | 0.25 -Output | 0.00030922 | 0.00030922 | 0.00030922 | 0.0 | 0.01 -Modify | 0.032856 | 0.032856 | 0.032856 | 0.0 | 1.02 -Other | | 0.01501 | | | 0.46 +Pair | 2.3655 | 2.3655 | 2.3655 | 0.0 | 87.77 +Neigh | 0.28659 | 0.28659 | 0.28659 | 0.0 | 10.63 +Comm | 0.0061924 | 0.0061924 | 0.0061924 | 0.0 | 0.23 +Output | 0.00034901 | 0.00034901 | 0.00034901 | 0.0 | 0.01 +Modify | 0.025061 | 0.025061 | 0.025061 | 0.0 | 0.93 +Other | | 0.01157 | | | 0.43 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -66,4 +65,4 @@ Total # of neighbors = 2370499 Ave neighs/atom = 74.0781 Neighbor list builds = 3 Dangerous builds = 0 -Total wall time: 0:00:03 +Total wall time: 0:00:02 diff --git a/examples/kim/log.04Jul2018.kim.lj.ubuntu.4 b/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 similarity index 60% rename from examples/kim/log.04Jul2018.kim.lj.ubuntu.4 rename to examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 index 70b2f82812..c8d5faeb20 100644 --- a/examples/kim/log.04Jul2018.kim.lj.ubuntu.4 +++ b/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 @@ -1,5 +1,5 @@ -------------------------------------------------------------------------- -[[19135,1],1]: A high-performance Open MPI point-to-point messaging module +[[5673,1],0]: A high-performance Open MPI point-to-point messaging module was unable to find any relevant network interfaces: Module: OpenFabrics (openib) @@ -16,19 +16,15 @@ Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00154417 secs -WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) -WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) -WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) -WARNING: KIM Model does not provide `partialVirial'. pair_kim will always use `LAMMPSvirial' option. (../pair_kim.cpp:987) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:992) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:996) + Time spent = 0.00215514 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -47,22 +43,22 @@ Setting up Verlet run ... Time step : 0.001 Per MPI rank memory allocation (min/avg/max) = 8.528 | 8.528 | 8.528 Mbytes Step Temp E_pair E_mol TotEng Press - 0 200 6290.8194 0 7118.0584 1270.4248 - 100 95.179725 6718.814 0 7112.496 604.59343 -Loop time of 3.17877 on 4 procs for 100 steps with 32000 atoms + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 3.06157 on 4 procs for 100 steps with 32000 atoms -Performance: 2.718 ns/day, 8.830 hours/ns, 31.459 timesteps/s -24.3% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 2.822 ns/day, 8.504 hours/ns, 32.663 timesteps/s +24.4% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.0514 | 2.1009 | 2.1859 | 3.6 | 66.09 -Neigh | 0.29304 | 0.31706 | 0.33568 | 2.7 | 9.97 -Comm | 0.61926 | 0.72709 | 0.77083 | 7.3 | 22.87 -Output | 0.00035457 | 0.00043741 | 0.000547 | 0.0 | 0.01 -Modify | 0.0066107 | 0.0067653 | 0.0069097 | 0.1 | 0.21 -Other | | 0.02653 | | | 0.83 +Pair | 1.9964 | 2.0369 | 2.084 | 2.5 | 66.53 +Neigh | 0.25048 | 0.27467 | 0.29605 | 3.1 | 8.97 +Comm | 0.66611 | 0.71603 | 0.74496 | 3.6 | 23.39 +Output | 0.00048383 | 0.00070085 | 0.00098836 | 0.0 | 0.02 +Modify | 0.0064885 | 0.0065907 | 0.006806 | 0.2 | 0.22 +Other | | 0.02664 | | | 0.87 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 diff --git a/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 b/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 new file mode 100644 index 0000000000..21af1a6299 --- /dev/null +++ b/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 @@ -0,0 +1,68 @@ +-------------------------------------------------------------------------- +[[5690,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 1 by 1 MPI processor grid +Created 32000 atoms + Time spent = 0.00258302 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: half, newton off, cut 8.45 + pair build: half/bin/newtoff + stencil: half/bin/3d/newtoff + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 20.87 | 20.87 | 20.87 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.7052 on 1 procs for 100 steps with 32000 atoms + +Performance: 3.194 ns/day, 7.514 hours/ns, 36.966 timesteps/s +99.6% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.3715 | 2.3715 | 2.3715 | 0.0 | 87.67 +Neigh | 0.28386 | 0.28386 | 0.28386 | 0.0 | 10.49 +Comm | 0.012808 | 0.012808 | 0.012808 | 0.0 | 0.47 +Output | 0.00033716 | 0.00033716 | 0.00033716 | 0.0 | 0.01 +Modify | 0.02349 | 0.02349 | 0.02349 | 0.0 | 0.87 +Other | | 0.01317 | | | 0.49 + +Nlocal: 32000 ave 32000 max 32000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19911 ave 19911 max 19911 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 2.3705e+06 ave 2.3705e+06 max 2.3705e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 2370499 +Ave neighs/atom = 74.0781 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:02 diff --git a/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 b/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 new file mode 100644 index 0000000000..1214436d4d --- /dev/null +++ b/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 @@ -0,0 +1,74 @@ +-------------------------------------------------------------------------- +[[5682,1],0]: A high-performance Open MPI point-to-point messaging module +was unable to find any relevant network interfaces: + +Module: OpenFabrics (openib) + Host: ubuntu-artful + +Another transport will be used instead, although this may result in +lower performance. + +NOTE: You can disable this warning by setting the MCA parameter +btl_base_warn_component_unused to 0. +-------------------------------------------------------------------------- +LAMMPS (22 Jun 2018) +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.00322684 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: half, newton off, cut 8.45 + pair build: half/bin/newtoff + stencil: half/bin/3d/newtoff + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 8.263 | 8.263 | 8.263 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 3.1366 on 4 procs for 100 steps with 32000 atoms + +Performance: 2.755 ns/day, 8.713 hours/ns, 31.882 timesteps/s +23.7% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.3641 | 1.4213 | 1.4783 | 3.5 | 45.31 +Neigh | 0.25408 | 0.27714 | 0.29697 | 3.2 | 8.84 +Comm | 1.3588 | 1.4045 | 1.4806 | 4.0 | 44.78 +Output | 0.00055232 | 0.00072915 | 0.00087484 | 0.0 | 0.02 +Modify | 0.0061178 | 0.0062019 | 0.0062811 | 0.1 | 0.20 +Other | | 0.02673 | | | 0.85 + +Nlocal: 8000 ave 8018 max 7967 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Nghost: 9131 ave 9164 max 9113 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Neighs: 630904 ave 632094 max 628209 min +Histogram: 1 0 0 0 0 0 0 1 0 2 + +Total # of neighbors = 2523614 +Ave neighs/atom = 78.8629 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 -- GitLab From 67e6afaab2b75f5a39c34edb7221d4a4672c69e4 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 11 Jul 2018 15:04:34 -0700 Subject: [PATCH 0027/1243] Update to KIM kim-api-v2.0.0-beta.1 --- cmake/CMakeLists.txt | 4 ++-- lib/kim/Install.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4672b4a3db..be5bc74f1c 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -407,8 +407,8 @@ if(PKG_KIM) if(DOWNLOAD_KIM) include(ExternalProject) ExternalProject_Add(kim_build - URL https://github.com/openkim/kim-api/archive/v2.0.0-beta.0.tar.gz - URL_MD5 2c099fe2603fda9a6904fc50d626f71b + URL https://github.com/openkim/kim-api/archive/v2.0.0-beta.1.tar.gz + URL_MD5 633e331cc7942c1f0462da71f41f94be BUILD_IN_SOURCE 1 CONFIGURE_COMMAND /configure --prefix= ) diff --git a/lib/kim/Install.py b/lib/kim/Install.py index f9eb1c5eed..da0dcd2789 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -21,7 +21,7 @@ Syntax from lib dir: python Install.py -b -v version -a kim-name specify one or more options, order does not matter -v = version of KIM API library to use - default = kim-api-v2.0.0-beta.0 (current as of June 2018) + default = kim-api-v2.0.0-beta.1 (current as of July 2018) -b = download and build base KIM API library with example Models this will delete any previous installation in the current folder -n = do NOT download and build base KIM API library. @@ -109,7 +109,7 @@ nargs = len(args) if nargs == 0: error() thisdir = os.environ['PWD'] -version = "kim-api-v2.0.0-beta.0" +version = "kim-api-v2.0.0-beta.1" buildflag = False everythingflag = False -- GitLab From e37e9cfa2f0b1dff19e5114cb2a2f2b992be83a0 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 16 Jul 2018 19:46:00 -0500 Subject: [PATCH 0028/1243] Add virtual set_contributing() to pair_kim --- src/KIM/pair_kim.cpp | 15 +++++++++++++-- src/KIM/pair_kim.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 88f576bad2..6d30cff01d 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -142,6 +142,16 @@ PairKIM::~PairKIM() return; } +/* ---------------------------------------------------------------------- */ +void PairKIM::set_contributing() +{ + int const nall = atom->nlocal + atom->nghost; + for (int i = 0; i < nall; ++i) + { + kim_particleContributing[i] = ( (i < atom->nlocal) ? 1 : 0 ); + } +} + /* ---------------------------------------------------------------------- */ void PairKIM::compute(int eflag , int vflag) @@ -185,10 +195,11 @@ void PairKIM::compute(int eflag , int vflag) for (int i = 0; i < nall; i++) { ielement = lmps_map_species_to_unique[species[i]]; kim_particleSpecies[i] = kim_particle_codes[ielement]; - - kim_particleContributing[i] = ( (inlocal) ? 1 : 0 ); } + // Set kim contributing flags + set_contributing(); + // pass current atom pointers to KIM set_argument_pointers(); diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index bdebfbcad0..59f477b1e4 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -117,6 +117,7 @@ namespace LAMMPS_NS { int** lmps_stripped_neigh_ptr; // pointer into lists // KIM specific helper functions + virtual void set_contributing(); void kim_init(); void kim_free(); void set_argument_pointers(); -- GitLab From 62c8ba78249790e629cd78b0ad3553432ed4887b Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 16 Jul 2018 21:21:28 -0500 Subject: [PATCH 0029/1243] pair_kim : private to protected and add virtual to all routines --- src/KIM/pair_kim.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 59f477b1e4..79b8c5d792 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -53,7 +53,7 @@ namespace LAMMPS_NS { virtual void unpack_reverse_comm(int, int*, double*); virtual double memory_usage(); - private: + protected: // (nearly) all bool flags are not initialized in constructor, but set // explicitly in the indicated function. All other data members are // initialized in constructor @@ -66,7 +66,7 @@ namespace LAMMPS_NS { // values set in coeff() // values set in allocate(), called by coeff() - void allocate(); + virtual void allocate(); int* lmps_map_species_to_unique; // values set in coeff(), after calling allocate() @@ -118,13 +118,13 @@ namespace LAMMPS_NS { // KIM specific helper functions virtual void set_contributing(); - void kim_init(); - void kim_free(); - void set_argument_pointers(); - void set_lmps_flags(); - void set_kim_model_has_flags(); + virtual void kim_init(); + virtual void kim_free(); + virtual void set_argument_pointers(); + virtual void set_lmps_flags(); + virtual void set_kim_model_has_flags(); // static methods used as callbacks from KIM - static int get_neigh( + static int get_neigh( void const * const dataObject, int const numberOfCutoffs, double const * const cutoffs, int const neighborListIndex, int const particleNumber, -- GitLab From c0a7cabcba95f9a16b95ac6e8bf659b9db34eab1 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 18 Jul 2018 22:15:23 -0500 Subject: [PATCH 0030/1243] Added GPLv2 exception to link to kim-api in pair_kim.* --- src/KIM/pair_kim.cpp | 34 ++++++++++++++++++++++++++++++++++ src/KIM/pair_kim.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 6d30cff01d..39f3c4a240 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -15,6 +15,40 @@ Contributing authors: Ryan S. Elliott (UMinn) ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + 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 the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, see . + + Linking LAMMPS statically or dynamically with other modules is making a + combined work based on LAMMPS. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + In addition, as a special exception, the copyright holders of LAMMPS give + you permission to combine LAMMPS with free software programs or libraries + that are released under the GNU LGPL and with code included in the standard + release of the "kim-api" under the CDDL (or modified versions of such code, + with unchanged license). You may copy and distribute such a system following + the terms of the GNU GPL for LAMMPS and the licenses of the other code + concerned, provided that you include the source code of that other code + when and as the GNU GPL requires distribution of source code. + + Note that people who make modified versions of LAMMPS are not obligated to + grant this special exception for their modified versions; it is their choice + whether to do so. The GNU General Public License gives permission to release + a modified version without this exception; this exception also makes it + possible to release a modified version which carries forward this exception. +------------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package ------------------------------------------------------------------------- */ diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 79b8c5d792..b6d3489c71 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -15,6 +15,40 @@ Contributing authors: Ryan S. Elliott (UMinn) ------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + 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 the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, see . + + Linking LAMMPS statically or dynamically with other modules is making a + combined work based on LAMMPS. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + In addition, as a special exception, the copyright holders of LAMMPS give + you permission to combine LAMMPS with free software programs or libraries + that are released under the GNU LGPL and with code included in the standard + release of the "kim-api" under the CDDL (or modified versions of such code, + with unchanged license). You may copy and distribute such a system following + the terms of the GNU GPL for LAMMPS and the licenses of the other code + concerned, provided that you include the source code of that other code + when and as the GNU GPL requires distribution of source code. + + Note that people who make modified versions of LAMMPS are not obligated to + grant this special exception for their modified versions; it is their choice + whether to do so. The GNU General Public License gives permission to release + a modified version without this exception; this exception also makes it + possible to release a modified version which carries forward this exception. +------------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package ------------------------------------------------------------------------- */ -- GitLab From dde0974a1aac9c48ce164c5f57813c381f4119a2 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 13 Aug 2018 22:34:42 -0500 Subject: [PATCH 0031/1243] Update for corrected neighbor list hint --- src/KIM/pair_kim.cpp | 28 ++++++++++------------------ src/KIM/pair_kim.h | 5 ++--- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 39f3c4a240..a298187c12 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -97,8 +97,7 @@ PairKIM::PairKIM(LAMMPS *lmp) : kim_global_influence_distance(0.0), kim_number_of_neighbor_lists(0), kim_cutoff_values(NULL), - padding_neighbor_hints(NULL), - half_list_hints(NULL), + modelWillNotRequestNeighborsOfNoncontributingParticles(NULL), neighborLists(NULL), kim_particle_codes(NULL), lmps_maxalloc(0), @@ -480,22 +479,15 @@ void PairKIM::init_style() // make sure comm_reverse expects (at most) 9 values when newton is off if (!lmps_using_newton) comm_reverse_off = 9; - // request full neighbor lists (unless hints allow for better alternatives) + // request full neighbor for (int i = 0; i < kim_number_of_neighbor_lists; ++i) { int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->id = i; - if (half_list_hints[i]) - { - neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full = 0; - } - else - { - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 1; - } - if (padding_neighbor_hints[i]) + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + + if (modelWillNotRequestNeighborsOfNoncontributingParticles[i]) { neighbor->requests[irequest]->ghost = 0; } @@ -787,10 +779,10 @@ void PairKIM::kim_init() set_kim_model_has_flags(); pkim->GetInfluenceDistance(&kim_global_influence_distance); - pkim->GetNeighborListPointers(&kim_number_of_neighbor_lists, - &kim_cutoff_values, - &padding_neighbor_hints, - &half_list_hints); + pkim->GetNeighborListPointers( + &kim_number_of_neighbor_lists, + &kim_cutoff_values, + &modelWillNotRequestNeighborsOfNoncontributingParticles); if (neighborLists) { delete [] neighborLists; diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index b6d3489c71..e2be0855db 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -134,9 +134,8 @@ namespace LAMMPS_NS { double kim_global_influence_distance; // KIM Model cutoff value int kim_number_of_neighbor_lists; double const * kim_cutoff_values; - int const * padding_neighbor_hints; - int const * half_list_hints; - class NeighList ** neighborLists; + int const * modelWillNotRequestNeighborsOfNoncontributingParticles; + class NeighList ** neighborLists; // values set in init_style() bool kim_particle_codes_ok; -- GitLab From 062c1a04fcc129f2ba61edaac2f7b35e07e11e81 Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 14 Aug 2018 14:42:01 -0600 Subject: [PATCH 0032/1243] Commit JT 081418 - initial commit pppm_spin branch - copied short_range spin files (src/SPIN) - copied/renamed Stan's file (from pppm_dipole branch) --- src/DIPOLE/pair_lj_cut_dipole_long.cpp | 2 +- src/KSPACE/pppm.h | 8 +- src/KSPACE/pppm_spin.cpp | 2559 ++++++++++++++++++++++++ src/KSPACE/pppm_spin.h | 213 ++ src/SPIN/pair_spin_long.cpp | 550 +++++ src/SPIN/pair_spin_long.h | 97 + src/kspace.cpp | 4 +- src/kspace.h | 2 +- 8 files changed, 3427 insertions(+), 8 deletions(-) create mode 100644 src/KSPACE/pppm_spin.cpp create mode 100644 src/KSPACE/pppm_spin.h create mode 100644 src/SPIN/pair_spin_long.cpp create mode 100644 src/SPIN/pair_spin_long.h diff --git a/src/DIPOLE/pair_lj_cut_dipole_long.cpp b/src/DIPOLE/pair_lj_cut_dipole_long.cpp index 817a120e3d..a0e7c1c4ec 100644 --- a/src/DIPOLE/pair_lj_cut_dipole_long.cpp +++ b/src/DIPOLE/pair_lj_cut_dipole_long.cpp @@ -44,7 +44,7 @@ using namespace MathConst; PairLJCutDipoleLong::PairLJCutDipoleLong(LAMMPS *lmp) : Pair(lmp) { single_enable = 0; - ewaldflag = dipoleflag = 1; + ewaldflag = pppmflag = dipoleflag = 1; respa_enable = 0; } diff --git a/src/KSPACE/pppm.h b/src/KSPACE/pppm.h index 9cb6bebb25..c6d463b69c 100644 --- a/src/KSPACE/pppm.h +++ b/src/KSPACE/pppm.h @@ -41,7 +41,7 @@ class PPPM : public KSpace { virtual ~PPPM(); virtual void init(); virtual void setup(); - void setup_grid(); + virtual void setup_grid(); virtual void compute(int, int); virtual int timing_1d(int, double &); virtual int timing_3d(int, double &); @@ -105,10 +105,10 @@ class PPPM : public KSpace { double qdist; // distance from O site to negative charge double alpha; // geometric factor - void set_grid_global(); + virtual void set_grid_global(); void set_grid_local(); void adjust_gewald(); - double newton_raphson_f(); + virtual double newton_raphson_f(); double derivf(); double final_accuracy(); @@ -145,7 +145,7 @@ class PPPM : public KSpace { void compute_drho1d(const FFT_SCALAR &, const FFT_SCALAR &, const FFT_SCALAR &); void compute_rho_coeff(); - void slabcorr(); + virtual void slabcorr(); // grid communication diff --git a/src/KSPACE/pppm_spin.cpp b/src/KSPACE/pppm_spin.cpp new file mode 100644 index 0000000000..32e91cc9b2 --- /dev/null +++ b/src/KSPACE/pppm_spin.cpp @@ -0,0 +1,2559 @@ +/* ---------------------------------------------------------------------- + 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: Stan Moore (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include "pppm_dipole.h" +#include "atom.h" +#include "comm.h" +#include "gridcomm.h" +#include "neighbor.h" +#include "force.h" +#include "pair.h" +#include "bond.h" +#include "angle.h" +#include "domain.h" +#include "fft3d_wrap.h" +#include "remap_wrap.h" +#include "memory.h" +#include "error.h" +#include "update.h" + +#include "math_const.h" +#include "math_special.h" + +using namespace LAMMPS_NS; +using namespace MathConst; +using namespace MathSpecial; + +#define MAXORDER 7 +#define OFFSET 16384 +#define LARGE 10000.0 +#define SMALL 0.00001 +#define EPS_HOC 1.0e-7 + +enum{REVERSE_MU}; +enum{FORWARD_MU,FORWARD_MU_PERATOM}; + +#ifdef FFT_SINGLE +#define ZEROF 0.0f +#define ONEF 1.0f +#else +#define ZEROF 0.0 +#define ONEF 1.0 +#endif + +/* ---------------------------------------------------------------------- */ + +PPPMDipole::PPPMDipole(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg), + densityx_brick_dipole(NULL), densityy_brick_dipole(NULL), + densityz_brick_dipole(NULL), ux_brick_dipole(NULL), + uy_brick_dipole(NULL), uz_brick_dipole(NULL), vdxx_brick_dipole(NULL), + vdxy_brick_dipole(NULL), vdyy_brick_dipole(NULL), + vdxz_brick_dipole(NULL), vdyz_brick_dipole(NULL), + vdzz_brick_dipole(NULL), v0x_brick_dipole(NULL), v1x_brick_dipole(NULL), + v2x_brick_dipole(NULL), v3x_brick_dipole(NULL), v4x_brick_dipole(NULL), + v5x_brick_dipole(NULL), v0y_brick_dipole(NULL), v1y_brick_dipole(NULL), + v2y_brick_dipole(NULL), v3y_brick_dipole(NULL), v4y_brick_dipole(NULL), + v5y_brick_dipole(NULL), v0z_brick_dipole(NULL), v1z_brick_dipole(NULL), + v2z_brick_dipole(NULL), v3z_brick_dipole(NULL), v4z_brick_dipole(NULL), + v5z_brick_dipole(NULL), work3(NULL), work4(NULL), + densityx_fft_dipole(NULL), densityy_fft_dipole(NULL), + densityz_fft_dipole(NULL) +{ + dipoleflag = 1; + group_group_enable = 0; + + cg_dipole = NULL; + cg_peratom_dipole = NULL; +} + +/* ---------------------------------------------------------------------- + free all memory +------------------------------------------------------------------------- */ + +PPPMDipole::~PPPMDipole() +{ + if (copymode) return; + + deallocate(); + if (peratom_allocate_flag) deallocate_peratom(); + fft1 = NULL; + fft2 = NULL; + remap = NULL; + cg_dipole = NULL; +} + +/* ---------------------------------------------------------------------- + called once before run +------------------------------------------------------------------------- */ + +void PPPMDipole::init() +{ + if (me == 0) { + if (screen) fprintf(screen,"PPPMDipole initialization ...\n"); + if (logfile) fprintf(logfile,"PPPMDipole initialization ...\n"); + } + + // error check + + dipoleflag = atom->mu?1:0; + qsum_qsq(0); + if (dipoleflag && q2) + error->all(FLERR,"Cannot (yet) uses charges with Kspace style PPPMDipole"); + + triclinic_check(); + + if (triclinic != domain->triclinic) + error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); + + if (domain->dimension == 2) error->all(FLERR, + "Cannot use PPPMDipole with 2d simulation"); + if (comm->style != 0) + error->universe_all(FLERR,"PPPMDipole can only currently be used with " + "comm_style brick"); + + if (!atom->mu) error->all(FLERR,"Kspace style requires atom attribute mu"); + + if (atom->mu && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" + " ad with dipoles"); + + if (dipoleflag && strcmp(update->unit_style,"electron") == 0) + error->all(FLERR,"Cannot (yet) use 'electron' units with dipoles"); + + if (slabflag == 0 && domain->nonperiodic > 0) + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipole"); + if (slabflag) { + if (domain->xperiodic != 1 || domain->yperiodic != 1 || + domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) + error->all(FLERR,"Incorrect boundaries with slab PPPMDipole"); + } + + if (order < 2 || order > MAXORDER) { + char str[128]; + sprintf(str,"PPPMDipole order cannot be < 2 or > than %d",MAXORDER); + error->all(FLERR,str); + } + + // extract short-range Coulombic cutoff from pair style + + triclinic = domain->triclinic; + if (triclinic) + error->all(FLERR,"Cannot yet use triclinic cells with PPPMDipole"); + + pair_check(); + + int itmp = 0; + double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); + if (p_cutoff == NULL) + error->all(FLERR,"KSpace style is incompatible with Pair style"); + cutoff = *p_cutoff; + + // kspace TIP4P not yet supported + + if (tip4pflag) + error->all(FLERR,"Cannot yet use TIP4P with PPPMDipole"); + + // compute qsum & qsqsum and warn if not charge-neutral + + scale = 1.0; + qqrd2e = force->qqrd2e; + musum_musq(); + natoms_original = atom->natoms; + + // set accuracy (force units) from accuracy_relative or accuracy_absolute + + if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute; + else accuracy = accuracy_relative * two_charge_force; + + // free all arrays previously allocated + + deallocate(); + if (peratom_allocate_flag) deallocate_peratom(); + + // setup FFT grid resolution and g_ewald + // normally one iteration thru while loop is all that is required + // if grid stencil does not extend beyond neighbor proc + // or overlap is allowed, then done + // else reduce order and try again + + int (*procneigh)[2] = comm->procneigh; + + GridComm *cgtmp = NULL; + int iteration = 0; + + while (order >= minorder) { + if (iteration && me == 0) + error->warning(FLERR,"Reducing PPPMDipole order b/c stencil extends " + "beyond nearest neighbor processor"); + + compute_gf_denom(); + set_grid_global(); + set_grid_local(); + if (overlap_allowed) break; + + cgtmp = new GridComm(lmp,world,1,1, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, + nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, + procneigh[0][0],procneigh[0][1],procneigh[1][0], + procneigh[1][1],procneigh[2][0],procneigh[2][1]); + cgtmp->ghost_notify(); + if (!cgtmp->ghost_overlap()) break; + delete cgtmp; + + order--; + iteration++; + } + + if (order < minorder) error->all(FLERR,"PPPMDipole order < minimum allowed order"); + if (!overlap_allowed && cgtmp->ghost_overlap()) + error->all(FLERR,"PPPMDipole grid stencil extends " + "beyond nearest neighbor processor"); + if (cgtmp) delete cgtmp; + + // adjust g_ewald + + if (!gewaldflag) adjust_gewald(); + + // calculate the final accuracy + + double estimated_accuracy = final_accuracy_dipole(); + + // print stats + + int ngrid_max,nfft_both_max; + MPI_Allreduce(&ngrid,&ngrid_max,1,MPI_INT,MPI_MAX,world); + MPI_Allreduce(&nfft_both,&nfft_both_max,1,MPI_INT,MPI_MAX,world); + + if (me == 0) { + +#ifdef FFT_SINGLE + const char fft_prec[] = "single"; +#else + const char fft_prec[] = "double"; +#endif + + if (screen) { + fprintf(screen," G vector (1/distance) = %g\n",g_ewald); + fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); + fprintf(screen," stencil order = %d\n",order); + fprintf(screen," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(screen," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(screen," using %s precision FFTs\n",fft_prec); + fprintf(screen," 3d grid and FFT values/proc = %d %d\n", + ngrid_max,nfft_both_max); + } + if (logfile) { + fprintf(logfile," G vector (1/distance) = %g\n",g_ewald); + fprintf(logfile," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); + fprintf(logfile," stencil order = %d\n",order); + fprintf(logfile," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(logfile," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(logfile," using %s precision FFTs\n",fft_prec); + fprintf(logfile," 3d grid and FFT values/proc = %d %d\n", + ngrid_max,nfft_both_max); + } + } + + // allocate K-space dependent memory + // don't invoke allocate peratom(), will be allocated when needed + + allocate(); + cg_dipole->ghost_notify(); + cg_dipole->setup(); + + // pre-compute Green's function denomiator expansion + // pre-compute 1d charge distribution coefficients + + compute_gf_denom(); + compute_rho_coeff(); +} + +/* ---------------------------------------------------------------------- + adjust PPPMDipole coeffs, called initially and whenever volume has changed +------------------------------------------------------------------------- */ + +void PPPMDipole::setup() +{ + // perform some checks to avoid illegal boundaries with read_data + + if (slabflag == 0 && domain->nonperiodic > 0) + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipole"); + if (slabflag) { + if (domain->xperiodic != 1 || domain->yperiodic != 1 || + domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) + error->all(FLERR,"Incorrect boundaries with slab PPPMDipole"); + } + + int i,j,k,n; + double *prd; + + // volume-dependent factors + // adjust z dimension for 2d slab PPPMDipole + // z dimension for 3d PPPMDipole is zprd since slab_volfactor = 1.0 + + prd = domain->prd; + double xprd = prd[0]; + double yprd = prd[1]; + double zprd = prd[2]; + double zprd_slab = zprd*slab_volfactor; + volume = xprd * yprd * zprd_slab; + + delxinv = nx_pppm/xprd; + delyinv = ny_pppm/yprd; + delzinv = nz_pppm/zprd_slab; + + delvolinv = delxinv*delyinv*delzinv; + + double unitkx = (MY_2PI/xprd); + double unitky = (MY_2PI/yprd); + double unitkz = (MY_2PI/zprd_slab); + + // fkx,fky,fkz for my FFT grid pts + + double per; + + for (i = nxlo_fft; i <= nxhi_fft; i++) { + per = i - nx_pppm*(2*i/nx_pppm); + fkx[i] = unitkx*per; + } + + for (i = nylo_fft; i <= nyhi_fft; i++) { + per = i - ny_pppm*(2*i/ny_pppm); + fky[i] = unitky*per; + } + + for (i = nzlo_fft; i <= nzhi_fft; i++) { + per = i - nz_pppm*(2*i/nz_pppm); + fkz[i] = unitkz*per; + } + + // virial coefficients + + double sqk,vterm; + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) { + for (j = nylo_fft; j <= nyhi_fft; j++) { + for (i = nxlo_fft; i <= nxhi_fft; i++) { + sqk = fkx[i]*fkx[i] + fky[j]*fky[j] + fkz[k]*fkz[k]; + if (sqk == 0.0) { + vg[n][0] = 0.0; + vg[n][1] = 0.0; + vg[n][2] = 0.0; + vg[n][3] = 0.0; + vg[n][4] = 0.0; + vg[n][5] = 0.0; + } else { + vterm = -2.0 * (1.0/sqk + 0.25/(g_ewald*g_ewald)); + vg[n][0] = 1.0 + vterm*fkx[i]*fkx[i]; + vg[n][1] = 1.0 + vterm*fky[j]*fky[j]; + vg[n][2] = 1.0 + vterm*fkz[k]*fkz[k]; + vg[n][3] = vterm*fkx[i]*fky[j]; + vg[n][4] = vterm*fkx[i]*fkz[k]; + vg[n][5] = vterm*fky[j]*fkz[k]; + } + n++; + } + } + } + + compute_gf_dipole(); +} + +/* ---------------------------------------------------------------------- + reset local grid arrays and communication stencils + called by fix balance b/c it changed sizes of processor sub-domains +------------------------------------------------------------------------- */ + +void PPPMDipole::setup_grid() +{ + // free all arrays previously allocated + + deallocate(); + if (peratom_allocate_flag) deallocate_peratom(); + + // reset portion of global grid that each proc owns + + set_grid_local(); + + // reallocate K-space dependent memory + // check if grid communication is now overlapping if not allowed + // don't invoke allocate peratom(), will be allocated when needed + + allocate(); + + cg_dipole->ghost_notify(); + if (overlap_allowed == 0 && cg_dipole->ghost_overlap()) + error->all(FLERR,"PPPMDipole grid stencil extends " + "beyond nearest neighbor processor"); + cg_dipole->setup(); + + // pre-compute Green's function denomiator expansion + // pre-compute 1d charge distribution coefficients + + compute_gf_denom(); + compute_rho_coeff(); + + // pre-compute volume-dependent coeffs + + setup(); +} + +/* ---------------------------------------------------------------------- + compute the PPPMDipole long-range force, energy, virial +------------------------------------------------------------------------- */ + +void PPPMDipole::compute(int eflag, int vflag) +{ + int i,j; + + // set energy/virial flags + // invoke allocate_peratom() if needed for first time + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = evflag_atom = eflag_global = vflag_global = + eflag_atom = vflag_atom = 0; + + if (evflag_atom && !peratom_allocate_flag) { + allocate_peratom(); + cg_peratom_dipole->ghost_notify(); + cg_peratom_dipole->setup(); + } + + // if atom count has changed, update qsum and qsqsum + + if (atom->natoms != natoms_original) { + musum_musq(); + natoms_original = atom->natoms; + } + + // return if there are no dipoles + + if (musqsum == 0.0) return; + + // convert atoms from box to lamda coords + + boxlo = domain->boxlo; + + // extend size of per-atom arrays if necessary + + if (atom->nmax > nmax) { + memory->destroy(part2grid); + nmax = atom->nmax; + memory->create(part2grid,nmax,3,"pppm_dipole:part2grid"); + } + + // find grid points for all my particles + // map my particle charge onto my local 3d density grid + + particle_map(); + make_rho_dipole(); + + // all procs communicate density values from their ghost cells + // to fully sum contribution in their 3d bricks + // remap from 3d decomposition to FFT decomposition + + cg_dipole->reverse_comm(this,REVERSE_MU); + brick2fft_dipole(); + + // compute potential gradient on my FFT grid and + // portion of e_long on this proc's FFT grid + // return gradients (electric fields) in 3d brick decomposition + // also performs per-atom calculations via poisson_peratom() + + poisson_ik_dipole(); + + // all procs communicate E-field values + // to fill ghost cells surrounding their 3d bricks + + cg_dipole->forward_comm(this,FORWARD_MU); + + // extra per-atom energy/virial communication + + if (evflag_atom) { + cg_peratom_dipole->forward_comm(this,FORWARD_MU_PERATOM); + } + + // calculate the force on my particles + + fieldforce_ik_dipole(); + + // extra per-atom energy/virial communication + + if (evflag_atom) fieldforce_peratom_dipole(); + + // sum global energy across procs and add in volume-dependent term + + const double qscale = qqrd2e * scale; + const double g3 = g_ewald*g_ewald*g_ewald; + + if (eflag_global) { + double energy_all; + MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world); + energy = energy_all; + + energy *= 0.5*volume; + energy -= musqsum*2.0*g3/3.0/MY_PIS; + energy *= qscale; + } + + // sum global virial across procs + + if (vflag_global) { + double virial_all[6]; + MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); + for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i]; + } + + // per-atom energy/virial + // energy includes self-energy correction + + if (evflag_atom) { + double *q = atom->q; + double **mu = atom->mu; + int nlocal = atom->nlocal; + int ntotal = nlocal; + + if (eflag_atom) { + for (i = 0; i < nlocal; i++) { + eatom[i] *= 0.5; + eatom[i] -= (mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2])*2.0*g3/3.0/MY_PIS; + eatom[i] *= qscale; + } + } + + if (vflag_atom) { + for (i = 0; i < ntotal; i++) + for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*qscale; + } + } + + // 2d slab correction + + if (slabflag == 1) slabcorr(); +} + +/* ---------------------------------------------------------------------- + allocate memory that depends on # of K-vectors and order +------------------------------------------------------------------------- */ + +void PPPMDipole::allocate() +{ + memory->create3d_offset(densityx_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:densityx_brick_dipole"); + memory->create3d_offset(densityy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:densityy_brick_dipole"); + memory->create3d_offset(densityz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:densityz_brick_dipole"); + + memory->create(densityx_fft_dipole,nfft_both,"pppm_dipole:densityy_fft_dipole"); + memory->create(densityy_fft_dipole,nfft_both,"pppm_dipole:densityy_fft_dipole"); + memory->create(densityz_fft_dipole,nfft_both,"pppm_dipole:densityz_fft_dipole"); + + memory->create(greensfn,nfft_both,"pppm_dipole:greensfn"); + memory->create(work1,2*nfft_both,"pppm_dipole:work1"); + memory->create(work2,2*nfft_both,"pppm_dipole:work2"); + memory->create(work3,2*nfft_both,"pppm_dipole:work3"); + memory->create(work4,2*nfft_both,"pppm_dipole:work4"); + memory->create(vg,nfft_both,6,"pppm_dipole:vg"); + + memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm_dipole:fkx"); + memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm_dipole:fky"); + memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm_dipole:fkz"); + + memory->create3d_offset(ux_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:ux_brick_dipole"); + memory->create3d_offset(uy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:uy_brick_dipole"); + memory->create3d_offset(uz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:uz_brick_dipole"); + + memory->create3d_offset(vdxx_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdxx_brick_dipole"); + memory->create3d_offset(vdxy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdxy_brick_dipole"); + memory->create3d_offset(vdyy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdyy_brick_dipole"); + memory->create3d_offset(vdxz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdxz_brick_dipole"); + memory->create3d_offset(vdyz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdyz_brick_dipole"); + memory->create3d_offset(vdzz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdzz_brick_dipole"); + + // summation coeffs + + order_allocated = order; + memory->create(gf_b,order,"pppm_dipole:gf_b"); + memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm_dipole:rho1d"); + memory->create2d_offset(drho1d,3,-order/2,order/2,"pppm_dipole:drho1d"); + memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm_dipole:rho_coeff"); + memory->create2d_offset(drho_coeff,order,(1-order)/2,order/2, + "pppm_dipole:drho_coeff"); + + // create 2 FFTs and a Remap + // 1st FFT keeps data in FFT decompostion + // 2nd FFT returns data in 3d brick decomposition + // remap takes data from 3d brick to FFT decomposition + + int tmp; + + fft1 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm, + nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, + nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, + 0,0,&tmp,collective_flag); + + fft2 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm, + nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, + 0,0,&tmp,collective_flag); + + remap = new Remap(lmp,world, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, + nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft, + 1,0,0,FFT_PRECISION,collective_flag); + + // create ghost grid object for rho and electric field communication + + int (*procneigh)[2] = comm->procneigh; + + cg_dipole = new GridComm(lmp,world,9,3, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, + nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, + procneigh[0][0],procneigh[0][1],procneigh[1][0], + procneigh[1][1],procneigh[2][0],procneigh[2][1]); +} + +/* ---------------------------------------------------------------------- + deallocate memory that depends on # of K-vectors and order +------------------------------------------------------------------------- */ + +void PPPMDipole::deallocate() +{ + memory->destroy3d_offset(densityx_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(ux_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(uy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(uz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(vdxx_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdyy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdyz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdzz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy(densityx_fft_dipole); + memory->destroy(densityy_fft_dipole); + memory->destroy(densityz_fft_dipole); + + memory->destroy(greensfn); + memory->destroy(work1); + memory->destroy(work2); + memory->destroy(work3); + memory->destroy(work4); + memory->destroy(vg); + + memory->destroy1d_offset(fkx,nxlo_fft); + memory->destroy1d_offset(fky,nylo_fft); + memory->destroy1d_offset(fkz,nzlo_fft); + + memory->destroy(gf_b); + memory->destroy2d_offset(rho1d,-order_allocated/2); + memory->destroy2d_offset(drho1d,-order_allocated/2); + memory->destroy2d_offset(rho_coeff,(1-order_allocated)/2); + memory->destroy2d_offset(drho_coeff,(1-order_allocated)/2); + + delete fft1; + delete fft2; + delete remap; + delete cg_dipole; +} + +/* ---------------------------------------------------------------------- + allocate per-atom memory that depends on # of K-vectors and order +------------------------------------------------------------------------- */ + +void PPPMDipole::allocate_peratom() +{ + peratom_allocate_flag = 1; + + memory->create3d_offset(v0x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v0x_brick_dipole"); + memory->create3d_offset(v1x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v1x_brick_dipole"); + memory->create3d_offset(v2x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v2x_brick_dipole"); + memory->create3d_offset(v3x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v3x_brick_dipole"); + memory->create3d_offset(v4x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v4x_brick_dipole"); + memory->create3d_offset(v5x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v5x_brick_dipole"); + + memory->create3d_offset(v0y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v0y_brick_dipole"); + memory->create3d_offset(v1y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v1y_brick_dipole"); + memory->create3d_offset(v2y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v2y_brick_dipole"); + memory->create3d_offset(v3y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v3y_brick_dipole"); + memory->create3d_offset(v4y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v4y_brick_dipole"); + memory->create3d_offset(v5y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v5y_brick_dipole"); + + memory->create3d_offset(v0z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v0z_brick_dipole"); + memory->create3d_offset(v1z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v1z_brick_dipole"); + memory->create3d_offset(v2z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v2z_brick_dipole"); + memory->create3d_offset(v3z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v3z_brick_dipole"); + memory->create3d_offset(v4z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v4z_brick_dipole"); + memory->create3d_offset(v5z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v5z_brick_dipole"); + + // create ghost grid object for rho and electric field communication + + int (*procneigh)[2] = comm->procneigh; + + cg_peratom_dipole = + new GridComm(lmp,world,18,1, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, + nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, + procneigh[0][0],procneigh[0][1],procneigh[1][0], + procneigh[1][1],procneigh[2][0],procneigh[2][1]); +} + +/* ---------------------------------------------------------------------- + deallocate per-atom memory that depends on # of K-vectors and order +------------------------------------------------------------------------- */ + +void PPPMDipole::deallocate_peratom() +{ + peratom_allocate_flag = 0; + + memory->destroy3d_offset(v0x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(v0y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(v0z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + delete cg_peratom_dipole; +} + +/* ---------------------------------------------------------------------- + set global size of PPPMDipole grid = nx,ny,nz_pppm + used for charge accumulation, FFTs, and electric field interpolation +------------------------------------------------------------------------- */ + +void PPPMDipole::set_grid_global() +{ + // use xprd,yprd,zprd + // adjust z dimension for 2d slab PPPMDipole + // 3d PPPMDipole just uses zprd since slab_volfactor = 1.0 + + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + double zprd_slab = zprd*slab_volfactor; + + // make initial g_ewald estimate + // based on desired accuracy and real space cutoff + // fluid-occupied volume used to estimate real-space error + // zprd used rather than zprd_slab + + double h; + bigint natoms = atom->natoms; + + if (!gewaldflag) { + if (accuracy <= 0.0) + error->all(FLERR,"KSpace accuracy must be > 0"); + if (mu2 == 0.0) + error->all(FLERR,"Must use kspace_modify gewald for systems with no dipoles"); + g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; + //Try Newton Solver + double g_ewald_new = + find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); + if (g_ewald_new > 0.0) g_ewald = g_ewald_new; + else error->warning(FLERR,"PPPMDipole dipole Newton solver failed, " + "using old method to estimate g_ewald"); + } + + // set optimal nx_pppm,ny_pppm,nz_pppm based on order and accuracy + // nz_pppm uses extended zprd_slab instead of zprd + // reduce it until accuracy target is met + + if (!gridflag) { + + h = h_x = h_y = h_z = 4.0/g_ewald; + int count = 0; + while (1) { + + // set grid dimension + nx_pppm = static_cast (xprd/h_x); + ny_pppm = static_cast (yprd/h_y); + nz_pppm = static_cast (zprd_slab/h_z); + + if (nx_pppm <= 1) nx_pppm = 2; + if (ny_pppm <= 1) ny_pppm = 2; + if (nz_pppm <= 1) nz_pppm = 2; + + //set local grid dimension + int npey_fft,npez_fft; + if (nz_pppm >= nprocs) { + npey_fft = 1; + npez_fft = nprocs; + } else procs2grid2d(nprocs,ny_pppm,nz_pppm,&npey_fft,&npez_fft); + + int me_y = me % npey_fft; + int me_z = me / npey_fft; + + nxlo_fft = 0; + nxhi_fft = nx_pppm - 1; + nylo_fft = me_y*ny_pppm/npey_fft; + nyhi_fft = (me_y+1)*ny_pppm/npey_fft - 1; + nzlo_fft = me_z*nz_pppm/npez_fft; + nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1; + + double df_kspace = compute_df_kspace_dipole(); + + count++; + + // break loop if the accuracy has been reached or + // too many loops have been performed + + if (df_kspace <= accuracy) break; + if (count > 500) error->all(FLERR, "Could not compute grid size"); + h *= 0.95; + h_x = h_y = h_z = h; + } + } + + // boost grid size until it is factorable + + while (!factorable(nx_pppm)) nx_pppm++; + while (!factorable(ny_pppm)) ny_pppm++; + while (!factorable(nz_pppm)) nz_pppm++; + + h_x = xprd/nx_pppm; + h_y = yprd/ny_pppm; + h_z = zprd_slab/nz_pppm; + + if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET) + error->all(FLERR,"PPPMDipole grid is too large"); +} + + +/* ---------------------------------------------------------------------- + compute estimated kspace force error for dipoles +------------------------------------------------------------------------- */ + +double PPPMDipole::compute_df_kspace_dipole() +{ + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + double zprd_slab = zprd*slab_volfactor; + bigint natoms = atom->natoms; + double qopt = compute_qopt_dipole(); + double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); + return df_kspace; +} + +/* ---------------------------------------------------------------------- + compute qopt for dipoles with ik differentiation +------------------------------------------------------------------------- */ + +double PPPMDipole::compute_qopt_dipole() +{ + double qopt = 0.0; + const double * const prd = domain->prd; + + const double xprd = prd[0]; + const double yprd = prd[1]; + const double zprd = prd[2]; + const double zprd_slab = zprd*slab_volfactor; + const double unitkx = (MY_2PI/xprd); + const double unitky = (MY_2PI/yprd); + const double unitkz = (MY_2PI/zprd_slab); + + double snx,sny,snz; + double cnx,cny,cnz; + double argx,argy,argz,wx,wy,wz,sx,sy,sz,qx,qy,qz; + double sum1,sum2,dot1,dot2; + double numerator,denominator; + double u1,u2,u3,sqk; + + int k,l,m,nx,ny,nz,kper,lper,mper; + + const int nbx = 2; + const int nby = 2; + const int nbz = 2; + + const int twoorder = 2*order; + + for (m = nzlo_fft; m <= nzhi_fft; m++) { + mper = m - nz_pppm*(2*m/nz_pppm); + snz = square(sin(0.5*unitkz*mper*zprd_slab/nz_pppm)); + cnz = cos(0.5*unitkz*mper*zprd_slab/nz_pppm); + + for (l = nylo_fft; l <= nyhi_fft; l++) { + lper = l - ny_pppm*(2*l/ny_pppm); + sny = square(sin(0.5*unitky*lper*yprd/ny_pppm)); + cny = cos(0.5*unitky*lper*yprd/ny_pppm); + + for (k = nxlo_fft; k <= nxhi_fft; k++) { + kper = k - nx_pppm*(2*k/nx_pppm); + snx = square(sin(0.5*unitkx*kper*xprd/nx_pppm)); + cnx = cos(0.5*unitkx*kper*xprd/nx_pppm); + + sqk = square(unitkx*kper) + square(unitky*lper) + square(unitkz*mper); + + if (sqk != 0.0) { + numerator = MY_4PI/sqk; + denominator = gf_denom(snx,sny,snz); + sum1 = 0.0; + sum2 = 0.0; + + for (nx = -nbx; nx <= nbx; nx++) { + qx = unitkx*(kper+nx_pppm*nx); + sx = exp(-0.25*square(qx/g_ewald)); + argx = 0.5*qx*xprd/nx_pppm; + wx = powsinxx(argx,twoorder); + + for (ny = -nby; ny <= nby; ny++) { + qy = unitky*(lper+ny_pppm*ny); + sy = exp(-0.25*square(qy/g_ewald)); + argy = 0.5*qy*yprd/ny_pppm; + wy = powsinxx(argy,twoorder); + + for (nz = -nbz; nz <= nbz; nz++) { + qz = unitkz*(mper+nz_pppm*nz); + sz = exp(-0.25*square(qz/g_ewald)); + argz = 0.5*qz*zprd_slab/nz_pppm; + wz = powsinxx(argz,twoorder); + + dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz; + dot2 = qx*qx + qy*qy + qz*qz; + //dot1 = dot1*dot1*dot1; // power of 3 for dipole forces + //dot2 = dot2*dot2*dot2; + u1 = sx*sy*sz; + const double w2 = wx*wy*wz; + const double phi = u1*MY_4PI/dot2; + const double top = dot1*dot1*dot1*w2*phi; + sum1 += phi*phi*dot2*dot2*dot2; + sum2 += top*top/sqk/sqk/sqk; + } + } + } + qopt += sum1 - sum2/denominator; + } + } + } + } + double qopt_all; + MPI_Allreduce(&qopt,&qopt_all,1,MPI_DOUBLE,MPI_SUM,world); + return qopt_all; +} + +/* ---------------------------------------------------------------------- + pre-compute modified (Hockney-Eastwood) Coulomb Green's function +------------------------------------------------------------------------- */ + +void PPPMDipole::compute_gf_dipole() +{ + const double * const prd = domain->prd; + + const double xprd = prd[0]; + const double yprd = prd[1]; + const double zprd = prd[2]; + const double zprd_slab = zprd*slab_volfactor; + const double unitkx = (MY_2PI/xprd); + const double unitky = (MY_2PI/yprd); + const double unitkz = (MY_2PI/zprd_slab); + + double snx,sny,snz; + double cnx,cny,cnz; + double argx,argy,argz,wx,wy,wz,sx,sy,sz,qx,qy,qz; + double sum1,dot1,dot2; + double numerator,denominator; + double sqk; + + int k,l,m,n,nx,ny,nz,kper,lper,mper; + + int nbx = static_cast ((g_ewald*xprd/(MY_PI*nx_pppm)) * + pow(-log(EPS_HOC),0.25)); + 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/(MY_PI*nz_pppm)) * + pow(-log(EPS_HOC),0.25)); + nbx = MAX(nbx,2); + nby = MAX(nby,2); + nbz = MAX(nbz,2); + const int twoorder = 2*order; + + n = 0; + for (m = nzlo_fft; m <= nzhi_fft; m++) { + mper = m - nz_pppm*(2*m/nz_pppm); + snz = square(sin(0.5*unitkz*mper*zprd_slab/nz_pppm)); + cnz = cos(0.5*unitkz*mper*zprd_slab/nz_pppm); + + for (l = nylo_fft; l <= nyhi_fft; l++) { + lper = l - ny_pppm*(2*l/ny_pppm); + sny = square(sin(0.5*unitky*lper*yprd/ny_pppm)); + cny = cos(0.5*unitky*lper*yprd/ny_pppm); + + for (k = nxlo_fft; k <= nxhi_fft; k++) { + kper = k - nx_pppm*(2*k/nx_pppm); + snx = square(sin(0.5*unitkx*kper*xprd/nx_pppm)); + cnx = cos(0.5*unitkx*kper*xprd/nx_pppm); + + sqk = square(unitkx*kper) + square(unitky*lper) + square(unitkz*mper); + + if (sqk != 0.0) { + numerator = MY_4PI/sqk; + denominator = gf_denom(snx,sny,snz); + sum1 = 0.0; + + for (nx = -nbx; nx <= nbx; nx++) { + qx = unitkx*(kper+nx_pppm*nx); + sx = exp(-0.25*square(qx/g_ewald)); + argx = 0.5*qx*xprd/nx_pppm; + wx = powsinxx(argx,twoorder); + + for (ny = -nby; ny <= nby; ny++) { + qy = unitky*(lper+ny_pppm*ny); + sy = exp(-0.25*square(qy/g_ewald)); + argy = 0.5*qy*yprd/ny_pppm; + wy = powsinxx(argy,twoorder); + + for (nz = -nbz; nz <= nbz; nz++) { + qz = unitkz*(mper+nz_pppm*nz); + sz = exp(-0.25*square(qz/g_ewald)); + argz = 0.5*qz*zprd_slab/nz_pppm; + wz = powsinxx(argz,twoorder); + + dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz; + dot2 = qx*qx + qy*qy + qz*qz; + const double u1 = sx*sy*sz; + const double w2 = wx*wy*wz; + const double phi = u1*MY_4PI/dot2; + sum1 += dot1*dot1*dot1*w2*phi/sqk/sqk/sqk; + } + } + } + greensfn[n++] = sum1/denominator; + } else greensfn[n++] = 0.0; + } + } + } +} + +/* ---------------------------------------------------------------------- + calculate f(x) for use in Newton-Raphson solver +------------------------------------------------------------------------- */ + +double PPPMDipole::newton_raphson_f() +{ + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + bigint natoms = atom->natoms; + + double df_rspace,df_kspace; + double vol = xprd*yprd*zprd; + double a = cutoff*g_ewald; + double rg2 = a*a; + double rg4 = rg2*rg2; + double rg6 = rg4*rg2; + double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; + double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; + df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); + df_kspace = compute_df_kspace_dipole(); + + return df_rspace - df_kspace; +} + +/* ---------------------------------------------------------------------- + find g_ewald parameter for dipoles based on desired accuracy + using a Newton-Raphson solver +------------------------------------------------------------------------- */ + +double PPPMDipole::find_gewald_dipole(double x, double Rc, + bigint natoms, double vol, double b2) +{ + double dx,tol; + int maxit; + + maxit = 10000; //Maximum number of iterations + tol = 0.00001; //Convergence tolerance + + //Begin algorithm + + for (int i = 0; i < maxit; i++) { + dx = newton_raphson_f_dipole(x,Rc,natoms,vol,b2) / derivf_dipole(x,Rc,natoms,vol,b2); + x = x - dx; //Update x + if (fabs(dx) < tol) return x; + if (x < 0 || x != x) // solver failed + return -1; + } + return -1; +} + +/* ---------------------------------------------------------------------- + calculate f(x) objective function for dipoles + ------------------------------------------------------------------------- */ + +double PPPMDipole::newton_raphson_f_dipole(double x, double Rc, bigint +natoms, double vol, double b2) +{ + double a = Rc*x; + double rg2 = a*a; + double rg4 = rg2*rg2; + double rg6 = rg4*rg2; + double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; + double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; + double f = (b2/(sqrt(vol*powint(x,4)*powint(Rc,9)*natoms)) * + sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * + exp(-rg2)) - accuracy; + + return f; +} + +/* ---------------------------------------------------------------------- + calculate numerical derivative f'(x) of objective function for dipoles + ------------------------------------------------------------------------- */ + +double PPPMDipole::derivf_dipole(double x, double Rc, + bigint natoms, double vol, double b2) +{ + double h = 0.000001; //Derivative step-size + return (newton_raphson_f_dipole(x + h,Rc,natoms,vol,b2) - newton_raphson_f_dipole(x,Rc,natoms,vol,b2)) / h; +} + +/* ---------------------------------------------------------------------- + calculate the final estimate of the accuracy +------------------------------------------------------------------------- */ + +double PPPMDipole::final_accuracy_dipole() +{ + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + double vol = xprd*yprd*zprd; + bigint natoms = atom->natoms; + if (natoms == 0) natoms = 1; // avoid division by zero + + double df_kspace = compute_df_kspace_dipole(); + + double a = cutoff*g_ewald; + double rg2 = a*a; + double rg4 = rg2*rg2; + double rg6 = rg4*rg2; + double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; + double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; + double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * + exp(-rg2)); + + double estimated_accuracy = sqrt(df_kspace*df_kspace + df_rspace*df_rspace); + + return estimated_accuracy; +} + +/* ---------------------------------------------------------------------- + pre-compute Green's function denominator expansion coeffs, Gamma(2n) +------------------------------------------------------------------------- */ + +void PPPMDipole::compute_gf_denom() +{ + if (gf_b) memory->destroy(gf_b); + memory->create(gf_b,order,"pppm_dipole:gf_b"); + + int k,l,m; + + for (l = 1; l < order; l++) gf_b[l] = 0.0; + gf_b[0] = 1.0; + + for (m = 1; m < order; m++) { + for (l = m; l > 0; l--) + gf_b[l] = 4.0 * (gf_b[l]*(l-m)*(l-m-0.5)-gf_b[l-1]*(l-m-1)*(l-m-1)); + gf_b[0] = 4.0 * (gf_b[0]*(l-m)*(l-m-0.5)); + } + + bigint ifact = 1; + for (k = 1; k < 2*order; k++) ifact *= k; + double gaminv = 1.0/ifact; + for (l = 0; l < order; l++) gf_b[l] *= gaminv; +} + +/* ---------------------------------------------------------------------- + create discretized "density" on section of global grid due to my particles + density(x,y,z) = charge "density" at grid points of my 3d brick + (nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts) + in global grid +------------------------------------------------------------------------- */ + +void PPPMDipole::make_rho_dipole() +{ + int l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz; + FFT_SCALAR x0,y0,z0; + FFT_SCALAR x1,y1,z1; + FFT_SCALAR x2,y2,z2; + + // clear 3d density array + + memset(&(densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + ngrid*sizeof(FFT_SCALAR)); + memset(&(densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + ngrid*sizeof(FFT_SCALAR)); + memset(&(densityz_brick_dipole[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 + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + + double **mu = atom->mu; + double **x = atom->x; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + z0 = delvolinv * mu[i][0]; + z1 = delvolinv * mu[i][1]; + z2 = delvolinv * mu[i][2]; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + y0 = z0*rho1d[2][n]; + y1 = z1*rho1d[2][n]; + y2 = z2*rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + x0 = y0*rho1d[1][m]; + x1 = y1*rho1d[1][m]; + x2 = y2*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + densityx_brick_dipole[mz][my][mx] += x0*rho1d[0][l]; + densityy_brick_dipole[mz][my][mx] += x1*rho1d[0][l]; + densityz_brick_dipole[mz][my][mx] += x2*rho1d[0][l]; + } + } + } + } +} + +/* ---------------------------------------------------------------------- + remap density from 3d brick decomposition to FFT decomposition +------------------------------------------------------------------------- */ + +void PPPMDipole::brick2fft_dipole() +{ + int n,ix,iy,iz; + + // copy grabs inner portion of density from 3d brick + // remap could be done as pre-stage of FFT, + // but this works optimally on only double values, not complex values + + n = 0; + for (iz = nzlo_in; iz <= nzhi_in; iz++) + for (iy = nylo_in; iy <= nyhi_in; iy++) + for (ix = nxlo_in; ix <= nxhi_in; ix++) { + densityx_fft_dipole[n] = densityx_brick_dipole[iz][iy][ix]; + densityy_fft_dipole[n] = densityy_brick_dipole[iz][iy][ix]; + densityz_fft_dipole[n] = densityz_brick_dipole[iz][iy][ix]; + n++; + } + + remap->perform(densityx_fft_dipole,densityx_fft_dipole,work1); + remap->perform(densityy_fft_dipole,densityy_fft_dipole,work1); + remap->perform(densityz_fft_dipole,densityz_fft_dipole,work1); +} + +/* ---------------------------------------------------------------------- + FFT-based Poisson solver for ik +------------------------------------------------------------------------- */ + +void PPPMDipole::poisson_ik_dipole() +{ + int i,j,k,n,ii; + double eng; + double wreal,wimg; + + // transform dipole density (r -> k) + + n = 0; + for (i = 0; i < nfft; i++) { + work1[n] = densityx_fft_dipole[i]; + work1[n+1] = ZEROF; + work2[n] = densityy_fft_dipole[i]; + work2[n+1] = ZEROF; + work3[n] = densityz_fft_dipole[i]; + work3[n+1] = ZEROF; + n += 2; + } + + fft1->compute(work1,work1,1); + fft1->compute(work2,work2,1); + fft1->compute(work3,work3,1); + + // global energy and virial contribution + + double scaleinv = 1.0/(nx_pppm*ny_pppm*nz_pppm); + double s2 = scaleinv*scaleinv; + + if (eflag_global || vflag_global) { + if (vflag_global) { + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + wreal = (work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + wimg = (work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + eng = s2 * greensfn[ii] * (wreal*wreal + wimg*wimg); + for (int jj = 0; jj < 6; jj++) virial[jj] += eng*vg[ii][jj]; + virial[0] += 2.0*s2*greensfn[ii]*fkx[i]*(work1[n]*wreal + work1[n+1]*wimg); + virial[1] += 2.0*s2*greensfn[ii]*fky[j]*(work2[n]*wreal + work2[n+1]*wimg); + virial[2] += 2.0*s2*greensfn[ii]*fkz[k]*(work3[n]*wreal + work3[n+1]*wimg); + virial[3] += 2.0*s2*greensfn[ii]*fky[j]*(work1[n]*wreal + work1[n+1]*wimg); + virial[4] += 2.0*s2*greensfn[ii]*fkz[k]*(work1[n]*wreal + work1[n+1]*wimg); + virial[5] += 2.0*s2*greensfn[ii]*fkz[k]*(work2[n]*wreal + work2[n+1]*wimg); + if (eflag_global) energy += eng; + ii++; + n += 2; + } + } else { + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + wreal = (work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + wimg = (work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + energy += + s2 * greensfn[ii] * (wreal*wreal + wimg*wimg); + ii++; + n += 2; + } + } + } + + // scale by 1/total-grid-pts to get rho(k) + // multiply by Green's function to get V(k) + + n = 0; + for (i = 0; i < nfft; i++) { + work1[n] *= scaleinv * greensfn[i]; + work1[n+1] *= scaleinv * greensfn[i]; + work2[n] *= scaleinv * greensfn[i]; + work2[n+1] *= scaleinv * greensfn[i]; + work3[n] *= scaleinv * greensfn[i]; + work3[n+1] *= scaleinv * greensfn[i]; + n += 2; + } + + // extra FFTs for per-atom energy/virial + + if (vflag_atom) poisson_peratom_dipole(); + + // compute electric potential + // FFT leaves data in 3d brick decomposition + + // Ex + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + work4[n+1] = fkx[i]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + ux_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Ey + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + work4[n+1] = fky[j]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + uy_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Ez + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + work4[n+1] = fkz[k]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + uz_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Vxx + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*fkx[i]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + work4[n+1] = -fkx[i]*fkx[i]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + vdxx_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Vyy + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*fky[j]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + work4[n+1] = -fky[j]*fky[j]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + vdyy_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Vzz + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*fkz[k]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + work4[n+1] = -fkz[k]*fkz[k]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + vdzz_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Vxy + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*fky[j]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + work4[n+1] = -fkx[i]*fky[j]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + vdxy_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Vxz + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*fkz[k]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + work4[n+1] = -fkx[i]*fkz[k]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + vdxz_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // Vyz + + n = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*fkz[k]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]); + work4[n+1] = -fky[j]*fkz[k]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]); + n += 2; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + vdyz_brick_dipole[k][j][i] = work4[n]; + n += 2; + } +} + +/* ---------------------------------------------------------------------- + FFT-based Poisson solver for per-atom energy/virial +------------------------------------------------------------------------- */ + +void PPPMDipole::poisson_peratom_dipole() +{ + int i,ii,j,k,n; + + // 18 components of virial in v0 thru v5 + + if (!vflag_atom) return; + + // V0x + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(vg[ii][0]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkx[i]*work1[n]); + work4[n+1] = fkx[i]*(vg[ii][0]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkx[i]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v0x_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V0y + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(vg[ii][0]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkx[i]*work1[n]); + work4[n+1] = fky[j]*(vg[ii][0]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkx[i]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v0y_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V0z + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(vg[ii][0]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkx[i]*work1[n]); + work4[n+1] = fkz[k]*(vg[ii][0]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkx[i]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v0z_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V1x + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(vg[ii][1]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fky[j]*work2[n]); + work4[n+1] = fkx[i]*(vg[ii][1]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fky[j]*work2[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v1x_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V1y + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(vg[ii][1]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fky[j]*work2[n]); + work4[n+1] = fky[j]*(vg[ii][1]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fky[j]*work2[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v1y_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V1z + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(vg[ii][1]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fky[j]*work2[n]); + work4[n+1] = fkz[k]*(vg[ii][1]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fky[j]*work2[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v1z_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V2x + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(vg[ii][2]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work3[n]); + work4[n+1] = fkx[i]*(vg[ii][2]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work3[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v2x_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V2y + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(vg[ii][2]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work3[n]); + work4[n+1] = fky[j]*(vg[ii][2]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work3[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v2y_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V2z + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(vg[ii][2]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work3[n]); + work4[n+1] = fkz[k]*(vg[ii][2]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work3[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v2z_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V3x + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(vg[ii][3]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fky[j]*work1[n]); + work4[n+1] = fkx[i]*(vg[ii][3]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fky[j]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v3x_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V3y + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(vg[ii][3]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fky[j]*work1[n]); + work4[n+1] = fky[j]*(vg[ii][3]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fky[j]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v3y_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V3z + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(vg[ii][3]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fky[j]*work1[n]); + work4[n+1] = fkz[k]*(vg[ii][3]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fky[j]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v3z_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V4x + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(vg[ii][4]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work1[n]); + work4[n+1] = fkx[i]*(vg[ii][4]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v4x_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V4y + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(vg[ii][4]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work1[n]); + work4[n+1] = fky[j]*(vg[ii][4]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v4y_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V4z + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(vg[ii][4]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work1[n]); + work4[n+1] = fkz[k]*(vg[ii][4]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work1[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v4z_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V5x + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkx[i]*(vg[ii][5]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work2[n]); + work4[n+1] = fkx[i]*(vg[ii][5]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work2[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v5x_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V5y + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fky[j]*(vg[ii][5]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work2[n]); + work4[n+1] = fky[j]*(vg[ii][5]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work2[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v5y_brick_dipole[k][j][i] = work4[n]; + n += 2; + } + + // V5z + + n = 0; + ii = 0; + for (k = nzlo_fft; k <= nzhi_fft; k++) + for (j = nylo_fft; j <= nyhi_fft; j++) + for (i = nxlo_fft; i <= nxhi_fft; i++) { + work4[n] = fkz[k]*(vg[ii][5]*(work1[n]*fkx[i] + work2[n]*fky[j] + work3[n]*fkz[k]) + 2.0*fkz[k]*work2[n]); + work4[n+1] = fkz[k]*(vg[ii][5]*(work1[n+1]*fkx[i] + work2[n+1]*fky[j] + work3[n+1]*fkz[k]) + 2.0*fkz[k]*work2[n+1]); + n += 2; + ii++; + } + + fft2->compute(work4,work4,-1); + + n = 0; + for (k = nzlo_in; k <= nzhi_in; k++) + for (j = nylo_in; j <= nyhi_in; j++) + for (i = nxlo_in; i <= nxhi_in; i++) { + v5z_brick_dipole[k][j][i] = work4[n]; + n += 2; + } +} + +/* ---------------------------------------------------------------------- + interpolate from grid to get electric field & force on my particles for ik +------------------------------------------------------------------------- */ + +void PPPMDipole::fieldforce_ik_dipole() +{ + int i,l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz; + FFT_SCALAR x0,y0,z0; + FFT_SCALAR ex,ey,ez; + FFT_SCALAR vxx,vyy,vzz,vxy,vxz,vyz; + + // loop over my charges, interpolate electric field from nearby grid points + // (nx,ny,nz) = global coords of grid pt to "lower left" of charge + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + + + double **mu = atom->mu; + double **x = atom->x; + double **f = atom->f; + double **t = atom->torque; + + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) { + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + ex = ey = ez = ZEROF; + vxx = vyy = vzz = vxy = vxz = vyz = ZEROF; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + z0 = rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + y0 = z0*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + x0 = y0*rho1d[0][l]; + ex -= x0*ux_brick_dipole[mz][my][mx]; + ey -= x0*uy_brick_dipole[mz][my][mx]; + ez -= x0*uz_brick_dipole[mz][my][mx]; + vxx -= x0*vdxx_brick_dipole[mz][my][mx]; + vyy -= x0*vdyy_brick_dipole[mz][my][mx]; + vzz -= x0*vdzz_brick_dipole[mz][my][mx]; + vxy -= x0*vdxy_brick_dipole[mz][my][mx]; + vxz -= x0*vdxz_brick_dipole[mz][my][mx]; + vyz -= x0*vdyz_brick_dipole[mz][my][mx]; + } + } + } + + // convert E-field to torque + + const double mufactor = qqrd2e * scale; + f[i][0] += mufactor*(vxx*mu[i][0] + vxy*mu[i][1] + vxz*mu[i][2]); + f[i][1] += mufactor*(vxy*mu[i][0] + vyy*mu[i][1] + vyz*mu[i][2]); + f[i][2] += mufactor*(vxz*mu[i][0] + vyz*mu[i][1] + vzz*mu[i][2]); + + t[i][0] += mufactor*(mu[i][1]*ez - mu[i][2]*ey); + t[i][1] += mufactor*(mu[i][2]*ex - mu[i][0]*ez); + t[i][2] += mufactor*(mu[i][0]*ey - mu[i][1]*ex); + } +} + +/* ---------------------------------------------------------------------- + interpolate from grid to get per-atom energy/virial +------------------------------------------------------------------------- */ + +void PPPMDipole::fieldforce_peratom_dipole() +{ + int i,l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz,x0,y0,z0; + FFT_SCALAR ux,uy,uz; + FFT_SCALAR v0x,v1x,v2x,v3x,v4x,v5x; + FFT_SCALAR v0y,v1y,v2y,v3y,v4y,v5y; + FFT_SCALAR v0z,v1z,v2z,v3z,v4z,v5z; + + // loop over my charges, interpolate from nearby grid points + // (nx,ny,nz) = global coords of grid pt to "lower left" of charge + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + + double **mu = atom->mu; + double **x = atom->x; + + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) { + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + ux = uy = uz = ZEROF; + v0x = v1x = v2x = v3x = v4x = v5x = ZEROF; + v0y = v1y = v2y = v3y = v4y = v5y = ZEROF; + v0z = v1z = v2z = v3z = v4z = v5z = ZEROF; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + z0 = rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + y0 = z0*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + x0 = y0*rho1d[0][l]; + if (eflag_atom) { + ux += x0*ux_brick_dipole[mz][my][mx]; + uy += x0*uy_brick_dipole[mz][my][mx]; + uz += x0*uz_brick_dipole[mz][my][mx]; + } + if (vflag_atom) { + v0x += x0*v0x_brick_dipole[mz][my][mx]; + v1x += x0*v1x_brick_dipole[mz][my][mx]; + v2x += x0*v2x_brick_dipole[mz][my][mx]; + v3x += x0*v3x_brick_dipole[mz][my][mx]; + v4x += x0*v4x_brick_dipole[mz][my][mx]; + v5x += x0*v5x_brick_dipole[mz][my][mx]; + v0y += x0*v0y_brick_dipole[mz][my][mx]; + v1y += x0*v1y_brick_dipole[mz][my][mx]; + v2y += x0*v2y_brick_dipole[mz][my][mx]; + v3y += x0*v3y_brick_dipole[mz][my][mx]; + v4y += x0*v4y_brick_dipole[mz][my][mx]; + v5y += x0*v5y_brick_dipole[mz][my][mx]; + v0z += x0*v0z_brick_dipole[mz][my][mx]; + v1z += x0*v1z_brick_dipole[mz][my][mx]; + v2z += x0*v2z_brick_dipole[mz][my][mx]; + v3z += x0*v3z_brick_dipole[mz][my][mx]; + v4z += x0*v4z_brick_dipole[mz][my][mx]; + v5z += x0*v5z_brick_dipole[mz][my][mx]; + } + } + } + } + + if (eflag_atom) eatom[i] += mu[i][0]*ux + mu[i][1]*uy + mu[i][2]*uz; + if (vflag_atom) { + vatom[i][0] += mu[i][0]*v0x + mu[i][1]*v0y + mu[i][2]*v0z; + vatom[i][1] += mu[i][0]*v1x + mu[i][1]*v1y + mu[i][2]*v1z; + vatom[i][2] += mu[i][0]*v2x + mu[i][1]*v2y + mu[i][2]*v2z; + vatom[i][3] += mu[i][0]*v3x + mu[i][1]*v3y + mu[i][2]*v3z; + vatom[i][4] += mu[i][0]*v4x + mu[i][1]*v4y + mu[i][2]*v4z; + vatom[i][5] += mu[i][0]*v5x + mu[i][1]*v5y + mu[i][2]*v5z; + } + } +} + +/* ---------------------------------------------------------------------- + pack own values to buf to send to another proc +------------------------------------------------------------------------- */ + +void PPPMDipole::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) +{ + int n = 0; + + if (flag == FORWARD_MU) { + FFT_SCALAR *src_ux = &ux_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_uy = &uy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_uz = &uz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxx = &vdxx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vyy = &vdyy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vzz = &vdzz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxy = &vdxy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxz = &vdxz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vyz = &vdyz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + for (int i = 0; i < nlist; i++) { + buf[n++] = src_ux[list[i]]; + buf[n++] = src_uy[list[i]]; + buf[n++] = src_uz[list[i]]; + buf[n++] = src_vxx[list[i]]; + buf[n++] = src_vyy[list[i]]; + buf[n++] = src_vzz[list[i]]; + buf[n++] = src_vxy[list[i]]; + buf[n++] = src_vxz[list[i]]; + buf[n++] = src_vyz[list[i]]; + } + } else if (flag == FORWARD_MU_PERATOM) { + FFT_SCALAR *v0xsrc = &v0x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1xsrc = &v1x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2xsrc = &v2x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3xsrc = &v3x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4xsrc = &v4x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5xsrc = &v5x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0ysrc = &v0y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1ysrc = &v1y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2ysrc = &v2y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3ysrc = &v3y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4ysrc = &v4y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5ysrc = &v5y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0zsrc = &v0z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1zsrc = &v1z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2zsrc = &v2z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3zsrc = &v3z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4zsrc = &v4z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5zsrc = &v5z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + for (int i = 0; i < nlist; i++) { + buf[n++] = v0xsrc[list[i]]; + buf[n++] = v1xsrc[list[i]]; + buf[n++] = v2xsrc[list[i]]; + buf[n++] = v3xsrc[list[i]]; + buf[n++] = v4xsrc[list[i]]; + buf[n++] = v5xsrc[list[i]]; + buf[n++] = v0ysrc[list[i]]; + buf[n++] = v1ysrc[list[i]]; + buf[n++] = v2ysrc[list[i]]; + buf[n++] = v3ysrc[list[i]]; + buf[n++] = v4ysrc[list[i]]; + buf[n++] = v5ysrc[list[i]]; + buf[n++] = v0zsrc[list[i]]; + buf[n++] = v1zsrc[list[i]]; + buf[n++] = v2zsrc[list[i]]; + buf[n++] = v3zsrc[list[i]]; + buf[n++] = v4zsrc[list[i]]; + buf[n++] = v5zsrc[list[i]]; + } + } +} + +/* ---------------------------------------------------------------------- + unpack another proc's own values from buf and set own ghost values +------------------------------------------------------------------------- */ + +void PPPMDipole::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) +{ + int n = 0; + + if (flag == FORWARD_MU) { + FFT_SCALAR *dest_ux = &ux_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_uy = &uy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_uz = &uz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxx = &vdxx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vyy = &vdyy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vzz = &vdzz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxy = &vdxy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxz = &vdxz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vyz = &vdyz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + for (int i = 0; i < nlist; i++) { + dest_ux[list[i]] = buf[n++]; + dest_uy[list[i]] = buf[n++]; + dest_uz[list[i]] = buf[n++]; + dest_vxx[list[i]] = buf[n++]; + dest_vyy[list[i]] = buf[n++]; + dest_vzz[list[i]] = buf[n++]; + dest_vxy[list[i]] = buf[n++]; + dest_vxz[list[i]] = buf[n++]; + dest_vyz[list[i]] = buf[n++]; + } + } else if (flag == FORWARD_MU_PERATOM) { + FFT_SCALAR *v0xsrc = &v0x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1xsrc = &v1x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2xsrc = &v2x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3xsrc = &v3x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4xsrc = &v4x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5xsrc = &v5x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0ysrc = &v0y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1ysrc = &v1y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2ysrc = &v2y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3ysrc = &v3y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4ysrc = &v4y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5ysrc = &v5y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0zsrc = &v0z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1zsrc = &v1z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2zsrc = &v2z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3zsrc = &v3z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4zsrc = &v4z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5zsrc = &v5z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + for (int i = 0; i < nlist; i++) { + v0xsrc[list[i]] = buf[n++]; + v1xsrc[list[i]] = buf[n++]; + v2xsrc[list[i]] = buf[n++]; + v3xsrc[list[i]] = buf[n++]; + v4xsrc[list[i]] = buf[n++]; + v5xsrc[list[i]] = buf[n++]; + v0ysrc[list[i]] = buf[n++]; + v1ysrc[list[i]] = buf[n++]; + v2ysrc[list[i]] = buf[n++]; + v3ysrc[list[i]] = buf[n++]; + v4ysrc[list[i]] = buf[n++]; + v5ysrc[list[i]] = buf[n++]; + v0zsrc[list[i]] = buf[n++]; + v1zsrc[list[i]] = buf[n++]; + v2zsrc[list[i]] = buf[n++]; + v3zsrc[list[i]] = buf[n++]; + v4zsrc[list[i]] = buf[n++]; + v5zsrc[list[i]] = buf[n++]; + } + } +} + +/* ---------------------------------------------------------------------- + pack ghost values into buf to send to another proc +------------------------------------------------------------------------- */ + +void PPPMDipole::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) +{ + int n = 0; + if (flag == REVERSE_MU) { + FFT_SCALAR *src_dipole0 = &densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_dipole1 = &densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_dipole2 = &densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + for (int i = 0; i < nlist; i++) { + buf[n++] = src_dipole0[list[i]]; + buf[n++] = src_dipole1[list[i]]; + buf[n++] = src_dipole2[list[i]]; + } + } +} + +/* ---------------------------------------------------------------------- + unpack another proc's ghost values from buf and add to own values +------------------------------------------------------------------------- */ + +void PPPMDipole::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) +{ + int n = 0; + if (flag == REVERSE_MU) { + FFT_SCALAR *dest_dipole0 = &densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_dipole1 = &densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_dipole2 = &densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + for (int i = 0; i < nlist; i++) { + dest_dipole0[list[i]] += buf[n++]; + dest_dipole1[list[i]] += buf[n++]; + dest_dipole2[list[i]] += buf[n++]; + } + } +} + +/* ---------------------------------------------------------------------- + Slab-geometry correction term to dampen inter-slab interactions between + periodically repeating slabs. Yields good approximation to 2D Ewald if + adequate empty space is left between repeating slabs (J. Chem. Phys. + 111, 3155). Slabs defined here to be parallel to the xy plane. Also + extended to non-neutral systems (J. Chem. Phys. 131, 094107). +------------------------------------------------------------------------- */ + +void PPPMDipole::slabcorr() +{ + // compute local contribution to global dipole moment + + double **x = atom->x; + double zprd = domain->zprd; + int nlocal = atom->nlocal; + + double dipole = 0.0; + double **mu = atom->mu; + for (int i = 0; i < nlocal; i++) dipole += mu[i][2]; + + // sum local contributions to get global dipole moment + + double dipole_all; + MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world); + + // need to make non-neutral systems and/or + // per-atom energy translationally invariant + + if (eflag_atom || fabs(qsum) > SMALL) { + + error->all(FLERR,"Cannot (yet) use kspace slab correction with " + "long-range dipoles and non-neutral systems or per-atom energy"); + } + + // compute corrections + + const double e_slabcorr = MY_2PI*(dipole_all*dipole_all/12.0)/volume; + const double qscale = qqrd2e * scale; + + if (eflag_global) energy += qscale * e_slabcorr; + + // per-atom energy + + if (eflag_atom) { + double efact = qscale * MY_2PI/volume/12.0; + for (int i = 0; i < nlocal; i++) + eatom[i] += efact * mu[i][2]*dipole_all; + } + + // add on torque corrections + + if (atom->torque) { + double ffact = qscale * (-4.0*MY_PI/volume); + double **mu = atom->mu; + double **torque = atom->torque; + for (int i = 0; i < nlocal; i++) { + torque[i][0] += ffact * dipole_all * mu[i][1]; + torque[i][1] += -ffact * dipole_all * mu[i][0]; + } + } +} + +/* ---------------------------------------------------------------------- + perform and time the 1d FFTs required for N timesteps +------------------------------------------------------------------------- */ + +int PPPMDipole::timing_1d(int n, double &time1d) +{ + double time1,time2; + + for (int i = 0; i < 2*nfft_both; i++) work1[i] = ZEROF; + + MPI_Barrier(world); + time1 = MPI_Wtime(); + + for (int i = 0; i < n; i++) { + fft1->timing1d(work1,nfft_both,1); + fft1->timing1d(work1,nfft_both,1); + fft1->timing1d(work1,nfft_both,1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + fft2->timing1d(work1,nfft_both,-1); + } + + MPI_Barrier(world); + time2 = MPI_Wtime(); + time1d = time2 - time1; + + return 12; +} + +/* ---------------------------------------------------------------------- + perform and time the 3d FFTs required for N timesteps +------------------------------------------------------------------------- */ + +int PPPMDipole::timing_3d(int n, double &time3d) +{ + double time1,time2; + + for (int i = 0; i < 2*nfft_both; i++) work1[i] = ZEROF; + + MPI_Barrier(world); + time1 = MPI_Wtime(); + + for (int i = 0; i < n; i++) { + fft1->compute(work1,work1,1); + fft1->compute(work1,work1,1); + fft1->compute(work1,work1,1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + fft2->compute(work1,work1,-1); + } + + MPI_Barrier(world); + time2 = MPI_Wtime(); + time3d = time2 - time1; + + return 12; +} + +/* ---------------------------------------------------------------------- + memory usage of local arrays +------------------------------------------------------------------------- */ + +double PPPMDipole::memory_usage() +{ + double bytes = nmax*3 * sizeof(double); + int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) * + (nzhi_out-nzlo_out+1); + bytes += 6 * nfft_both * sizeof(double); // vg + bytes += nfft_both * sizeof(double); // greensfn + bytes += nfft_both*5 * sizeof(FFT_SCALAR); // work*2*2 + bytes += 9 * nbrick * sizeof(FFT_SCALAR); // ubrick*3 + vdbrick*6 + bytes += nfft_both*7 * sizeof(FFT_SCALAR); //density_ffx*3 + work*2*2 + + if (peratom_allocate_flag) + bytes += 21 * nbrick * sizeof(FFT_SCALAR); + + if (cg_dipole) bytes += cg_dipole->memory_usage(); + if (cg_peratom_dipole) bytes += cg_peratom_dipole->memory_usage(); + + return bytes; +} + +/* ---------------------------------------------------------------------- + compute musum,musqsum,mu2 + called initially, when particle count changes, when dipoles are changed +------------------------------------------------------------------------- */ + +void PPPMDipole::musum_musq() +{ + const int nlocal = atom->nlocal; + + musum = musqsum = mu2 = 0.0; + if (atom->mu_flag) { + double** mu = atom->mu; + double musum_local(0.0), musqsum_local(0.0); + + for (int i = 0; i < nlocal; i++) { + musum_local += mu[i][0] + mu[i][1] + mu[i][2]; + musqsum_local += mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]; + } + + MPI_Allreduce(&musum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&musqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); + + mu2 = musqsum * force->qqrd2e; + } + + if (mu2 == 0 && comm->me == 0) + error->all(FLERR,"Using kspace solver PPPMDipole on system with no dipoles"); +} \ No newline at end of file diff --git a/src/KSPACE/pppm_spin.h b/src/KSPACE/pppm_spin.h new file mode 100644 index 0000000000..4d6906f974 --- /dev/null +++ b/src/KSPACE/pppm_spin.h @@ -0,0 +1,213 @@ +/* -*- 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 KSPACE_CLASS + +KSpaceStyle(pppm/dipole,PPPMDipole) + +#else + +#ifndef LMP_PPPM_DIPOLE_H +#define LMP_PPPM_DIPOLE_H + +#include "pppm.h" + +namespace LAMMPS_NS { + +class PPPMDipole : public PPPM { + public: + PPPMDipole(class LAMMPS *, int, char **); + virtual ~PPPMDipole(); + void init(); + void setup(); + void setup_grid(); + void compute(int, int); + int timing_1d(int, double &); + int timing_3d(int, double &); + double memory_usage(); + + protected: + void set_grid_global(); + double newton_raphson_f(); + + void allocate(); + void allocate_peratom(); + void deallocate(); + void deallocate_peratom(); + void compute_gf_denom(); + + void slabcorr(); + + // grid communication + + void pack_forward(int, FFT_SCALAR *, int, int *); + void unpack_forward(int, FFT_SCALAR *, int, int *); + void pack_reverse(int, FFT_SCALAR *, int, int *); + void unpack_reverse(int, FFT_SCALAR *, int, int *); + + // dipole + + FFT_SCALAR ***densityx_brick_dipole,***densityy_brick_dipole,***densityz_brick_dipole; + FFT_SCALAR ***vdxx_brick_dipole,***vdyy_brick_dipole,***vdzz_brick_dipole; + FFT_SCALAR ***vdxy_brick_dipole,***vdxz_brick_dipole,***vdyz_brick_dipole; + FFT_SCALAR ***ux_brick_dipole,***uy_brick_dipole,***uz_brick_dipole; + FFT_SCALAR ***v0x_brick_dipole,***v1x_brick_dipole,***v2x_brick_dipole; + FFT_SCALAR ***v3x_brick_dipole,***v4x_brick_dipole,***v5x_brick_dipole; + FFT_SCALAR ***v0y_brick_dipole,***v1y_brick_dipole,***v2y_brick_dipole; + FFT_SCALAR ***v3y_brick_dipole,***v4y_brick_dipole,***v5y_brick_dipole; + FFT_SCALAR ***v0z_brick_dipole,***v1z_brick_dipole,***v2z_brick_dipole; + FFT_SCALAR ***v3z_brick_dipole,***v4z_brick_dipole,***v5z_brick_dipole; + FFT_SCALAR *work3,*work4; + FFT_SCALAR *densityx_fft_dipole,*densityy_fft_dipole,*densityz_fft_dipole; + class GridComm *cg_dipole; + class GridComm *cg_peratom_dipole; + int only_dipole_flag; + double musum,musqsum,mu2; + double find_gewald_dipole(double, double, bigint, double, double); + double newton_raphson_f_dipole(double, double, bigint, double, double); + double derivf_dipole(double, double, bigint, double, double); + double compute_df_kspace_dipole(); + double compute_qopt_dipole(); + void compute_gf_dipole(); + void make_rho_dipole(); + void brick2fft_dipole(); + void poisson_ik_dipole(); + void poisson_peratom_dipole(); + void fieldforce_ik_dipole(); + void fieldforce_peratom_dipole(); + double final_accuracy_dipole(); + void musum_musq(); + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Cannot (yet) use charges with Kspace style PPPMDipole + +Charge-dipole interactions are not yet implemented in PPPMDipole so this +feature is not yet supported. + +E: Must redefine kspace_style after changing to triclinic box + +Self-explanatory. + +E: Kspace style requires atom attribute mu + +The atom style defined does not have this attribute. + +E: Cannot (yet) use kspace_modify diff ad with dipoles + +This feature is not yet supported. + +E: Cannot (yet) use 'electron' units with dipoles + +This feature is not yet supported. + +E: Cannot yet use triclinic cells with PPPMDipole + +This feature is not yet supported. + +E: Cannot yet use TIP4P with PPPMDipole + +This feature is not yet supported. + +E: Cannot use nonperiodic boundaries with PPPM + +For kspace style pppm, all 3 dimensions must have periodic boundaries +unless you use the kspace_modify command to define a 2d slab with a +non-periodic z dimension. + +E: Incorrect boundaries with slab PPPM + +Must have periodic x,y dimensions and non-periodic z dimension to use +2d slab option with PPPM. + +E: PPPM order cannot be < 2 or > than %d + +This is a limitation of the PPPM implementation in LAMMPS. + +E: KSpace style is incompatible with Pair style + +Setting a kspace style requires that a pair style with matching +long-range dipole components be used. + +W: Reducing PPPM order b/c stencil extends beyond nearest neighbor processor + +This may lead to a larger grid than desired. See the kspace_modify overlap +command to prevent changing of the PPPM order. + +E: PPPM order < minimum allowed order + +The default minimum order is 2. This can be reset by the +kspace_modify minorder command. + +E: PPPM grid stencil extends beyond nearest neighbor processor + +This is not allowed if the kspace_modify overlap setting is no. + +E: KSpace accuracy must be > 0 + +The kspace accuracy designated in the input must be greater than zero. + +E: Could not compute grid size + +The code is unable to compute a grid size consistent with the desired +accuracy. This error should not occur for typical problems. Please +send an email to the developers. + +E: PPPM grid is too large + +The global PPPM grid is larger than OFFSET in one or more dimensions. +OFFSET is currently set to 4096. You likely need to decrease the +requested accuracy. + +E: Could not compute g_ewald + +The Newton-Raphson solver failed to converge to a good value for +g_ewald. This error should not occur for typical problems. Please +send an email to the developers. + +E: Non-numeric box dimensions - simulation unstable + +The box size has apparently blown up. + +E: Out of range atoms - cannot compute PPPM + +One or more atoms are attempting to map their charge to a PPPM grid +point that is not owned by a processor. This is likely for one of two +reasons, both of them bad. First, it may mean that an atom near the +boundary of a processor's sub-domain has moved more than 1/2 the +"neighbor skin distance"_neighbor.html without neighbor lists being +rebuilt and atoms being migrated to new processors. This also means +you may be missing pairwise interactions that need to be computed. +The solution is to change the re-neighboring criteria via the +"neigh_modify"_neigh_modify command. The safest settings are "delay 0 +every 1 check yes". Second, it may mean that an atom has moved far +outside a processor's sub-domain or even the entire simulation box. +This indicates bad physics, e.g. due to highly overlapping atoms, too +large a timestep, etc. + +E: Using kspace solver PPPMDipole on system with no dipoles + +Must have non-zero dipoles with PPPMDipole. + +E: Must use kspace_modify gewald for system with no dipoles + +Self-explanatory. + +*/ diff --git a/src/SPIN/pair_spin_long.cpp b/src/SPIN/pair_spin_long.cpp new file mode 100644 index 0000000000..66b684ae1d --- /dev/null +++ b/src/SPIN/pair_spin_long.cpp @@ -0,0 +1,550 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + www.cs.sandia.gov/~sjplimp/lammps.html + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + 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: Julien Tranchida (SNL) + Stan Moore (SNL) + + Please cite the related publication: + Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). + Massively parallel symplectic algorithm for coupled magnetic spin dynamics + and molecular dynamics. arXiv preprint arXiv:1801.10233. +------------------------------------------------------------------------- */ + + +#include +#include +#include +#include +#include "pair_spin_long.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "fix_nve_spin.h" +#include "force.h" +#include "kspace.h" +#include "math_const.h" +#include "memory.h" +#include "modify.h" +#include "error.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace MathConst; + +#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 + +/* ---------------------------------------------------------------------- */ + +PairSpinLong::PairSpinLong(LAMMPS *lmp) : PairSpin(lmp), +lockfixnvespin(NULL) +{ + single_enable = 0; + ewaldflag = pppmflag = 1; + respa_enable = 0; + no_virial_fdotr_compute = 1; + lattice_flag = 0; + + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairSpinLong::~PairSpinLong() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + } +} + +/* ---------------------------------------------------------------------- */ + +void PairSpinLong::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double r,rinv,r2inv,rsq; + double grij,expm2,t,erfc; + double bij[4]; + double evdwl,ecoul; + double xi[3],rij[3]; + double spi[4],spj[4],fi[3],fmi[3]; + double pre1,pre2,pre3; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + double **fm = atom->fm; + double **sp = atom->sp; + 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; + + pre1 = 2.0 * g_ewald / MY_PIS; + pre2 = 4.0 * pow(g_ewald,3.0) / MY_PIS; + pre3 = 8.0 * pow(g_ewald,5.0) / MY_PIS; + + // computation of the exchange interaction + // loop over atoms and their neighbors + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spi[3] = sp[i][3]; + itype = type[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + spj[3] = sp[j][3]; + + evdwl = 0.0; + + fi[0] = fi[1] = fi[2] = 0.0; + fmi[0] = fmi[1] = fmi[2] = 0.0; + bij[0] = bij[1] = bij[2] = bij[3] = 0.0; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + + if (rsq < cut_spinsq) { + 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; + + bij[0] = erfc * rinv; + bij[1] = (bij[0] + pre1*expm2) * r2inv; + bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + + compute_long(i,j,rij,bij,fmi,spi,spj); + compute_long_mech(i,j,rij,bij,fmi,spi,spj); + + } + } + + // force accumulation + + f[i][0] += fi[0] * mub2mu0; + f[i][1] += fi[1] * mub2mu0; + f[i][2] += fi[2] * mub2mu0; + fm[i][0] += fmi[0] * mub2mu0hbinv; + fm[i][1] += fmi[1] * mub2mu0hbinv; + fm[i][2] += fmi[2] * mub2mu0hbinv; + + if (newton_pair || j < nlocal) { + f[j][0] -= fi[0]; + f[j][1] -= fi[1]; + f[j][2] -= fi[2]; + } + + if (eflag) { + if (rsq <= cut_spinsq) { + evdwl -= spi[0]*fmi[0] + spi[1]*fmi[1] + + spi[2]*fmi[2]; + evdwl *= hbar; + } + } else evdwl = 0.0; + + + if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, + evdwl,ecoul,fi[0],fi[1],fi[2],rij[0],rij[1],rij[2]); + + } + } +} + +/* ---------------------------------------------------------------------- + update the pair interaction fmi acting on the spin ii +------------------------------------------------------------------------- */ + +void PairSpinLong::compute_single_pair(int ii, double fmi[3]) +{ + int i,j,jj,jnum,itype,jtype; + double r,rinv,r2inv,rsq; + double grij,expm2,t,erfc; + double bij[4],xi[3],rij[3],spi[4],spj[4]; + double pre1,pre2,pre3; + int *ilist,*jlist,*numneigh,**firstneigh; + + double **x = atom->x; + double **sp = atom->sp; + int *type = atom->type; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + pre1 = 2.0 * g_ewald / MY_PIS; + pre2 = 4.0 * pow(g_ewald,3.0) / MY_PIS; + pre3 = 8.0 * pow(g_ewald,5.0) / MY_PIS; + + // computation of the exchange interaction + // loop over neighbors of atom i + + i = ilist[ii]; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spi[3] = sp[i][3]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + itype = type[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + spj[3] = sp[j][3]; + + fmi[0] = fmi[1] = fmi[2] = 0.0; + bij[0] = bij[1] = bij[2] = bij[3] = 0.0; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + + if (rsq < cutsq[itype][jtype]) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + + if (rsq < cut_spinsq) { + 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; + + bij[0] = erfc * rinv; + bij[1] = (bij[0] + pre1*expm2) * r2inv; + bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + + compute_long(i,j,rij,bij,fmi,spi,spj); + + } + } + } + + // force accumulation + + fmi[0] *= mub2mu0hbinv; + fmi[1] *= mub2mu0hbinv; + fmi[2] *= mub2mu0hbinv; +} + +/* ---------------------------------------------------------------------- + compute exchange interaction between spins i and j +------------------------------------------------------------------------- */ + +void PairSpinLong::compute_long(int i, int j, double rij[3], + double bij[4], double fmi[3], double spi[4], double spj[4]) +{ + double sjdotr; + double b1,b2,gigj; + + gigj = spi[3] * spj[3]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + b1 = bij[1]; + b2 = bij[2]; + + fmi[0] += gigj * (b2 * sjdotr *rij[0] - b1 * spj[0]); + fmi[1] += gigj * (b2 * sjdotr *rij[1] - b1 * spj[1]); + fmi[2] += gigj * (b2 * sjdotr *rij[2] - b1 * spj[2]); +} + +/* ---------------------------------------------------------------------- + compute the mechanical force due to the exchange interaction between atom i and atom j +------------------------------------------------------------------------- */ + +void PairSpinLong::compute_long_mech(int i, int j, double rij[3], + double bij[4], double fi[3], double spi[3], double spj[3]) +{ + double sdots,sidotr,sjdotr,b2,b3; + double g1,g2,g1b2_g2b3,gigj; + + gigj = spi[3] * spj[3]; + sdots = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; + sidotr = spi[0]*rij[0] + spi[1]*rij[1] + spi[2]*rij[2]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + b2 = bij[2]; + b3 = bij[3]; + g1 = sdots; + g2 = -sidotr*sjdotr; + g1b2_g2b3 = g1*b2 + g2*b3; + + fi[0] += gigj * (rij[0] * g1b2_g2b3 + + b2 * (sjdotr*spi[0] + sidotr*spj[0])); + fi[1] += gigj * (rij[1] * g1b2_g2b3 + + b2 * (sjdotr*spi[1] + sidotr*spj[1])); + fi[2] += gigj * (rij[2] * g1b2_g2b3 + + b2 * (sjdotr*spi[2] + sidotr*spj[2])); +} + + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairSpinLong::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"); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairSpinLong::settings(int narg, char **arg) +{ + if (narg < 1 || narg > 2) + error->all(FLERR,"Incorrect args in pair_style command"); + + if (strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"Spin simulations require metal unit style"); + + cut_spin = force->numeric(FLERR,arg[0]); + +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairSpinLong::coeff(int narg, char **arg) +{ + if (narg < 4 || narg > 5) + error->all(FLERR,"Incorrect args for pair coefficients"); + if (!allocated) allocate(); + + // check if args correct + + if (strcmp(arg[2],"long") != 0) + error->all(FLERR,"Incorrect args in pair_style command"); + if (narg != 3) + error->all(FLERR,"Incorrect args in pair_style command"); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + 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 PairSpinLong::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + double cut = cut_spin; + return cut; +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSpinLong::init_style() +{ + if (!atom->sp_flag) + error->all(FLERR,"Pair spin requires atom/spin style"); + + // need a full neighbor list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + + // checking if nve/spin is a listed fix + + int ifix = 0; + while (ifix < modify->nfix) { + if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + ifix++; + } + if (ifix == modify->nfix) + error->all(FLERR,"pair/spin style requires nve/spin"); + + // get the lattice_flag from nve/spin + + for (int i = 0; i < modify->nfix; i++) { + if (strcmp(modify->fix[i]->style,"nve/spin") == 0) { + lockfixnvespin = (FixNVESpin *) modify->fix[i]; + lattice_flag = lockfixnvespin->lattice_flag; + } + } + + // insure use of KSpace long-range solver, set g_ewald + + if (force->kspace == NULL) + error->all(FLERR,"Pair style requires a KSpace style"); + + g_ewald = force->kspace->g_ewald; + + cut_spinsq = cut_spin * cut_spin; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairSpinLong::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); + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairSpinLong::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); + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairSpinLong::write_restart_settings(FILE *fp) +{ + fwrite(&cut_spin,sizeof(double),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairSpinLong::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_spin,sizeof(double),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&cut_spin,1,MPI_DOUBLE,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); +} + +/* ---------------------------------------------------------------------- */ + +void *PairSpinLong::extract(const char *str, int &dim) +{ + if (strcmp(str,"cut") == 0) { + dim = 0; + return (void *) &cut_spin; + } else if (strcmp(str,"cut_coul") == 0) { + dim = 0; + return (void *) &cut_spin; + } else if (strcmp(str,"ewald_order") == 0) { + ewald_order = 0; + ewald_order |= 1<<1; + ewald_order |= 1<<3; + dim = 0; + return (void *) &ewald_order; + } else if (strcmp(str,"ewald_mix") == 0) { + dim = 0; + return (void *) &mix_flag; + } + return NULL; +} diff --git a/src/SPIN/pair_spin_long.h b/src/SPIN/pair_spin_long.h new file mode 100644 index 0000000000..867b771f74 --- /dev/null +++ b/src/SPIN/pair_spin_long.h @@ -0,0 +1,97 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + www.cs.sandia.gov/~sjplimp/lammps.html + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + 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(spin/long,PairSpinLong) + +#else + +#ifndef LMP_PAIR_SPIN_LONG_H +#define LMP_PAIR_SPIN_LONG_H + +#include "pair_spin.h" + +namespace LAMMPS_NS { + +class PairSpinLong : public PairSpin { + public: + double cut_coul; + double **sigma; + + PairSpinLong(class LAMMPS *); + ~PairSpinLong(); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + void init_style(); + void *extract(const char *, int &); + + void compute(int, int); + void compute_single_pair(int, double *); + + void compute_long(int, int, double *, double *, double *, + double *, double *); + void compute_long_mech(int, int, double *, double *, double *, + double *, double *); + + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + + protected: + double hbar; // reduced Planck's constant + double mub; // Bohr's magneton + double mu_0; // vacuum permeability + double mub2mu0; // prefactor for mech force + double mub2mu0hbinv; // prefactor for mag force + double cut_spin, cut_spinsq; + + double g_ewald; + int ewald_order; + + int lattice_flag; // flag for mech force computation + class FixNVESpin *lockfixnvespin; // ptr for setups + + void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Incorrect args in pair_style command + +Self-explanatory. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair dipole/long requires atom attributes q, mu, torque + +The atom style defined does not have these attributes. + +E: Cannot (yet) use 'electron' units with dipoles + +This feature is not yet supported. + +E: Pair style requires a KSpace style + +No kspace style is defined. + +*/ diff --git a/src/kspace.cpp b/src/kspace.cpp index fc8b12288b..da606bbf3d 100644 --- a/src/kspace.cpp +++ b/src/kspace.cpp @@ -268,7 +268,7 @@ void KSpace::ev_setup(int eflag, int vflag, int alloc) called initially, when particle count changes, when charges are changed ------------------------------------------------------------------------- */ -void KSpace::qsum_qsq() +void KSpace::qsum_qsq(int warning_flag) { const double * const q = atom->q; const int nlocal = atom->nlocal; @@ -285,7 +285,7 @@ void KSpace::qsum_qsq() MPI_Allreduce(&qsum_local,&qsum,1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&qsqsum_local,&qsqsum,1,MPI_DOUBLE,MPI_SUM,world); - if ((qsqsum == 0.0) && (comm->me == 0) && warn_nocharge) { + if ((qsqsum == 0.0) && (comm->me == 0) && warn_nocharge && warning_flag) { error->warning(FLERR,"Using kspace solver on system with no charge"); warn_nocharge = 0; } diff --git a/src/kspace.h b/src/kspace.h index 28c7bcef2a..55ace5aa71 100644 --- a/src/kspace.h +++ b/src/kspace.h @@ -108,7 +108,7 @@ class KSpace : protected Pointers { // public so can be called by commands that change charge - void qsum_qsq(); + void qsum_qsq(int warning_flag = 1); // general child-class methods -- GitLab From e1ab38439b9eae0ced06b796613f0e2b17f1fe1c Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 14 Aug 2018 17:09:44 -0600 Subject: [PATCH 0033/1243] Commit2 JT 081418 - converted pppm_dipole toward spin quantities - need to check if can handle ferrimagnets --- src/KSPACE/pppm_spin.cpp | 983 ++++++++++++++++++++------------------- src/KSPACE/pppm_spin.h | 86 ++-- 2 files changed, 558 insertions(+), 511 deletions(-) diff --git a/src/KSPACE/pppm_spin.cpp b/src/KSPACE/pppm_spin.cpp index 32e91cc9b2..c51de8d023 100644 --- a/src/KSPACE/pppm_spin.cpp +++ b/src/KSPACE/pppm_spin.cpp @@ -13,6 +13,7 @@ /* ---------------------------------------------------------------------- Contributing author: Stan Moore (SNL) + Julien Tranchida (SNL) ------------------------------------------------------------------------- */ #include @@ -20,7 +21,7 @@ #include #include #include -#include "pppm_dipole.h" +#include "pppm_spin.h" #include "atom.h" #include "comm.h" #include "gridcomm.h" @@ -49,8 +50,8 @@ using namespace MathSpecial; #define SMALL 0.00001 #define EPS_HOC 1.0e-7 -enum{REVERSE_MU}; -enum{FORWARD_MU,FORWARD_MU_PERATOM}; +enum{REVERSE_SP}; +enum{FORWARD_SP,FORWARD_SP_PERATOM}; #ifdef FFT_SINGLE #define ZEROF 0.0f @@ -62,34 +63,34 @@ enum{FORWARD_MU,FORWARD_MU_PERATOM}; /* ---------------------------------------------------------------------- */ -PPPMDipole::PPPMDipole(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg), - densityx_brick_dipole(NULL), densityy_brick_dipole(NULL), - densityz_brick_dipole(NULL), ux_brick_dipole(NULL), - uy_brick_dipole(NULL), uz_brick_dipole(NULL), vdxx_brick_dipole(NULL), - vdxy_brick_dipole(NULL), vdyy_brick_dipole(NULL), - vdxz_brick_dipole(NULL), vdyz_brick_dipole(NULL), - vdzz_brick_dipole(NULL), v0x_brick_dipole(NULL), v1x_brick_dipole(NULL), - v2x_brick_dipole(NULL), v3x_brick_dipole(NULL), v4x_brick_dipole(NULL), - v5x_brick_dipole(NULL), v0y_brick_dipole(NULL), v1y_brick_dipole(NULL), - v2y_brick_dipole(NULL), v3y_brick_dipole(NULL), v4y_brick_dipole(NULL), - v5y_brick_dipole(NULL), v0z_brick_dipole(NULL), v1z_brick_dipole(NULL), - v2z_brick_dipole(NULL), v3z_brick_dipole(NULL), v4z_brick_dipole(NULL), - v5z_brick_dipole(NULL), work3(NULL), work4(NULL), - densityx_fft_dipole(NULL), densityy_fft_dipole(NULL), - densityz_fft_dipole(NULL) +PPPMSpin::PPPMSpin(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg), + densityx_brick_spin(NULL), densityy_brick_spin(NULL), + densityz_brick_spin(NULL), ux_brick_spin(NULL), + uy_brick_spin(NULL), uz_brick_spin(NULL), vdxx_brick_spin(NULL), + vdxy_brick_spin(NULL), vdyy_brick_spin(NULL), + vdxz_brick_spin(NULL), vdyz_brick_spin(NULL), + vdzz_brick_spin(NULL), v0x_brick_spin(NULL), v1x_brick_spin(NULL), + v2x_brick_spin(NULL), v3x_brick_spin(NULL), v4x_brick_spin(NULL), + v5x_brick_spin(NULL), v0y_brick_spin(NULL), v1y_brick_spin(NULL), + v2y_brick_spin(NULL), v3y_brick_spin(NULL), v4y_brick_spin(NULL), + v5y_brick_spin(NULL), v0z_brick_spin(NULL), v1z_brick_spin(NULL), + v2z_brick_spin(NULL), v3z_brick_spin(NULL), v4z_brick_spin(NULL), + v5z_brick_spin(NULL), work3(NULL), work4(NULL), + densityx_fft_spin(NULL), densityy_fft_spin(NULL), + densityz_fft_spin(NULL) { - dipoleflag = 1; + spinflag = 1; group_group_enable = 0; - cg_dipole = NULL; - cg_peratom_dipole = NULL; + cg_spin = NULL; + cg_peratom_spin = NULL; } /* ---------------------------------------------------------------------- free all memory ------------------------------------------------------------------------- */ -PPPMDipole::~PPPMDipole() +PPPMSpin::~PPPMSpin() { if (copymode) return; @@ -98,26 +99,29 @@ PPPMDipole::~PPPMDipole() fft1 = NULL; fft2 = NULL; remap = NULL; - cg_dipole = NULL; + cg_spin = NULL; } /* ---------------------------------------------------------------------- called once before run ------------------------------------------------------------------------- */ -void PPPMDipole::init() +void PPPMSpin::init() { if (me == 0) { - if (screen) fprintf(screen,"PPPMDipole initialization ...\n"); - if (logfile) fprintf(logfile,"PPPMDipole initialization ...\n"); + if (screen) fprintf(screen,"PPPMSpin initialization ...\n"); + if (logfile) fprintf(logfile,"PPPMSpin initialization ...\n"); } // error check - dipoleflag = atom->mu?1:0; - qsum_qsq(0); - if (dipoleflag && q2) - error->all(FLERR,"Cannot (yet) uses charges with Kspace style PPPMDipole"); + //spinflag = atom->mu?1:0; + spinflag = atom->sp?1:0; + // no charges here, charge neutrality + //qsum_qsq(0); + // maybe change this test + if (spinflag && q2) + error->all(FLERR,"Cannot (yet) uses charges with Kspace style PPPMSpin"); triclinic_check(); @@ -125,30 +129,30 @@ void PPPMDipole::init() error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); if (domain->dimension == 2) error->all(FLERR, - "Cannot use PPPMDipole with 2d simulation"); + "Cannot use PPPMSpin with 2d simulation"); if (comm->style != 0) - error->universe_all(FLERR,"PPPMDipole can only currently be used with " + error->universe_all(FLERR,"PPPMSpin can only currently be used with " "comm_style brick"); - if (!atom->mu) error->all(FLERR,"Kspace style requires atom attribute mu"); + if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); - if (atom->mu && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" - " ad with dipoles"); + if (atom->sp && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" + " ad with spins"); - if (dipoleflag && strcmp(update->unit_style,"electron") == 0) - error->all(FLERR,"Cannot (yet) use 'electron' units with dipoles"); + if (spinflag && strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"'metal' units have to be used with spins"); if (slabflag == 0 && domain->nonperiodic > 0) - error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipole"); + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMSpin"); if (slabflag) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all(FLERR,"Incorrect boundaries with slab PPPMDipole"); + error->all(FLERR,"Incorrect boundaries with slab PPPMSpin"); } if (order < 2 || order > MAXORDER) { char str[128]; - sprintf(str,"PPPMDipole order cannot be < 2 or > than %d",MAXORDER); + sprintf(str,"PPPMSpin order cannot be < 2 or > than %d",MAXORDER); error->all(FLERR,str); } @@ -156,7 +160,7 @@ void PPPMDipole::init() triclinic = domain->triclinic; if (triclinic) - error->all(FLERR,"Cannot yet use triclinic cells with PPPMDipole"); + error->all(FLERR,"Cannot yet use triclinic cells with PPPMSpin"); pair_check(); @@ -169,17 +173,26 @@ void PPPMDipole::init() // kspace TIP4P not yet supported if (tip4pflag) - error->all(FLERR,"Cannot yet use TIP4P with PPPMDipole"); + error->all(FLERR,"Cannot yet use TIP4P with PPPMSpin"); // compute qsum & qsqsum and warn if not charge-neutral scale = 1.0; - qqrd2e = force->qqrd2e; - musum_musq(); + //qqrd2e = force->qqrd2e; + // need to define mag constants instead + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + //musum_musq(); + spsum_spsq(); natoms_original = atom->natoms; // set accuracy (force units) from accuracy_relative or accuracy_absolute + // is two_charge_force still relevant for spin systems? + if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute; else accuracy = accuracy_relative * two_charge_force; @@ -201,7 +214,7 @@ void PPPMDipole::init() while (order >= minorder) { if (iteration && me == 0) - error->warning(FLERR,"Reducing PPPMDipole order b/c stencil extends " + error->warning(FLERR,"Reducing PPPMSpin order b/c stencil extends " "beyond nearest neighbor processor"); compute_gf_denom(); @@ -222,9 +235,9 @@ void PPPMDipole::init() iteration++; } - if (order < minorder) error->all(FLERR,"PPPMDipole order < minimum allowed order"); + if (order < minorder) error->all(FLERR,"PPPMSpin order < minimum allowed order"); if (!overlap_allowed && cgtmp->ghost_overlap()) - error->all(FLERR,"PPPMDipole grid stencil extends " + error->all(FLERR,"PPPMSpin grid stencil extends " "beyond nearest neighbor processor"); if (cgtmp) delete cgtmp; @@ -234,7 +247,7 @@ void PPPMDipole::init() // calculate the final accuracy - double estimated_accuracy = final_accuracy_dipole(); + double estimated_accuracy = final_accuracy_spin(); // print stats @@ -280,10 +293,10 @@ void PPPMDipole::init() // don't invoke allocate peratom(), will be allocated when needed allocate(); - cg_dipole->ghost_notify(); - cg_dipole->setup(); + cg_spin->ghost_notify(); + cg_spin->setup(); - // pre-compute Green's function denomiator expansion + // pre-compute Green's function denominator expansion // pre-compute 1d charge distribution coefficients compute_gf_denom(); @@ -291,27 +304,27 @@ void PPPMDipole::init() } /* ---------------------------------------------------------------------- - adjust PPPMDipole coeffs, called initially and whenever volume has changed + adjust PPPMSpin coeffs, called initially and whenever volume has changed ------------------------------------------------------------------------- */ -void PPPMDipole::setup() +void PPPMSpin::setup() { // perform some checks to avoid illegal boundaries with read_data if (slabflag == 0 && domain->nonperiodic > 0) - error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipole"); + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMSpin"); if (slabflag) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all(FLERR,"Incorrect boundaries with slab PPPMDipole"); + error->all(FLERR,"Incorrect boundaries with slab PPPMSpin"); } int i,j,k,n; double *prd; // volume-dependent factors - // adjust z dimension for 2d slab PPPMDipole - // z dimension for 3d PPPMDipole is zprd since slab_volfactor = 1.0 + // adjust z dimension for 2d slab PPPMSpin + // z dimension for 3d PPPMSpin is zprd since slab_volfactor = 1.0 prd = domain->prd; double xprd = prd[0]; @@ -379,7 +392,7 @@ void PPPMDipole::setup() } } - compute_gf_dipole(); + compute_gf_spin(); } /* ---------------------------------------------------------------------- @@ -387,7 +400,7 @@ void PPPMDipole::setup() called by fix balance b/c it changed sizes of processor sub-domains ------------------------------------------------------------------------- */ -void PPPMDipole::setup_grid() +void PPPMSpin::setup_grid() { // free all arrays previously allocated @@ -404,11 +417,11 @@ void PPPMDipole::setup_grid() allocate(); - cg_dipole->ghost_notify(); - if (overlap_allowed == 0 && cg_dipole->ghost_overlap()) - error->all(FLERR,"PPPMDipole grid stencil extends " + cg_spin->ghost_notify(); + if (overlap_allowed == 0 && cg_spin->ghost_overlap()) + error->all(FLERR,"PPPMSpin grid stencil extends " "beyond nearest neighbor processor"); - cg_dipole->setup(); + cg_spin->setup(); // pre-compute Green's function denomiator expansion // pre-compute 1d charge distribution coefficients @@ -422,10 +435,10 @@ void PPPMDipole::setup_grid() } /* ---------------------------------------------------------------------- - compute the PPPMDipole long-range force, energy, virial + compute the PPPMSpin long-range force, energy, virial ------------------------------------------------------------------------- */ -void PPPMDipole::compute(int eflag, int vflag) +void PPPMSpin::compute(int eflag, int vflag) { int i,j; @@ -438,20 +451,21 @@ void PPPMDipole::compute(int eflag, int vflag) if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); - cg_peratom_dipole->ghost_notify(); - cg_peratom_dipole->setup(); + cg_peratom_spin->ghost_notify(); + cg_peratom_spin->setup(); } // if atom count has changed, update qsum and qsqsum if (atom->natoms != natoms_original) { - musum_musq(); + //musum_musq(); + spsum_spsq(); natoms_original = atom->natoms; } - // return if there are no dipoles + // return if there are no spins - if (musqsum == 0.0) return; + if (spsqsum == 0.0) return; // convert atoms from box to lamda coords @@ -462,51 +476,52 @@ void PPPMDipole::compute(int eflag, int vflag) if (atom->nmax > nmax) { memory->destroy(part2grid); nmax = atom->nmax; - memory->create(part2grid,nmax,3,"pppm_dipole:part2grid"); + memory->create(part2grid,nmax,3,"pppm_spin:part2grid"); } // find grid points for all my particles - // map my particle charge onto my local 3d density grid + // map my particle charge onto my local 3d on-grid density particle_map(); - make_rho_dipole(); + make_rho_spin(); // all procs communicate density values from their ghost cells // to fully sum contribution in their 3d bricks // remap from 3d decomposition to FFT decomposition - cg_dipole->reverse_comm(this,REVERSE_MU); - brick2fft_dipole(); + cg_spin->reverse_comm(this,REVERSE_SP); + brick2fft_spin(); // compute potential gradient on my FFT grid and // portion of e_long on this proc's FFT grid // return gradients (electric fields) in 3d brick decomposition // also performs per-atom calculations via poisson_peratom() - poisson_ik_dipole(); + poisson_ik_spin(); // all procs communicate E-field values // to fill ghost cells surrounding their 3d bricks - cg_dipole->forward_comm(this,FORWARD_MU); + cg_spin->forward_comm(this,FORWARD_SP); // extra per-atom energy/virial communication if (evflag_atom) { - cg_peratom_dipole->forward_comm(this,FORWARD_MU_PERATOM); + cg_peratom_spin->forward_comm(this,FORWARD_SP_PERATOM); } // calculate the force on my particles - fieldforce_ik_dipole(); + fieldforce_ik_spin(); // extra per-atom energy/virial communication - if (evflag_atom) fieldforce_peratom_dipole(); + if (evflag_atom) fieldforce_peratom_spin(); // sum global energy across procs and add in volume-dependent term - const double qscale = qqrd2e * scale; + //const double qscale = qqrd2e * scale; + const double spscale = mub2mu0 * scale; const double g3 = g_ewald*g_ewald*g_ewald; if (eflag_global) { @@ -515,7 +530,7 @@ void PPPMDipole::compute(int eflag, int vflag) energy = energy_all; energy *= 0.5*volume; - energy -= musqsum*2.0*g3/3.0/MY_PIS; + energy -= spsqsum*2.0*g3/3.0/MY_PIS; energy *= qscale; } @@ -531,16 +546,19 @@ void PPPMDipole::compute(int eflag, int vflag) // energy includes self-energy correction if (evflag_atom) { - double *q = atom->q; - double **mu = atom->mu; + //double *q = atom->q; + //double **mu = atom->mu; + double **sp = atom->sp; int nlocal = atom->nlocal; int ntotal = nlocal; if (eflag_atom) { for (i = 0; i < nlocal; i++) { eatom[i] *= 0.5; - eatom[i] -= (mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2])*2.0*g3/3.0/MY_PIS; - eatom[i] *= qscale; + //eatom[i] -= (mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2])*2.0*g3/3.0/MY_PIS; + eatom[i] -= (sp[i][0]*sp[i][0] + sp[i][1]*sp[i][1] + sp[i][2]*sp[i][2])*2.0*g3/3.0/MY_PIS; + //eatom[i] *= qscale; + eatom[i] *= spscale; } } @@ -559,59 +577,59 @@ void PPPMDipole::compute(int eflag, int vflag) allocate memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMDipole::allocate() +void PPPMSpin::allocate() { - memory->create3d_offset(densityx_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:densityx_brick_dipole"); - memory->create3d_offset(densityy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:densityy_brick_dipole"); - memory->create3d_offset(densityz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:densityz_brick_dipole"); - - memory->create(densityx_fft_dipole,nfft_both,"pppm_dipole:densityy_fft_dipole"); - memory->create(densityy_fft_dipole,nfft_both,"pppm_dipole:densityy_fft_dipole"); - memory->create(densityz_fft_dipole,nfft_both,"pppm_dipole:densityz_fft_dipole"); - - memory->create(greensfn,nfft_both,"pppm_dipole:greensfn"); - memory->create(work1,2*nfft_both,"pppm_dipole:work1"); - memory->create(work2,2*nfft_both,"pppm_dipole:work2"); - memory->create(work3,2*nfft_both,"pppm_dipole:work3"); - memory->create(work4,2*nfft_both,"pppm_dipole:work4"); - memory->create(vg,nfft_both,6,"pppm_dipole:vg"); - - memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm_dipole:fkx"); - memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm_dipole:fky"); - memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm_dipole:fkz"); - - memory->create3d_offset(ux_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:ux_brick_dipole"); - memory->create3d_offset(uy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:uy_brick_dipole"); - memory->create3d_offset(uz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:uz_brick_dipole"); - - memory->create3d_offset(vdxx_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:vdxx_brick_dipole"); - memory->create3d_offset(vdxy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:vdxy_brick_dipole"); - memory->create3d_offset(vdyy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:vdyy_brick_dipole"); - memory->create3d_offset(vdxz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:vdxz_brick_dipole"); - memory->create3d_offset(vdyz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:vdyz_brick_dipole"); - memory->create3d_offset(vdzz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:vdzz_brick_dipole"); + memory->create3d_offset(densityx_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:densityx_brick_spin"); + memory->create3d_offset(densityy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:densityy_brick_spin"); + memory->create3d_offset(densityz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:densityz_brick_spin"); + + memory->create(densityx_fft_spin,nfft_both,"pppm_spin:densityy_fft_spin"); + memory->create(densityy_fft_spin,nfft_both,"pppm_spin:densityy_fft_spin"); + memory->create(densityz_fft_spin,nfft_both,"pppm_spin:densityz_fft_spin"); + + memory->create(greensfn,nfft_both,"pppm_spin:greensfn"); + memory->create(work1,2*nfft_both,"pppm_spin:work1"); + memory->create(work2,2*nfft_both,"pppm_spin:work2"); + memory->create(work3,2*nfft_both,"pppm_spin:work3"); + memory->create(work4,2*nfft_both,"pppm_spin:work4"); + memory->create(vg,nfft_both,6,"pppm_spin:vg"); + + memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm_spin:fkx"); + memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm_spin:fky"); + memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm_spin:fkz"); + + memory->create3d_offset(ux_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:ux_brick_spin"); + memory->create3d_offset(uy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:uy_brick_spin"); + memory->create3d_offset(uz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:uz_brick_spin"); + + memory->create3d_offset(vdxx_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:vdxx_brick_spin"); + memory->create3d_offset(vdxy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:vdxy_brick_spin"); + memory->create3d_offset(vdyy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:vdyy_brick_spin"); + memory->create3d_offset(vdxz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:vdxz_brick_spin"); + memory->create3d_offset(vdyz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:vdyz_brick_spin"); + memory->create3d_offset(vdzz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:vdzz_brick_spin"); // summation coeffs order_allocated = order; - memory->create(gf_b,order,"pppm_dipole:gf_b"); - memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm_dipole:rho1d"); - memory->create2d_offset(drho1d,3,-order/2,order/2,"pppm_dipole:drho1d"); - memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm_dipole:rho_coeff"); + memory->create(gf_b,order,"pppm_spin:gf_b"); + memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm_spin:rho1d"); + memory->create2d_offset(drho1d,3,-order/2,order/2,"pppm_spin:drho1d"); + memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm_spin:rho_coeff"); memory->create2d_offset(drho_coeff,order,(1-order)/2,order/2, - "pppm_dipole:drho_coeff"); + "pppm_spin:drho_coeff"); // create 2 FFTs and a Remap // 1st FFT keeps data in FFT decompostion @@ -639,7 +657,7 @@ void PPPMDipole::allocate() int (*procneigh)[2] = comm->procneigh; - cg_dipole = new GridComm(lmp,world,9,3, + cg_spin = new GridComm(lmp,world,9,3, nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, procneigh[0][0],procneigh[0][1],procneigh[1][0], @@ -650,26 +668,26 @@ void PPPMDipole::allocate() deallocate memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMDipole::deallocate() +void PPPMSpin::deallocate() { - memory->destroy3d_offset(densityx_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(densityy_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(densityz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityx_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityy_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityz_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(ux_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(uy_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(uz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(ux_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(uy_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(uz_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdxx_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdxy_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdyy_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdxz_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdyz_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdzz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxx_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxy_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdyy_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxz_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdyz_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdzz_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy(densityx_fft_dipole); - memory->destroy(densityy_fft_dipole); - memory->destroy(densityz_fft_dipole); + memory->destroy(densityx_fft_spin); + memory->destroy(densityy_fft_spin); + memory->destroy(densityz_fft_spin); memory->destroy(greensfn); memory->destroy(work1); @@ -691,61 +709,61 @@ void PPPMDipole::deallocate() delete fft1; delete fft2; delete remap; - delete cg_dipole; + delete cg_spin; } /* ---------------------------------------------------------------------- allocate per-atom memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMDipole::allocate_peratom() +void PPPMSpin::allocate_peratom() { peratom_allocate_flag = 1; - memory->create3d_offset(v0x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v0x_brick_dipole"); - memory->create3d_offset(v1x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v1x_brick_dipole"); - memory->create3d_offset(v2x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v2x_brick_dipole"); - memory->create3d_offset(v3x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v3x_brick_dipole"); - memory->create3d_offset(v4x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v4x_brick_dipole"); - memory->create3d_offset(v5x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v5x_brick_dipole"); - - memory->create3d_offset(v0y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v0y_brick_dipole"); - memory->create3d_offset(v1y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v1y_brick_dipole"); - memory->create3d_offset(v2y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v2y_brick_dipole"); - memory->create3d_offset(v3y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v3y_brick_dipole"); - memory->create3d_offset(v4y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v4y_brick_dipole"); - memory->create3d_offset(v5y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v5y_brick_dipole"); - - memory->create3d_offset(v0z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v0z_brick_dipole"); - memory->create3d_offset(v1z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v1z_brick_dipole"); - memory->create3d_offset(v2z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v2z_brick_dipole"); - memory->create3d_offset(v3z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v3z_brick_dipole"); - memory->create3d_offset(v4z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v4z_brick_dipole"); - memory->create3d_offset(v5z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_dipole:v5z_brick_dipole"); + memory->create3d_offset(v0x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v0x_brick_spin"); + memory->create3d_offset(v1x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v1x_brick_spin"); + memory->create3d_offset(v2x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v2x_brick_spin"); + memory->create3d_offset(v3x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v3x_brick_spin"); + memory->create3d_offset(v4x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v4x_brick_spin"); + memory->create3d_offset(v5x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v5x_brick_spin"); + + memory->create3d_offset(v0y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v0y_brick_spin"); + memory->create3d_offset(v1y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v1y_brick_spin"); + memory->create3d_offset(v2y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v2y_brick_spin"); + memory->create3d_offset(v3y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v3y_brick_spin"); + memory->create3d_offset(v4y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v4y_brick_spin"); + memory->create3d_offset(v5y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v5y_brick_spin"); + + memory->create3d_offset(v0z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v0z_brick_spin"); + memory->create3d_offset(v1z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v1z_brick_spin"); + memory->create3d_offset(v2z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v2z_brick_spin"); + memory->create3d_offset(v3z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v3z_brick_spin"); + memory->create3d_offset(v4z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v4z_brick_spin"); + memory->create3d_offset(v5z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_spin:v5z_brick_spin"); // create ghost grid object for rho and electric field communication int (*procneigh)[2] = comm->procneigh; - cg_peratom_dipole = + cg_peratom_spin = new GridComm(lmp,world,18,1, nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, @@ -757,44 +775,44 @@ void PPPMDipole::allocate_peratom() deallocate per-atom memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMDipole::deallocate_peratom() +void PPPMSpin::deallocate_peratom() { peratom_allocate_flag = 0; - memory->destroy3d_offset(v0x_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v1x_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v2x_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v3x_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v4x_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v5x_brick_dipole,nzlo_out,nylo_out,nxlo_out); - - memory->destroy3d_offset(v0y_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v1y_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v2y_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v3y_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v4y_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v5y_brick_dipole,nzlo_out,nylo_out,nxlo_out); - - memory->destroy3d_offset(v0z_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v1z_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v2z_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v3z_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v4z_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v5z_brick_dipole,nzlo_out,nylo_out,nxlo_out); - - delete cg_peratom_dipole; + memory->destroy3d_offset(v0x_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1x_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2x_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3x_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4x_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5x_brick_spin,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(v0y_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1y_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2y_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3y_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4y_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5y_brick_spin,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(v0z_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1z_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2z_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3z_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4z_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5z_brick_spin,nzlo_out,nylo_out,nxlo_out); + + delete cg_peratom_spin; } /* ---------------------------------------------------------------------- - set global size of PPPMDipole grid = nx,ny,nz_pppm + set global size of PPPMSpin grid = nx,ny,nz_pppm used for charge accumulation, FFTs, and electric field interpolation ------------------------------------------------------------------------- */ -void PPPMDipole::set_grid_global() +void PPPMSpin::set_grid_global() { // use xprd,yprd,zprd - // adjust z dimension for 2d slab PPPMDipole - // 3d PPPMDipole just uses zprd since slab_volfactor = 1.0 + // adjust z dimension for 2d slab PPPMSpin + // 3d PPPMSpin just uses zprd since slab_volfactor = 1.0 double xprd = domain->xprd; double yprd = domain->yprd; @@ -812,14 +830,14 @@ void PPPMDipole::set_grid_global() if (!gewaldflag) { if (accuracy <= 0.0) error->all(FLERR,"KSpace accuracy must be > 0"); - if (mu2 == 0.0) - error->all(FLERR,"Must use kspace_modify gewald for systems with no dipoles"); + if (sp2 == 0.0) + error->all(FLERR,"Must use kspace_modify gewald for systems with no spins"); g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; //Try Newton Solver double g_ewald_new = - find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); + find_gewald_spin(g_ewald,cutoff,natoms,xprd*yprd*zprd,sp2); if (g_ewald_new > 0.0) g_ewald = g_ewald_new; - else error->warning(FLERR,"PPPMDipole dipole Newton solver failed, " + else error->warning(FLERR,"PPPMSpin spin Newton solver failed, " "using old method to estimate g_ewald"); } @@ -859,7 +877,7 @@ void PPPMDipole::set_grid_global() nzlo_fft = me_z*nz_pppm/npez_fft; nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1; - double df_kspace = compute_df_kspace_dipole(); + double df_kspace = compute_df_kspace_spin(); count++; @@ -884,31 +902,32 @@ void PPPMDipole::set_grid_global() h_z = zprd_slab/nz_pppm; if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET) - error->all(FLERR,"PPPMDipole grid is too large"); + error->all(FLERR,"PPPMSpin grid is too large"); } /* ---------------------------------------------------------------------- - compute estimated kspace force error for dipoles + compute estimated kspace force error for spins ------------------------------------------------------------------------- */ -double PPPMDipole::compute_df_kspace_dipole() +double PPPMSpin::compute_df_kspace_spin() { double xprd = domain->xprd; double yprd = domain->yprd; double zprd = domain->zprd; double zprd_slab = zprd*slab_volfactor; bigint natoms = atom->natoms; - double qopt = compute_qopt_dipole(); - double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); + double qopt = compute_qopt_spin(); + //double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); + double df_kspace = sqrt(qopt/natoms)*sp2/(3.0*xprd*yprd*zprd_slab); return df_kspace; } /* ---------------------------------------------------------------------- - compute qopt for dipoles with ik differentiation + compute qopt for spins with ik differentiation ------------------------------------------------------------------------- */ -double PPPMDipole::compute_qopt_dipole() +double PPPMSpin::compute_qopt_spin() { double qopt = 0.0; const double * const prd = domain->prd; @@ -979,7 +998,7 @@ double PPPMDipole::compute_qopt_dipole() dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz; dot2 = qx*qx + qy*qy + qz*qz; - //dot1 = dot1*dot1*dot1; // power of 3 for dipole forces + //dot1 = dot1*dot1*dot1; // power of 3 for spin forces //dot2 = dot2*dot2*dot2; u1 = sx*sy*sz; const double w2 = wx*wy*wz; @@ -1004,7 +1023,7 @@ double PPPMDipole::compute_qopt_dipole() pre-compute modified (Hockney-Eastwood) Coulomb Green's function ------------------------------------------------------------------------- */ -void PPPMDipole::compute_gf_dipole() +void PPPMSpin::compute_gf_spin() { const double * const prd = domain->prd; @@ -1097,7 +1116,7 @@ void PPPMDipole::compute_gf_dipole() calculate f(x) for use in Newton-Raphson solver ------------------------------------------------------------------------- */ -double PPPMDipole::newton_raphson_f() +double PPPMSpin::newton_raphson_f() { double xprd = domain->xprd; double yprd = domain->yprd; @@ -1112,19 +1131,21 @@ double PPPMDipole::newton_raphson_f() double rg6 = rg4*rg2; double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + //df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + // sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); + df_rspace = (sp2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); - df_kspace = compute_df_kspace_dipole(); + df_kspace = compute_df_kspace_spin(); return df_rspace - df_kspace; } /* ---------------------------------------------------------------------- - find g_ewald parameter for dipoles based on desired accuracy + find g_ewald parameter for spins based on desired accuracy using a Newton-Raphson solver ------------------------------------------------------------------------- */ -double PPPMDipole::find_gewald_dipole(double x, double Rc, +double PPPMSpin::find_gewald_spin(double x, double Rc, bigint natoms, double vol, double b2) { double dx,tol; @@ -1136,7 +1157,7 @@ double PPPMDipole::find_gewald_dipole(double x, double Rc, //Begin algorithm for (int i = 0; i < maxit; i++) { - dx = newton_raphson_f_dipole(x,Rc,natoms,vol,b2) / derivf_dipole(x,Rc,natoms,vol,b2); + dx = newton_raphson_f_spin(x,Rc,natoms,vol,b2) / derivf_spin(x,Rc,natoms,vol,b2); x = x - dx; //Update x if (fabs(dx) < tol) return x; if (x < 0 || x != x) // solver failed @@ -1146,10 +1167,10 @@ double PPPMDipole::find_gewald_dipole(double x, double Rc, } /* ---------------------------------------------------------------------- - calculate f(x) objective function for dipoles + calculate f(x) objective function for spins ------------------------------------------------------------------------- */ -double PPPMDipole::newton_raphson_f_dipole(double x, double Rc, bigint +double PPPMSpin::newton_raphson_f_spin(double x, double Rc, bigint natoms, double vol, double b2) { double a = Rc*x; @@ -1166,21 +1187,21 @@ natoms, double vol, double b2) } /* ---------------------------------------------------------------------- - calculate numerical derivative f'(x) of objective function for dipoles + calculate numerical derivative f'(x) of objective function for spins ------------------------------------------------------------------------- */ -double PPPMDipole::derivf_dipole(double x, double Rc, +double PPPMSpin::derivf_spin(double x, double Rc, bigint natoms, double vol, double b2) { double h = 0.000001; //Derivative step-size - return (newton_raphson_f_dipole(x + h,Rc,natoms,vol,b2) - newton_raphson_f_dipole(x,Rc,natoms,vol,b2)) / h; + return (newton_raphson_f_spin(x + h,Rc,natoms,vol,b2) - newton_raphson_f_spin(x,Rc,natoms,vol,b2)) / h; } /* ---------------------------------------------------------------------- calculate the final estimate of the accuracy ------------------------------------------------------------------------- */ -double PPPMDipole::final_accuracy_dipole() +double PPPMSpin::final_accuracy_spin() { double xprd = domain->xprd; double yprd = domain->yprd; @@ -1189,7 +1210,7 @@ double PPPMDipole::final_accuracy_dipole() bigint natoms = atom->natoms; if (natoms == 0) natoms = 1; // avoid division by zero - double df_kspace = compute_df_kspace_dipole(); + double df_kspace = compute_df_kspace_spin(); double a = cutoff*g_ewald; double rg2 = a*a; @@ -1197,7 +1218,10 @@ double PPPMDipole::final_accuracy_dipole() double rg6 = rg4*rg2; double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + //double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + // sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * + // exp(-rg2)); + double df_rspace = (sp2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); @@ -1210,10 +1234,10 @@ double PPPMDipole::final_accuracy_dipole() pre-compute Green's function denominator expansion coeffs, Gamma(2n) ------------------------------------------------------------------------- */ -void PPPMDipole::compute_gf_denom() +void PPPMSpin::compute_gf_denom() { if (gf_b) memory->destroy(gf_b); - memory->create(gf_b,order,"pppm_dipole:gf_b"); + memory->create(gf_b,order,"pppm_spin:gf_b"); int k,l,m; @@ -1239,7 +1263,7 @@ void PPPMDipole::compute_gf_denom() in global grid ------------------------------------------------------------------------- */ -void PPPMDipole::make_rho_dipole() +void PPPMSpin::make_rho_spin() { int l,m,n,nx,ny,nz,mx,my,mz; FFT_SCALAR dx,dy,dz; @@ -1249,11 +1273,11 @@ void PPPMDipole::make_rho_dipole() // clear 3d density array - memset(&(densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + memset(&(densityx_brick_spin[nzlo_out][nylo_out][nxlo_out]),0, ngrid*sizeof(FFT_SCALAR)); - memset(&(densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + memset(&(densityy_brick_spin[nzlo_out][nylo_out][nxlo_out]),0, ngrid*sizeof(FFT_SCALAR)); - memset(&(densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + memset(&(densityz_brick_spin[nzlo_out][nylo_out][nxlo_out]),0, ngrid*sizeof(FFT_SCALAR)); // loop over my charges, add their contribution to nearby grid points @@ -1261,7 +1285,8 @@ void PPPMDipole::make_rho_dipole() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - double **mu = atom->mu; + //double **mu = atom->mu; + double **sp = atom->sp; double **x = atom->x; int nlocal = atom->nlocal; @@ -1276,9 +1301,9 @@ void PPPMDipole::make_rho_dipole() compute_rho1d(dx,dy,dz); - z0 = delvolinv * mu[i][0]; - z1 = delvolinv * mu[i][1]; - z2 = delvolinv * mu[i][2]; + z0 = delvolinv * sp[i][0]; + z1 = delvolinv * sp[i][1]; + z2 = delvolinv * sp[i][2]; for (n = nlower; n <= nupper; n++) { mz = n+nz; y0 = z0*rho1d[2][n]; @@ -1291,9 +1316,9 @@ void PPPMDipole::make_rho_dipole() x2 = y2*rho1d[1][m]; for (l = nlower; l <= nupper; l++) { mx = l+nx; - densityx_brick_dipole[mz][my][mx] += x0*rho1d[0][l]; - densityy_brick_dipole[mz][my][mx] += x1*rho1d[0][l]; - densityz_brick_dipole[mz][my][mx] += x2*rho1d[0][l]; + densityx_brick_spin[mz][my][mx] += x0*rho1d[0][l]; + densityy_brick_spin[mz][my][mx] += x1*rho1d[0][l]; + densityz_brick_spin[mz][my][mx] += x2*rho1d[0][l]; } } } @@ -1304,7 +1329,7 @@ void PPPMDipole::make_rho_dipole() remap density from 3d brick decomposition to FFT decomposition ------------------------------------------------------------------------- */ -void PPPMDipole::brick2fft_dipole() +void PPPMSpin::brick2fft_spin() { int n,ix,iy,iz; @@ -1316,36 +1341,36 @@ void PPPMDipole::brick2fft_dipole() for (iz = nzlo_in; iz <= nzhi_in; iz++) for (iy = nylo_in; iy <= nyhi_in; iy++) for (ix = nxlo_in; ix <= nxhi_in; ix++) { - densityx_fft_dipole[n] = densityx_brick_dipole[iz][iy][ix]; - densityy_fft_dipole[n] = densityy_brick_dipole[iz][iy][ix]; - densityz_fft_dipole[n] = densityz_brick_dipole[iz][iy][ix]; + densityx_fft_spin[n] = densityx_brick_spin[iz][iy][ix]; + densityy_fft_spin[n] = densityy_brick_spin[iz][iy][ix]; + densityz_fft_spin[n] = densityz_brick_spin[iz][iy][ix]; n++; } - remap->perform(densityx_fft_dipole,densityx_fft_dipole,work1); - remap->perform(densityy_fft_dipole,densityy_fft_dipole,work1); - remap->perform(densityz_fft_dipole,densityz_fft_dipole,work1); + remap->perform(densityx_fft_spin,densityx_fft_spin,work1); + remap->perform(densityy_fft_spin,densityy_fft_spin,work1); + remap->perform(densityz_fft_spin,densityz_fft_spin,work1); } /* ---------------------------------------------------------------------- FFT-based Poisson solver for ik ------------------------------------------------------------------------- */ -void PPPMDipole::poisson_ik_dipole() +void PPPMSpin::poisson_ik_spin() { int i,j,k,n,ii; double eng; double wreal,wimg; - // transform dipole density (r -> k) + // transform spin density (r -> k) n = 0; for (i = 0; i < nfft; i++) { - work1[n] = densityx_fft_dipole[i]; + work1[n] = densityx_fft_spin[i]; work1[n+1] = ZEROF; - work2[n] = densityy_fft_dipole[i]; + work2[n] = densityy_fft_spin[i]; work2[n+1] = ZEROF; - work3[n] = densityz_fft_dipole[i]; + work3[n] = densityz_fft_spin[i]; work3[n+1] = ZEROF; n += 2; } @@ -1412,7 +1437,7 @@ void PPPMDipole::poisson_ik_dipole() // extra FFTs for per-atom energy/virial - if (vflag_atom) poisson_peratom_dipole(); + if (vflag_atom) poisson_peratom_spin(); // compute electric potential // FFT leaves data in 3d brick decomposition @@ -1434,7 +1459,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - ux_brick_dipole[k][j][i] = work4[n]; + ux_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1455,7 +1480,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - uy_brick_dipole[k][j][i] = work4[n]; + uy_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1476,7 +1501,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - uz_brick_dipole[k][j][i] = work4[n]; + uz_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1497,7 +1522,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdxx_brick_dipole[k][j][i] = work4[n]; + vdxx_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1518,7 +1543,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdyy_brick_dipole[k][j][i] = work4[n]; + vdyy_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1539,7 +1564,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdzz_brick_dipole[k][j][i] = work4[n]; + vdzz_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1560,7 +1585,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdxy_brick_dipole[k][j][i] = work4[n]; + vdxy_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1581,7 +1606,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdxz_brick_dipole[k][j][i] = work4[n]; + vdxz_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1602,7 +1627,7 @@ void PPPMDipole::poisson_ik_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdyz_brick_dipole[k][j][i] = work4[n]; + vdyz_brick_spin[k][j][i] = work4[n]; n += 2; } } @@ -1611,7 +1636,7 @@ void PPPMDipole::poisson_ik_dipole() FFT-based Poisson solver for per-atom energy/virial ------------------------------------------------------------------------- */ -void PPPMDipole::poisson_peratom_dipole() +void PPPMSpin::poisson_peratom_spin() { int i,ii,j,k,n; @@ -1638,7 +1663,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v0x_brick_dipole[k][j][i] = work4[n]; + v0x_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1661,7 +1686,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v0y_brick_dipole[k][j][i] = work4[n]; + v0y_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1684,7 +1709,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v0z_brick_dipole[k][j][i] = work4[n]; + v0z_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1707,7 +1732,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v1x_brick_dipole[k][j][i] = work4[n]; + v1x_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1730,7 +1755,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v1y_brick_dipole[k][j][i] = work4[n]; + v1y_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1753,7 +1778,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v1z_brick_dipole[k][j][i] = work4[n]; + v1z_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1776,7 +1801,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v2x_brick_dipole[k][j][i] = work4[n]; + v2x_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1799,7 +1824,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v2y_brick_dipole[k][j][i] = work4[n]; + v2y_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1822,7 +1847,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v2z_brick_dipole[k][j][i] = work4[n]; + v2z_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1845,7 +1870,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v3x_brick_dipole[k][j][i] = work4[n]; + v3x_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1868,7 +1893,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v3y_brick_dipole[k][j][i] = work4[n]; + v3y_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1891,7 +1916,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v3z_brick_dipole[k][j][i] = work4[n]; + v3z_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1914,7 +1939,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v4x_brick_dipole[k][j][i] = work4[n]; + v4x_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1937,7 +1962,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v4y_brick_dipole[k][j][i] = work4[n]; + v4y_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1960,7 +1985,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v4z_brick_dipole[k][j][i] = work4[n]; + v4z_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -1983,7 +2008,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v5x_brick_dipole[k][j][i] = work4[n]; + v5x_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -2006,7 +2031,7 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v5y_brick_dipole[k][j][i] = work4[n]; + v5y_brick_spin[k][j][i] = work4[n]; n += 2; } @@ -2029,16 +2054,16 @@ void PPPMDipole::poisson_peratom_dipole() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v5z_brick_dipole[k][j][i] = work4[n]; + v5z_brick_spin[k][j][i] = work4[n]; n += 2; } } /* ---------------------------------------------------------------------- - interpolate from grid to get electric field & force on my particles for ik + interpolate from grid to get magnetic field & force on my particles for ik ------------------------------------------------------------------------- */ -void PPPMDipole::fieldforce_ik_dipole() +void PPPMSpin::fieldforce_ik_spin() { int i,l,m,n,nx,ny,nz,mx,my,mz; FFT_SCALAR dx,dy,dz; @@ -2052,9 +2077,11 @@ void PPPMDipole::fieldforce_ik_dipole() // (mx,my,mz) = global coords of moving stencil pt - double **mu = atom->mu; + //double **mu = atom->mu; + double **sp = atom->sp; double **x = atom->x; double **f = atom->f; + double **fm = atom->fm; double **t = atom->torque; int nlocal = atom->nlocal; @@ -2080,29 +2107,37 @@ void PPPMDipole::fieldforce_ik_dipole() for (l = nlower; l <= nupper; l++) { mx = l+nx; x0 = y0*rho1d[0][l]; - ex -= x0*ux_brick_dipole[mz][my][mx]; - ey -= x0*uy_brick_dipole[mz][my][mx]; - ez -= x0*uz_brick_dipole[mz][my][mx]; - vxx -= x0*vdxx_brick_dipole[mz][my][mx]; - vyy -= x0*vdyy_brick_dipole[mz][my][mx]; - vzz -= x0*vdzz_brick_dipole[mz][my][mx]; - vxy -= x0*vdxy_brick_dipole[mz][my][mx]; - vxz -= x0*vdxz_brick_dipole[mz][my][mx]; - vyz -= x0*vdyz_brick_dipole[mz][my][mx]; + ex -= x0*ux_brick_spin[mz][my][mx]; + ey -= x0*uy_brick_spin[mz][my][mx]; + ez -= x0*uz_brick_spin[mz][my][mx]; + vxx -= x0*vdxx_brick_spin[mz][my][mx]; + vyy -= x0*vdyy_brick_spin[mz][my][mx]; + vzz -= x0*vdzz_brick_spin[mz][my][mx]; + vxy -= x0*vdxy_brick_spin[mz][my][mx]; + vxz -= x0*vdxz_brick_spin[mz][my][mx]; + vyz -= x0*vdyz_brick_spin[mz][my][mx]; } } } // convert E-field to torque - const double mufactor = qqrd2e * scale; - f[i][0] += mufactor*(vxx*mu[i][0] + vxy*mu[i][1] + vxz*mu[i][2]); - f[i][1] += mufactor*(vxy*mu[i][0] + vyy*mu[i][1] + vyz*mu[i][2]); - f[i][2] += mufactor*(vxz*mu[i][0] + vyz*mu[i][1] + vzz*mu[i][2]); + //const double mufactor = qqrd2e * scale; + const double spfactor = mub2mu0 * scale; + //f[i][0] += mufactor*(vxx*mu[i][0] + vxy*mu[i][1] + vxz*mu[i][2]); + //f[i][1] += mufactor*(vxy*mu[i][0] + vyy*mu[i][1] + vyz*mu[i][2]); + //f[i][2] += mufactor*(vxz*mu[i][0] + vyz*mu[i][1] + vzz*mu[i][2]); + f[i][0] += spfactor*(vxx*sp[i][0] + vxy*sp[i][1] + vxz*sp[i][2]); + f[i][1] += spfactor*(vxy*sp[i][0] + vyy*sp[i][1] + vyz*sp[i][2]); + f[i][2] += spfactor*(vxz*sp[i][0] + vyz*sp[i][1] + vzz*sp[i][2]); + + const double spfactorh = mub2mu0hbinv * scale; + fm[i][0] += spfactorh*ex; + fm[i][1] += spfactorh*ey; + fm[i][2] += spfactorh*ez; + + // create a new vector (in atom_spin style ?) to store long-range fm tables - t[i][0] += mufactor*(mu[i][1]*ez - mu[i][2]*ey); - t[i][1] += mufactor*(mu[i][2]*ex - mu[i][0]*ez); - t[i][2] += mufactor*(mu[i][0]*ey - mu[i][1]*ex); } } @@ -2110,7 +2145,7 @@ void PPPMDipole::fieldforce_ik_dipole() interpolate from grid to get per-atom energy/virial ------------------------------------------------------------------------- */ -void PPPMDipole::fieldforce_peratom_dipole() +void PPPMSpin::fieldforce_peratom_spin() { int i,l,m,n,nx,ny,nz,mx,my,mz; FFT_SCALAR dx,dy,dz,x0,y0,z0; @@ -2124,7 +2159,8 @@ void PPPMDipole::fieldforce_peratom_dipole() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - double **mu = atom->mu; + //double **mu = atom->mu; + double **sp = atom->sp; double **x = atom->x; int nlocal = atom->nlocal; @@ -2153,42 +2189,42 @@ void PPPMDipole::fieldforce_peratom_dipole() mx = l+nx; x0 = y0*rho1d[0][l]; if (eflag_atom) { - ux += x0*ux_brick_dipole[mz][my][mx]; - uy += x0*uy_brick_dipole[mz][my][mx]; - uz += x0*uz_brick_dipole[mz][my][mx]; + ux += x0*ux_brick_spin[mz][my][mx]; + uy += x0*uy_brick_spin[mz][my][mx]; + uz += x0*uz_brick_spin[mz][my][mx]; } if (vflag_atom) { - v0x += x0*v0x_brick_dipole[mz][my][mx]; - v1x += x0*v1x_brick_dipole[mz][my][mx]; - v2x += x0*v2x_brick_dipole[mz][my][mx]; - v3x += x0*v3x_brick_dipole[mz][my][mx]; - v4x += x0*v4x_brick_dipole[mz][my][mx]; - v5x += x0*v5x_brick_dipole[mz][my][mx]; - v0y += x0*v0y_brick_dipole[mz][my][mx]; - v1y += x0*v1y_brick_dipole[mz][my][mx]; - v2y += x0*v2y_brick_dipole[mz][my][mx]; - v3y += x0*v3y_brick_dipole[mz][my][mx]; - v4y += x0*v4y_brick_dipole[mz][my][mx]; - v5y += x0*v5y_brick_dipole[mz][my][mx]; - v0z += x0*v0z_brick_dipole[mz][my][mx]; - v1z += x0*v1z_brick_dipole[mz][my][mx]; - v2z += x0*v2z_brick_dipole[mz][my][mx]; - v3z += x0*v3z_brick_dipole[mz][my][mx]; - v4z += x0*v4z_brick_dipole[mz][my][mx]; - v5z += x0*v5z_brick_dipole[mz][my][mx]; + v0x += x0*v0x_brick_spin[mz][my][mx]; + v1x += x0*v1x_brick_spin[mz][my][mx]; + v2x += x0*v2x_brick_spin[mz][my][mx]; + v3x += x0*v3x_brick_spin[mz][my][mx]; + v4x += x0*v4x_brick_spin[mz][my][mx]; + v5x += x0*v5x_brick_spin[mz][my][mx]; + v0y += x0*v0y_brick_spin[mz][my][mx]; + v1y += x0*v1y_brick_spin[mz][my][mx]; + v2y += x0*v2y_brick_spin[mz][my][mx]; + v3y += x0*v3y_brick_spin[mz][my][mx]; + v4y += x0*v4y_brick_spin[mz][my][mx]; + v5y += x0*v5y_brick_spin[mz][my][mx]; + v0z += x0*v0z_brick_spin[mz][my][mx]; + v1z += x0*v1z_brick_spin[mz][my][mx]; + v2z += x0*v2z_brick_spin[mz][my][mx]; + v3z += x0*v3z_brick_spin[mz][my][mx]; + v4z += x0*v4z_brick_spin[mz][my][mx]; + v5z += x0*v5z_brick_spin[mz][my][mx]; } } } } - if (eflag_atom) eatom[i] += mu[i][0]*ux + mu[i][1]*uy + mu[i][2]*uz; + if (eflag_atom) eatom[i] += sp[i][0]*ux + sp[i][1]*uy + sp[i][2]*uz; if (vflag_atom) { - vatom[i][0] += mu[i][0]*v0x + mu[i][1]*v0y + mu[i][2]*v0z; - vatom[i][1] += mu[i][0]*v1x + mu[i][1]*v1y + mu[i][2]*v1z; - vatom[i][2] += mu[i][0]*v2x + mu[i][1]*v2y + mu[i][2]*v2z; - vatom[i][3] += mu[i][0]*v3x + mu[i][1]*v3y + mu[i][2]*v3z; - vatom[i][4] += mu[i][0]*v4x + mu[i][1]*v4y + mu[i][2]*v4z; - vatom[i][5] += mu[i][0]*v5x + mu[i][1]*v5y + mu[i][2]*v5z; + vatom[i][0] += sp[i][0]*v0x + sp[i][1]*v0y + sp[i][2]*v0z; + vatom[i][1] += sp[i][0]*v1x + sp[i][1]*v1y + sp[i][2]*v1z; + vatom[i][2] += sp[i][0]*v2x + sp[i][1]*v2y + sp[i][2]*v2z; + vatom[i][3] += sp[i][0]*v3x + sp[i][1]*v3y + sp[i][2]*v3z; + vatom[i][4] += sp[i][0]*v4x + sp[i][1]*v4y + sp[i][2]*v4z; + vatom[i][5] += sp[i][0]*v5x + sp[i][1]*v5y + sp[i][2]*v5z; } } } @@ -2197,20 +2233,20 @@ void PPPMDipole::fieldforce_peratom_dipole() pack own values to buf to send to another proc ------------------------------------------------------------------------- */ -void PPPMDipole::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMSpin::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == FORWARD_MU) { - FFT_SCALAR *src_ux = &ux_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_uy = &uy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_uz = &uz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vxx = &vdxx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vyy = &vdyy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vzz = &vdzz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vxy = &vdxy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vxz = &vdxz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vyz = &vdyz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + if (flag == FORWARD_SP) { + FFT_SCALAR *src_ux = &ux_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_uy = &uy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_uz = &uz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxx = &vdxx_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vyy = &vdyy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vzz = &vdzz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxy = &vdxy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxz = &vdxz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vyz = &vdyz_brick_spin[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { buf[n++] = src_ux[list[i]]; buf[n++] = src_uy[list[i]]; @@ -2222,25 +2258,25 @@ void PPPMDipole::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) buf[n++] = src_vxz[list[i]]; buf[n++] = src_vyz[list[i]]; } - } else if (flag == FORWARD_MU_PERATOM) { - FFT_SCALAR *v0xsrc = &v0x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1xsrc = &v1x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2xsrc = &v2x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3xsrc = &v3x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4xsrc = &v4x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5xsrc = &v5x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0ysrc = &v0y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1ysrc = &v1y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2ysrc = &v2y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3ysrc = &v3y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4ysrc = &v4y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5ysrc = &v5y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0zsrc = &v0z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1zsrc = &v1z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2zsrc = &v2z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3zsrc = &v3z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4zsrc = &v4z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5zsrc = &v5z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + } else if (flag == FORWARD_SP_PERATOM) { + FFT_SCALAR *v0xsrc = &v0x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1xsrc = &v1x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2xsrc = &v2x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3xsrc = &v3x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4xsrc = &v4x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5xsrc = &v5x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0ysrc = &v0y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1ysrc = &v1y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2ysrc = &v2y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3ysrc = &v3y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4ysrc = &v4y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5ysrc = &v5y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0zsrc = &v0z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1zsrc = &v1z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2zsrc = &v2z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3zsrc = &v3z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4zsrc = &v4z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5zsrc = &v5z_brick_spin[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { buf[n++] = v0xsrc[list[i]]; buf[n++] = v1xsrc[list[i]]; @@ -2268,20 +2304,20 @@ void PPPMDipole::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) unpack another proc's own values from buf and set own ghost values ------------------------------------------------------------------------- */ -void PPPMDipole::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMSpin::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == FORWARD_MU) { - FFT_SCALAR *dest_ux = &ux_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_uy = &uy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_uz = &uz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vxx = &vdxx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vyy = &vdyy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vzz = &vdzz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vxy = &vdxy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vxz = &vdxz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vyz = &vdyz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + if (flag == FORWARD_SP) { + FFT_SCALAR *dest_ux = &ux_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_uy = &uy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_uz = &uz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxx = &vdxx_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vyy = &vdyy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vzz = &vdzz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxy = &vdxy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxz = &vdxz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vyz = &vdyz_brick_spin[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { dest_ux[list[i]] = buf[n++]; dest_uy[list[i]] = buf[n++]; @@ -2293,25 +2329,25 @@ void PPPMDipole::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) dest_vxz[list[i]] = buf[n++]; dest_vyz[list[i]] = buf[n++]; } - } else if (flag == FORWARD_MU_PERATOM) { - FFT_SCALAR *v0xsrc = &v0x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1xsrc = &v1x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2xsrc = &v2x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3xsrc = &v3x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4xsrc = &v4x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5xsrc = &v5x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0ysrc = &v0y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1ysrc = &v1y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2ysrc = &v2y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3ysrc = &v3y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4ysrc = &v4y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5ysrc = &v5y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0zsrc = &v0z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1zsrc = &v1z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2zsrc = &v2z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3zsrc = &v3z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4zsrc = &v4z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5zsrc = &v5z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + } else if (flag == FORWARD_SP_PERATOM) { + FFT_SCALAR *v0xsrc = &v0x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1xsrc = &v1x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2xsrc = &v2x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3xsrc = &v3x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4xsrc = &v4x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5xsrc = &v5x_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0ysrc = &v0y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1ysrc = &v1y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2ysrc = &v2y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3ysrc = &v3y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4ysrc = &v4y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5ysrc = &v5y_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0zsrc = &v0z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1zsrc = &v1z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2zsrc = &v2z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3zsrc = &v3z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4zsrc = &v4z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5zsrc = &v5z_brick_spin[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { v0xsrc[list[i]] = buf[n++]; v1xsrc[list[i]] = buf[n++]; @@ -2339,17 +2375,17 @@ void PPPMDipole::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) pack ghost values into buf to send to another proc ------------------------------------------------------------------------- */ -void PPPMDipole::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMSpin::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == REVERSE_MU) { - FFT_SCALAR *src_dipole0 = &densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_dipole1 = &densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_dipole2 = &densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + if (flag == REVERSE_SP) { + FFT_SCALAR *src_spin0 = &densityx_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_spin1 = &densityy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_spin2 = &densityz_brick_spin[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { - buf[n++] = src_dipole0[list[i]]; - buf[n++] = src_dipole1[list[i]]; - buf[n++] = src_dipole2[list[i]]; + buf[n++] = src_spin0[list[i]]; + buf[n++] = src_spin1[list[i]]; + buf[n++] = src_spin2[list[i]]; } } } @@ -2358,17 +2394,17 @@ void PPPMDipole::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) unpack another proc's ghost values from buf and add to own values ------------------------------------------------------------------------- */ -void PPPMDipole::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMSpin::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == REVERSE_MU) { - FFT_SCALAR *dest_dipole0 = &densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_dipole1 = &densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_dipole2 = &densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + if (flag == REVERSE_SP) { + FFT_SCALAR *dest_spin0 = &densityx_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_spin1 = &densityy_brick_spin[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_spin2 = &densityz_brick_spin[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { - dest_dipole0[list[i]] += buf[n++]; - dest_dipole1[list[i]] += buf[n++]; - dest_dipole2[list[i]] += buf[n++]; + dest_spin0[list[i]] += buf[n++]; + dest_spin1[list[i]] += buf[n++]; + dest_spin2[list[i]] += buf[n++]; } } } @@ -2381,22 +2417,23 @@ void PPPMDipole::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) extended to non-neutral systems (J. Chem. Phys. 131, 094107). ------------------------------------------------------------------------- */ -void PPPMDipole::slabcorr() +void PPPMSpin::slabcorr() { - // compute local contribution to global dipole moment + // compute local contribution to global spin moment double **x = atom->x; double zprd = domain->zprd; int nlocal = atom->nlocal; - double dipole = 0.0; - double **mu = atom->mu; - for (int i = 0; i < nlocal; i++) dipole += mu[i][2]; + double spin = 0.0; + //double **mu = atom->mu; + double **sp = atom->sp; + for (int i = 0; i < nlocal; i++) spin += sp[i][2]; - // sum local contributions to get global dipole moment + // sum local contributions to get global spin moment - double dipole_all; - MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world); + double spin_all; + MPI_Allreduce(&spin,&spin_all,1,MPI_DOUBLE,MPI_SUM,world); // need to make non-neutral systems and/or // per-atom energy translationally invariant @@ -2404,42 +2441,48 @@ void PPPMDipole::slabcorr() if (eflag_atom || fabs(qsum) > SMALL) { error->all(FLERR,"Cannot (yet) use kspace slab correction with " - "long-range dipoles and non-neutral systems or per-atom energy"); + "long-range spins and non-neutral systems or per-atom energy"); } // compute corrections - const double e_slabcorr = MY_2PI*(dipole_all*dipole_all/12.0)/volume; - const double qscale = qqrd2e * scale; + const double e_slabcorr = MY_2PI*(spin_all*spin_all/12.0)/volume; + //const double qscale = qqrd2e * scale; + const double spscale = mub2mu0 * scale; - if (eflag_global) energy += qscale * e_slabcorr; + if (eflag_global) energy += spscale * e_slabcorr; // per-atom energy if (eflag_atom) { - double efact = qscale * MY_2PI/volume/12.0; + //double efact = qscale * MY_2PI/volume/12.0; + double efact = spscale * MY_2PI/volume/12.0; for (int i = 0; i < nlocal; i++) - eatom[i] += efact * mu[i][2]*dipole_all; + //eatom[i] += efact * mu[i][2]*spin_all; + eatom[i] += efact * sp[i][2]*spin_all; } // add on torque corrections - if (atom->torque) { - double ffact = qscale * (-4.0*MY_PI/volume); - double **mu = atom->mu; - double **torque = atom->torque; - for (int i = 0; i < nlocal; i++) { - torque[i][0] += ffact * dipole_all * mu[i][1]; - torque[i][1] += -ffact * dipole_all * mu[i][0]; - } - } + // no torque for the spins + // should it be calculated for the magnetic force fm? + + //if (atom->torque) { + // double ffact = qscale * (-4.0*MY_PI/volume); + // double **mu = atom->mu; + // double **torque = atom->torque; + // for (int i = 0; i < nlocal; i++) { + // torque[i][0] += ffact * spin_all * mu[i][1]; + // torque[i][1] += -ffact * spin_all * mu[i][0]; + // } + //} } /* ---------------------------------------------------------------------- perform and time the 1d FFTs required for N timesteps ------------------------------------------------------------------------- */ -int PPPMDipole::timing_1d(int n, double &time1d) +int PPPMSpin::timing_1d(int n, double &time1d) { double time1,time2; @@ -2474,7 +2517,7 @@ int PPPMDipole::timing_1d(int n, double &time1d) perform and time the 3d FFTs required for N timesteps ------------------------------------------------------------------------- */ -int PPPMDipole::timing_3d(int n, double &time3d) +int PPPMSpin::timing_3d(int n, double &time3d) { double time1,time2; @@ -2509,7 +2552,7 @@ int PPPMDipole::timing_3d(int n, double &time3d) memory usage of local arrays ------------------------------------------------------------------------- */ -double PPPMDipole::memory_usage() +double PPPMSpin::memory_usage() { double bytes = nmax*3 * sizeof(double); int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) * @@ -2523,37 +2566,41 @@ double PPPMDipole::memory_usage() if (peratom_allocate_flag) bytes += 21 * nbrick * sizeof(FFT_SCALAR); - if (cg_dipole) bytes += cg_dipole->memory_usage(); - if (cg_peratom_dipole) bytes += cg_peratom_dipole->memory_usage(); + if (cg_spin) bytes += cg_spin->memory_usage(); + if (cg_peratom_spin) bytes += cg_peratom_spin->memory_usage(); return bytes; } /* ---------------------------------------------------------------------- - compute musum,musqsum,mu2 - called initially, when particle count changes, when dipoles are changed + compute spsum,spsqsum,sp2 + called initially, when particle count changes, when spins are changed ------------------------------------------------------------------------- */ -void PPPMDipole::musum_musq() +void PPPMSpin::spsum_spsq() { const int nlocal = atom->nlocal; - musum = musqsum = mu2 = 0.0; - if (atom->mu_flag) { - double** mu = atom->mu; - double musum_local(0.0), musqsum_local(0.0); + spsum = spsqsum = sp2 = 0.0; + if (atom->sp_flag) { + double **sp = atom->sp; + double spsum_local(0.0), spsqsum_local(0.0); + + // not exactly the good loop: need to add norm of spins for (int i = 0; i < nlocal; i++) { - musum_local += mu[i][0] + mu[i][1] + mu[i][2]; - musqsum_local += mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]; + spsum_local += sp[i][0] + sp[i][1] + sp[i][2]; + spsqsum_local += sp[i][0]*sp[i][0] + sp[i][1]*sp[i][1] + sp[i][2]*sp[i][2]; } - MPI_Allreduce(&musum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(&musqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&spsum_local,&spsum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&spsqsum_local,&spsqsum,1,MPI_DOUBLE,MPI_SUM,world); - mu2 = musqsum * force->qqrd2e; + //mu2 = musqsum * force->qqrd2e; + // find correct units + sp2 = spsqsum * mub2mu0; } - if (mu2 == 0 && comm->me == 0) - error->all(FLERR,"Using kspace solver PPPMDipole on system with no dipoles"); -} \ No newline at end of file + if (sp2 == 0 && comm->me == 0) + error->all(FLERR,"Using kspace solver PPPMSpin on system with no spins"); +} diff --git a/src/KSPACE/pppm_spin.h b/src/KSPACE/pppm_spin.h index 4d6906f974..aacda1f0af 100644 --- a/src/KSPACE/pppm_spin.h +++ b/src/KSPACE/pppm_spin.h @@ -13,7 +13,7 @@ #ifdef KSPACE_CLASS -KSpaceStyle(pppm/dipole,PPPMDipole) +KSpaceStyle(pppm/spin,PPPMSpin) #else @@ -24,10 +24,10 @@ KSpaceStyle(pppm/dipole,PPPMDipole) namespace LAMMPS_NS { -class PPPMDipole : public PPPM { +class PPPMSpin : public PPPM { public: - PPPMDipole(class LAMMPS *, int, char **); - virtual ~PPPMDipole(); + PPPMSpin(class LAMMPS *, int, char **); + virtual ~PPPMSpin(); void init(); void setup(); void setup_grid(); @@ -55,37 +55,37 @@ class PPPMDipole : public PPPM { void pack_reverse(int, FFT_SCALAR *, int, int *); void unpack_reverse(int, FFT_SCALAR *, int, int *); - // dipole - - FFT_SCALAR ***densityx_brick_dipole,***densityy_brick_dipole,***densityz_brick_dipole; - FFT_SCALAR ***vdxx_brick_dipole,***vdyy_brick_dipole,***vdzz_brick_dipole; - FFT_SCALAR ***vdxy_brick_dipole,***vdxz_brick_dipole,***vdyz_brick_dipole; - FFT_SCALAR ***ux_brick_dipole,***uy_brick_dipole,***uz_brick_dipole; - FFT_SCALAR ***v0x_brick_dipole,***v1x_brick_dipole,***v2x_brick_dipole; - FFT_SCALAR ***v3x_brick_dipole,***v4x_brick_dipole,***v5x_brick_dipole; - FFT_SCALAR ***v0y_brick_dipole,***v1y_brick_dipole,***v2y_brick_dipole; - FFT_SCALAR ***v3y_brick_dipole,***v4y_brick_dipole,***v5y_brick_dipole; - FFT_SCALAR ***v0z_brick_dipole,***v1z_brick_dipole,***v2z_brick_dipole; - FFT_SCALAR ***v3z_brick_dipole,***v4z_brick_dipole,***v5z_brick_dipole; + // spin + + FFT_SCALAR ***densityx_brick_spin,***densityy_brick_spin,***densityz_brick_spin; + FFT_SCALAR ***vdxx_brick_spin,***vdyy_brick_spin,***vdzz_brick_spin; + FFT_SCALAR ***vdxy_brick_spin,***vdxz_brick_spin,***vdyz_brick_spin; + FFT_SCALAR ***ux_brick_spin,***uy_brick_spin,***uz_brick_spin; + FFT_SCALAR ***v0x_brick_spin,***v1x_brick_spin,***v2x_brick_spin; + FFT_SCALAR ***v3x_brick_spin,***v4x_brick_spin,***v5x_brick_spin; + FFT_SCALAR ***v0y_brick_spin,***v1y_brick_spin,***v2y_brick_spin; + FFT_SCALAR ***v3y_brick_spin,***v4y_brick_spin,***v5y_brick_spin; + FFT_SCALAR ***v0z_brick_spin,***v1z_brick_spin,***v2z_brick_spin; + FFT_SCALAR ***v3z_brick_spin,***v4z_brick_spin,***v5z_brick_spin; FFT_SCALAR *work3,*work4; - FFT_SCALAR *densityx_fft_dipole,*densityy_fft_dipole,*densityz_fft_dipole; - class GridComm *cg_dipole; - class GridComm *cg_peratom_dipole; - int only_dipole_flag; + FFT_SCALAR *densityx_fft_spin,*densityy_fft_spin,*densityz_fft_spin; + class GridComm *cg_spin; + class GridComm *cg_peratom_spin; + int only_spin_flag; double musum,musqsum,mu2; - double find_gewald_dipole(double, double, bigint, double, double); - double newton_raphson_f_dipole(double, double, bigint, double, double); - double derivf_dipole(double, double, bigint, double, double); - double compute_df_kspace_dipole(); - double compute_qopt_dipole(); - void compute_gf_dipole(); - void make_rho_dipole(); - void brick2fft_dipole(); - void poisson_ik_dipole(); - void poisson_peratom_dipole(); - void fieldforce_ik_dipole(); - void fieldforce_peratom_dipole(); - double final_accuracy_dipole(); + double find_gewald_spin(double, double, bigint, double, double); + double newton_raphson_f_spin(double, double, bigint, double, double); + double derivf_spin(double, double, bigint, double, double); + double compute_df_kspace_spin(); + double compute_qopt_spin(); + void compute_gf_spin(); + void make_rho_spin(); + void brick2fft_spin(); + void poisson_ik_spin(); + void poisson_peratom_spin(); + void fieldforce_ik_spin(); + void fieldforce_peratom_spin(); + double final_accuracy_spin(); void musum_musq(); }; @@ -97,9 +97,9 @@ class PPPMDipole : public PPPM { /* ERROR/WARNING messages: -E: Cannot (yet) use charges with Kspace style PPPMDipole +E: Cannot (yet) use charges with Kspace style PPPMSpin -Charge-dipole interactions are not yet implemented in PPPMDipole so this +Charge-spin interactions are not yet implemented in PPPMSpin so this feature is not yet supported. E: Must redefine kspace_style after changing to triclinic box @@ -110,19 +110,19 @@ E: Kspace style requires atom attribute mu The atom style defined does not have this attribute. -E: Cannot (yet) use kspace_modify diff ad with dipoles +E: Cannot (yet) use kspace_modify diff ad with spins This feature is not yet supported. -E: Cannot (yet) use 'electron' units with dipoles +E: Cannot (yet) use 'electron' units with spins This feature is not yet supported. -E: Cannot yet use triclinic cells with PPPMDipole +E: Cannot yet use triclinic cells with PPPMSpin This feature is not yet supported. -E: Cannot yet use TIP4P with PPPMDipole +E: Cannot yet use TIP4P with PPPMSpin This feature is not yet supported. @@ -144,7 +144,7 @@ This is a limitation of the PPPM implementation in LAMMPS. E: KSpace style is incompatible with Pair style Setting a kspace style requires that a pair style with matching -long-range dipole components be used. +long-range spin components be used. W: Reducing PPPM order b/c stencil extends beyond nearest neighbor processor @@ -202,11 +202,11 @@ outside a processor's sub-domain or even the entire simulation box. This indicates bad physics, e.g. due to highly overlapping atoms, too large a timestep, etc. -E: Using kspace solver PPPMDipole on system with no dipoles +E: Using kspace solver PPPMSpin on system with no spins -Must have non-zero dipoles with PPPMDipole. +Must have non-zero spins with PPPMSpin. -E: Must use kspace_modify gewald for system with no dipoles +E: Must use kspace_modify gewald for system with no spins Self-explanatory. -- GitLab From 5e287033f79e8662a18767239b4c8d2b6eac7308 Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 16 Aug 2018 10:13:18 -0600 Subject: [PATCH 0034/1243] Commit1 JT 081618 - converted pppm_spin for long range spin-spin interactions - modified kspace, pair,and pair_hybrid to add spinflag --- src/KSPACE/pppm_spin.cpp | 138 ++++++++++++++---------------------- src/KSPACE/pppm_spin.h | 9 ++- src/SPIN/pair_spin_long.cpp | 2 +- src/kspace.cpp | 4 +- src/kspace.h | 1 + src/pair.cpp | 2 +- src/pair.h | 1 + src/pair_hybrid.cpp | 1 + 8 files changed, 70 insertions(+), 88 deletions(-) diff --git a/src/KSPACE/pppm_spin.cpp b/src/KSPACE/pppm_spin.cpp index c51de8d023..9b59f9cd7b 100644 --- a/src/KSPACE/pppm_spin.cpp +++ b/src/KSPACE/pppm_spin.cpp @@ -115,13 +115,7 @@ void PPPMSpin::init() // error check - //spinflag = atom->mu?1:0; spinflag = atom->sp?1:0; - // no charges here, charge neutrality - //qsum_qsq(0); - // maybe change this test - if (spinflag && q2) - error->all(FLERR,"Cannot (yet) uses charges with Kspace style PPPMSpin"); triclinic_check(); @@ -175,17 +169,12 @@ void PPPMSpin::init() if (tip4pflag) error->all(FLERR,"Cannot yet use TIP4P with PPPMSpin"); - // compute qsum & qsqsum and warn if not charge-neutral - scale = 1.0; - //qqrd2e = force->qqrd2e; - // need to define mag constants instead hbar = force->hplanck/MY_2PI; // eV/(rad.THz) mub = 5.78901e-5; // in eV/T mu_0 = 1.2566370614e-6; // in T.m/A mub2mu0 = mub * mub * mu_0; // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz - //musum_musq(); spsum_spsq(); natoms_original = atom->natoms; @@ -458,7 +447,6 @@ void PPPMSpin::compute(int eflag, int vflag) // if atom count has changed, update qsum and qsqsum if (atom->natoms != natoms_original) { - //musum_musq(); spsum_spsq(); natoms_original = atom->natoms; } @@ -520,7 +508,6 @@ void PPPMSpin::compute(int eflag, int vflag) // sum global energy across procs and add in volume-dependent term - //const double qscale = qqrd2e * scale; const double spscale = mub2mu0 * scale; const double g3 = g_ewald*g_ewald*g_ewald; @@ -531,7 +518,7 @@ void PPPMSpin::compute(int eflag, int vflag) energy *= 0.5*volume; energy -= spsqsum*2.0*g3/3.0/MY_PIS; - energy *= qscale; + energy *= spscale; } // sum global virial across procs @@ -539,32 +526,32 @@ void PPPMSpin::compute(int eflag, int vflag) if (vflag_global) { double virial_all[6]; MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); - for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i]; + for (i = 0; i < 6; i++) virial[i] = 0.5*spscale*volume*virial_all[i]; } // per-atom energy/virial // energy includes self-energy correction if (evflag_atom) { - //double *q = atom->q; - //double **mu = atom->mu; double **sp = atom->sp; + double spx,spy,spz; int nlocal = atom->nlocal; int ntotal = nlocal; if (eflag_atom) { for (i = 0; i < nlocal; i++) { + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; eatom[i] *= 0.5; - //eatom[i] -= (mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2])*2.0*g3/3.0/MY_PIS; - eatom[i] -= (sp[i][0]*sp[i][0] + sp[i][1]*sp[i][1] + sp[i][2]*sp[i][2])*2.0*g3/3.0/MY_PIS; - //eatom[i] *= qscale; + eatom[i] -= (spx*spx + spy*spy + spz*spz)*2.0*g3/3.0/MY_PIS; eatom[i] *= spscale; } } if (vflag_atom) { for (i = 0; i < ntotal; i++) - for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*qscale; + for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*spscale; } } @@ -918,7 +905,6 @@ double PPPMSpin::compute_df_kspace_spin() double zprd_slab = zprd*slab_volfactor; bigint natoms = atom->natoms; double qopt = compute_qopt_spin(); - //double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); double df_kspace = sqrt(qopt/natoms)*sp2/(3.0*xprd*yprd*zprd_slab); return df_kspace; } @@ -1131,8 +1117,6 @@ double PPPMSpin::newton_raphson_f() double rg6 = rg4*rg2; double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - //df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * - // sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); df_rspace = (sp2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); df_kspace = compute_df_kspace_spin(); @@ -1218,9 +1202,6 @@ double PPPMSpin::final_accuracy_spin() double rg6 = rg4*rg2; double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - //double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * - // sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * - // exp(-rg2)); double df_rspace = (sp2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); @@ -1285,8 +1266,8 @@ void PPPMSpin::make_rho_spin() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - //double **mu = atom->mu; double **sp = atom->sp; + double spx,spy,spz; double **x = atom->x; int nlocal = atom->nlocal; @@ -1301,9 +1282,12 @@ void PPPMSpin::make_rho_spin() compute_rho1d(dx,dy,dz); - z0 = delvolinv * sp[i][0]; - z1 = delvolinv * sp[i][1]; - z2 = delvolinv * sp[i][2]; + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + z0 = delvolinv * spx; + z1 = delvolinv * spy; + z2 = delvolinv * spz; for (n = nlower; n <= nupper; n++) { mz = n+nz; y0 = z0*rho1d[2][n]; @@ -2076,13 +2060,11 @@ void PPPMSpin::fieldforce_ik_spin() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - - //double **mu = atom->mu; double **sp = atom->sp; + double spx,spy,spz; double **x = atom->x; double **f = atom->f; double **fm = atom->fm; - double **t = atom->torque; int nlocal = atom->nlocal; @@ -2120,16 +2102,15 @@ void PPPMSpin::fieldforce_ik_spin() } } - // convert E-field to torque + // convert M-field to mech. and mag. forces - //const double mufactor = qqrd2e * scale; const double spfactor = mub2mu0 * scale; - //f[i][0] += mufactor*(vxx*mu[i][0] + vxy*mu[i][1] + vxz*mu[i][2]); - //f[i][1] += mufactor*(vxy*mu[i][0] + vyy*mu[i][1] + vyz*mu[i][2]); - //f[i][2] += mufactor*(vxz*mu[i][0] + vyz*mu[i][1] + vzz*mu[i][2]); - f[i][0] += spfactor*(vxx*sp[i][0] + vxy*sp[i][1] + vxz*sp[i][2]); - f[i][1] += spfactor*(vxy*sp[i][0] + vyy*sp[i][1] + vyz*sp[i][2]); - f[i][2] += spfactor*(vxz*sp[i][0] + vyz*sp[i][1] + vzz*sp[i][2]); + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + f[i][0] += spfactor*(vxx*spx + vxy*spy + vxz*spz); + f[i][1] += spfactor*(vxy*spx + vyy*spy + vyz*spz); + f[i][2] += spfactor*(vxz*spx + vyz*spy + vzz*spz); const double spfactorh = mub2mu0hbinv * scale; fm[i][0] += spfactorh*ex; @@ -2159,8 +2140,8 @@ void PPPMSpin::fieldforce_peratom_spin() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - //double **mu = atom->mu; double **sp = atom->sp; + double spx,spy,spz; double **x = atom->x; int nlocal = atom->nlocal; @@ -2217,14 +2198,17 @@ void PPPMSpin::fieldforce_peratom_spin() } } - if (eflag_atom) eatom[i] += sp[i][0]*ux + sp[i][1]*uy + sp[i][2]*uz; + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + if (eflag_atom) eatom[i] += spx*ux + spy*uy + spz*uz; if (vflag_atom) { - vatom[i][0] += sp[i][0]*v0x + sp[i][1]*v0y + sp[i][2]*v0z; - vatom[i][1] += sp[i][0]*v1x + sp[i][1]*v1y + sp[i][2]*v1z; - vatom[i][2] += sp[i][0]*v2x + sp[i][1]*v2y + sp[i][2]*v2z; - vatom[i][3] += sp[i][0]*v3x + sp[i][1]*v3y + sp[i][2]*v3z; - vatom[i][4] += sp[i][0]*v4x + sp[i][1]*v4y + sp[i][2]*v4z; - vatom[i][5] += sp[i][0]*v5x + sp[i][1]*v5y + sp[i][2]*v5z; + vatom[i][0] += spx*v0x + spy*v0y + spz*v0z; + vatom[i][1] += spx*v1x + spy*v1y + spz*v1z; + vatom[i][2] += spx*v2x + spy*v2y + spz*v2z; + vatom[i][3] += spx*v3x + spy*v3y + spz*v3z; + vatom[i][4] += spx*v4x + spy*v4y + spz*v4z; + vatom[i][5] += spx*v5x + spy*v5y + spz*v5z; } } } @@ -2426,28 +2410,21 @@ void PPPMSpin::slabcorr() int nlocal = atom->nlocal; double spin = 0.0; - //double **mu = atom->mu; double **sp = atom->sp; - for (int i = 0; i < nlocal; i++) spin += sp[i][2]; + double spx,spy,spz; + for (int i = 0; i < nlocal; i++) { + spz = sp[i][2]*sp[i][3]; + spin += spz; + } // sum local contributions to get global spin moment double spin_all; MPI_Allreduce(&spin,&spin_all,1,MPI_DOUBLE,MPI_SUM,world); - // need to make non-neutral systems and/or - // per-atom energy translationally invariant - - if (eflag_atom || fabs(qsum) > SMALL) { - - error->all(FLERR,"Cannot (yet) use kspace slab correction with " - "long-range spins and non-neutral systems or per-atom energy"); - } - // compute corrections const double e_slabcorr = MY_2PI*(spin_all*spin_all/12.0)/volume; - //const double qscale = qqrd2e * scale; const double spscale = mub2mu0 * scale; if (eflag_global) energy += spscale * e_slabcorr; @@ -2455,27 +2432,20 @@ void PPPMSpin::slabcorr() // per-atom energy if (eflag_atom) { - //double efact = qscale * MY_2PI/volume/12.0; double efact = spscale * MY_2PI/volume/12.0; - for (int i = 0; i < nlocal; i++) - //eatom[i] += efact * mu[i][2]*spin_all; - eatom[i] += efact * sp[i][2]*spin_all; + for (int i = 0; i < nlocal; i++) { + spz = sp[i][2]*sp[i][3]; + eatom[i] += efact * spz * spin_all; + } } - // add on torque corrections - - // no torque for the spins - // should it be calculated for the magnetic force fm? + // add on mag. force corrections - //if (atom->torque) { - // double ffact = qscale * (-4.0*MY_PI/volume); - // double **mu = atom->mu; - // double **torque = atom->torque; - // for (int i = 0; i < nlocal; i++) { - // torque[i][0] += ffact * spin_all * mu[i][1]; - // torque[i][1] += -ffact * spin_all * mu[i][0]; - // } - //} + double ffact = spscale * (-4.0*MY_PI/volume); + double **fm = atom->fm; + for (int i = 0; i < nlocal; i++) { + fm[i][2] += ffact * spin_all; + } } /* ---------------------------------------------------------------------- @@ -2584,20 +2554,22 @@ void PPPMSpin::spsum_spsq() spsum = spsqsum = sp2 = 0.0; if (atom->sp_flag) { double **sp = atom->sp; + double spx, spy, spz; double spsum_local(0.0), spsqsum_local(0.0); // not exactly the good loop: need to add norm of spins for (int i = 0; i < nlocal; i++) { - spsum_local += sp[i][0] + sp[i][1] + sp[i][2]; - spsqsum_local += sp[i][0]*sp[i][0] + sp[i][1]*sp[i][1] + sp[i][2]*sp[i][2]; + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + spsum_local += spx + spy + spz; + spsqsum_local += spx*spx + spy*spy + spz*spz; } MPI_Allreduce(&spsum_local,&spsum,1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&spsqsum_local,&spsqsum,1,MPI_DOUBLE,MPI_SUM,world); - //mu2 = musqsum * force->qqrd2e; - // find correct units sp2 = spsqsum * mub2mu0; } diff --git a/src/KSPACE/pppm_spin.h b/src/KSPACE/pppm_spin.h index aacda1f0af..3b4d42d4ea 100644 --- a/src/KSPACE/pppm_spin.h +++ b/src/KSPACE/pppm_spin.h @@ -37,6 +37,11 @@ class PPPMSpin : public PPPM { double memory_usage(); protected: + double hbar; // reduced Planck's constant + double mub; // Bohr's magneton + double mu_0; // vacuum permeability + double mub2mu0; // prefactor for mech force + double mub2mu0hbinv; // prefactor for mag force void set_grid_global(); double newton_raphson_f(); @@ -72,7 +77,7 @@ class PPPMSpin : public PPPM { class GridComm *cg_spin; class GridComm *cg_peratom_spin; int only_spin_flag; - double musum,musqsum,mu2; + double spsum,spsqsum,sp2; double find_gewald_spin(double, double, bigint, double, double); double newton_raphson_f_spin(double, double, bigint, double, double); double derivf_spin(double, double, bigint, double, double); @@ -86,7 +91,7 @@ class PPPMSpin : public PPPM { void fieldforce_ik_spin(); void fieldforce_peratom_spin(); double final_accuracy_spin(); - void musum_musq(); + void spsum_spsq(); }; diff --git a/src/SPIN/pair_spin_long.cpp b/src/SPIN/pair_spin_long.cpp index 66b684ae1d..95c4e6b5a9 100644 --- a/src/SPIN/pair_spin_long.cpp +++ b/src/SPIN/pair_spin_long.cpp @@ -59,7 +59,7 @@ PairSpinLong::PairSpinLong(LAMMPS *lmp) : PairSpin(lmp), lockfixnvespin(NULL) { single_enable = 0; - ewaldflag = pppmflag = 1; + ewaldflag = pppmflag = spinflag = 1; respa_enable = 0; no_virial_fdotr_compute = 1; lattice_flag = 0; diff --git a/src/kspace.cpp b/src/kspace.cpp index da606bbf3d..75b6abf515 100644 --- a/src/kspace.cpp +++ b/src/kspace.cpp @@ -37,7 +37,7 @@ KSpace::KSpace(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) virial[0] = virial[1] = virial[2] = virial[3] = virial[4] = virial[5] = 0.0; triclinic_support = 1; - ewaldflag = pppmflag = msmflag = dispersionflag = tip4pflag = dipoleflag = 0; + ewaldflag = pppmflag = msmflag = dispersionflag = tip4pflag = dipoleflag = spinflag = 0; compute_flag = 1; group_group_enable = 0; stagger_flag = 0; @@ -192,6 +192,8 @@ void KSpace::pair_check() error->all(FLERR,"KSpace style is incompatible with Pair style"); if (dipoleflag && !force->pair->dipoleflag) error->all(FLERR,"KSpace style is incompatible with Pair style"); + if (spinflag && !force->pair->spinflag) + error->all(FLERR,"KSpace style is incompatible with Pair style"); if (tip4pflag && !force->pair->tip4pflag) error->all(FLERR,"KSpace style is incompatible with Pair style"); diff --git a/src/kspace.h b/src/kspace.h index 55ace5aa71..c049ad11f1 100644 --- a/src/kspace.h +++ b/src/kspace.h @@ -44,6 +44,7 @@ class KSpace : protected Pointers { int dispersionflag; // 1 if a LJ/dispersion solver int tip4pflag; // 1 if a TIP4P solver int dipoleflag; // 1 if a dipole solver + int spinflag; // 1 if a spin solver int differentiation_flag; int neighrequest_flag; // used to avoid obsolete construction // of neighbor lists diff --git a/src/pair.cpp b/src/pair.cpp index 5c308cc7ce..88fed646b4 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -72,7 +72,7 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp) single_extra = 0; svector = NULL; - ewaldflag = pppmflag = msmflag = dispersionflag = tip4pflag = dipoleflag = 0; + ewaldflag = pppmflag = msmflag = dispersionflag = tip4pflag = dipoleflag = spinflag = 0; reinitflag = 1; // pair_modify settings diff --git a/src/pair.h b/src/pair.h index 844bc0cdc7..f830b7c035 100644 --- a/src/pair.h +++ b/src/pair.h @@ -61,6 +61,7 @@ class Pair : protected Pointers { int dispersionflag; // 1 if compatible with LJ/dispersion solver int tip4pflag; // 1 if compatible with TIP4P solver int dipoleflag; // 1 if compatible with dipole solver + int spinflag; // 1 if compatible with spin long solver int reinitflag; // 1 if compatible with fix adapt and alike int tail_flag; // pair_modify flag for LJ tail correction diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index dc74dd040d..34359b8009 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -352,6 +352,7 @@ void PairHybrid::flags() if (styles[m]->pppmflag) pppmflag = 1; if (styles[m]->msmflag) msmflag = 1; if (styles[m]->dipoleflag) dipoleflag = 1; + if (styles[m]->spinflag) spinflag = 1; if (styles[m]->dispersionflag) dispersionflag = 1; if (styles[m]->tip4pflag) tip4pflag = 1; if (styles[m]->compute_flag) compute_flag = 1; -- GitLab From 9962f941e674e3dd18e76dec4ba5017e98832513 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sat, 18 Aug 2018 11:53:03 -0500 Subject: [PATCH 0035/1243] pair_kim - no need to comm vatom() values --- src/KIM/pair_kim.cpp | 86 +++----------------------------------------- 1 file changed, 5 insertions(+), 81 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index a298187c12..d6dfa9112c 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -476,8 +476,8 @@ void PairKIM::init_style() } - // make sure comm_reverse expects (at most) 9 values when newton is off - if (!lmps_using_newton) comm_reverse_off = 9; + // make sure comm_reverse expects (at most) 3 values when newton is off + if (!lmps_using_newton) comm_reverse_off = 3; // request full neighbor for (int i = 0; i < kim_number_of_neighbor_lists; ++i) @@ -543,9 +543,7 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) m = 0; last = first + n; - if ((kim_model_support_for_forces != notSupported) && - ((vflag_atom == 0) || - (kim_model_support_for_particleVirial == notSupported))) + if (kim_model_support_for_forces != notSupported) { for (i = first; i < last; i++) { @@ -555,42 +553,6 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) } return m; } - else if ((kim_model_support_for_forces != notSupported) && - (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) - { - double *va=&(vatom[0][0]); - for (i = first; i < last; i++) - { - buf[m++] = fp[3*i+0]; - buf[m++] = fp[3*i+1]; - buf[m++] = fp[3*i+2]; - - buf[m++] = va[6*i+0]; - buf[m++] = va[6*i+1]; - buf[m++] = va[6*i+2]; - buf[m++] = va[6*i+3]; - buf[m++] = va[6*i+4]; - buf[m++] = va[6*i+5]; - } - return m; - } - else if ((kim_model_support_for_forces == notSupported) && - (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) - { - double *va=&(vatom[0][0]); - for (i = first; i < last; i++) - { - buf[m++] = va[6*i+0]; - buf[m++] = va[6*i+1]; - buf[m++] = va[6*i+2]; - buf[m++] = va[6*i+3]; - buf[m++] = va[6*i+4]; - buf[m++] = va[6*i+5]; - } - return m; - } else return 0; } @@ -606,9 +568,7 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) fp = &(atom->f[0][0]); m = 0; - if ((kim_model_support_for_forces != notSupported) && - ((vflag_atom == 0) || - (kim_model_support_for_particleVirial == notSupported))) + if (kim_model_support_for_forces != notSupported) { for (i = 0; i < n; i++) { @@ -618,42 +578,6 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) fp[3*j+2]+= buf[m++]; } } - else if ((kim_model_support_for_forces != notSupported) && - (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) - { - double *va=&(vatom[0][0]); - for (i = 0; i < n; i++) - { - j = list[i]; - fp[3*j+0]+= buf[m++]; - fp[3*j+1]+= buf[m++]; - fp[3*j+2]+= buf[m++]; - - va[j*6+0]+=buf[m++]; - va[j*6+1]+=buf[m++]; - va[j*6+2]+=buf[m++]; - va[j*6+3]+=buf[m++]; - va[j*6+4]+=buf[m++]; - va[j*6+5]+=buf[m++]; - } - } - else if ((kim_model_support_for_forces == notSupported) && - (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) - { - double *va=&(vatom[0][0]); - for (i = 0; i < n; i++) - { - j = list[i]; - va[j*6+0]+=buf[m++]; - va[j*6+1]+=buf[m++]; - va[j*6+2]+=buf[m++]; - va[j*6+3]+=buf[m++]; - va[j*6+4]+=buf[m++]; - va[j*6+5]+=buf[m++]; - } - } else ;// do nothing @@ -875,7 +799,7 @@ void PairKIM::set_argument_pointers() } else if (kim_model_support_for_particleVirial != notSupported) { - kimerror = kimerror || pargs->SetArgumentPointer(partialParticleEnergy, + kimerror = kimerror || pargs->SetArgumentPointer(partialParticleVirial, &(vatom[0][0])); } -- GitLab From 7aa7002347f709af29016071538182c8157f8d87 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sat, 18 Aug 2018 12:02:22 -0500 Subject: [PATCH 0036/1243] Added check & error for KIM/LAMMPSvirial argument --- src/KIM/pair_kim.cpp | 12 +++++++++++- src/KIM/pair_kim.h | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index d6dfa9112c..f82617ee0e 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -308,7 +308,17 @@ void PairKIM::settings(int narg, char **arg) ++settings_call_count; init_style_call_count = 0; - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + if (narg != 1) + { + if ((narg > 0) && ((0 == strcmp("KIMvirial", argv[0])) || + (0 == strcmp("LAMMPSvirial", argv[0])))) + { + error->all(FLERR,"'KIMvirial' or 'LAMMPSvirial' not supported with " + "kim-api-v2."); + } + else + error->all(FLERR,"Illegal pair_style command"); + } // arg[0] is the KIM Model name lmps_using_molecular = (atom->molecular > 0); diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index e2be0855db..eef6e0345b 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -179,6 +179,10 @@ E: KIM Compute returned error The KIM model was unable, for some reason, to complete the computation. +E: 'KIMvirial' or 'LAMMPSvirial' not supported with kim-api-v2. + +"KIMvirial or "LAMMPSvirial" found on the pair_style line. These keys are not supported kim-api-v2. (The virial computation is always performed by LAMMPS.) Please remove these keys, make sure the KIM model you are using supports kim-api-v2, and rerun. + E: Illegal pair_style command Self-explanatory. -- GitLab From dd2a1e4787a927ccf00f34bd0dc6e7e5c4c7023f Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sat, 18 Aug 2018 12:38:29 -0500 Subject: [PATCH 0037/1243] Fix typos in pair_kim.cpp --- src/KIM/pair_kim.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index f82617ee0e..e209cb1202 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -310,8 +310,8 @@ void PairKIM::settings(int narg, char **arg) if (narg != 1) { - if ((narg > 0) && ((0 == strcmp("KIMvirial", argv[0])) || - (0 == strcmp("LAMMPSvirial", argv[0])))) + if ((narg > 0) && ((0 == strcmp("KIMvirial", arg[0])) || + (0 == strcmp("LAMMPSvirial", arg[0])))) { error->all(FLERR,"'KIMvirial' or 'LAMMPSvirial' not supported with " "kim-api-v2."); -- GitLab From 8d79db03d38061cf18c12954472ba64a79aa12ad Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 21 Aug 2018 13:47:38 -0600 Subject: [PATCH 0038/1243] Commit1 JT 082118 - created pppm_dipole_spin.h/cpp (child-class of pppm_dipole) - improved pair_spin_long.h/cpp - created documentation for pair_spin_long - new 3xN fm_long vector in atom_vec_spin (with associated comm) --- doc/src/Eqs/pair_spin_long_range.jpg | Bin 0 -> 11980 bytes doc/src/Eqs/pair_spin_long_range.tex | 20 + doc/src/Eqs/pair_spin_long_range_force.jpg | Bin 0 -> 16016 bytes doc/src/Eqs/pair_spin_long_range_force.tex | 23 + doc/src/Eqs/pair_spin_long_range_magforce.jpg | Bin 0 -> 9440 bytes doc/src/Eqs/pair_spin_long_range_magforce.tex | 17 + doc/src/pair_spin_long.txt | 84 ++ src/KSPACE/{pppm_spin.cpp => pppm_dipole.cpp} | 1030 ++++++++--------- src/KSPACE/pppm_dipole.h | 213 ++++ src/KSPACE/pppm_dipole_spin.cpp | 750 ++++++++++++ .../{pppm_spin.h => pppm_dipole_spin.h} | 71 +- src/SPIN/atom_vec_spin.cpp | 14 +- src/SPIN/atom_vec_spin.h | 8 +- src/SPIN/pair_spin_exchange.cpp | 3 - src/SPIN/pair_spin_long.cpp | 372 +++--- src/SPIN/pair_spin_long.h | 5 +- 16 files changed, 1849 insertions(+), 761 deletions(-) create mode 100644 doc/src/Eqs/pair_spin_long_range.jpg create mode 100644 doc/src/Eqs/pair_spin_long_range.tex create mode 100644 doc/src/Eqs/pair_spin_long_range_force.jpg create mode 100644 doc/src/Eqs/pair_spin_long_range_force.tex create mode 100644 doc/src/Eqs/pair_spin_long_range_magforce.jpg create mode 100644 doc/src/Eqs/pair_spin_long_range_magforce.tex create mode 100644 doc/src/pair_spin_long.txt rename src/KSPACE/{pppm_spin.cpp => pppm_dipole.cpp} (67%) create mode 100644 src/KSPACE/pppm_dipole.h create mode 100644 src/KSPACE/pppm_dipole_spin.cpp rename src/KSPACE/{pppm_spin.h => pppm_dipole_spin.h} (66%) diff --git a/doc/src/Eqs/pair_spin_long_range.jpg b/doc/src/Eqs/pair_spin_long_range.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bc133d10cf0a0a2a07db95afaf64961911f94084 GIT binary patch literal 11980 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

q<0Ze`RolKVoL|nhC(+nI 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 T(U-kcyhOt>LHzaK@c%afe_ySw literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/pair_spin_long_range_magforce.tex b/doc/src/Eqs/pair_spin_long_range_magforce.tex new file mode 100644 index 0000000000..ad40cf9d8b --- /dev/null +++ b/doc/src/Eqs/pair_spin_long_range_magforce.tex @@ -0,0 +1,17 @@ +\documentclass[preview]{standalone} +\usepackage{varwidth} +\usepackage[utf8x]{inputenc} +\usepackage{amsmath,amssymb,graphics,bm,setspace} + +\begin{document} +\begin{varwidth}{50in} + \begin{equation} + \bm{\omega}_i = + \frac{\mu_0 (\mu_B)^2}{4\pi\hbar}\sum_{j} + \frac{g_i g_j}{r_{ij}^3} + \, \Big( + 3\,(\bm{e}_{ij}\cdot\bm{s}_{j})\bm{e}_{ij} + -\bm{s}_{j} \Big) \nonumber + \end{equation} +\end{varwidth} +\end{document} diff --git a/doc/src/pair_spin_long.txt b/doc/src/pair_spin_long.txt new file mode 100644 index 0000000000..c5b4a7b33e --- /dev/null +++ b/doc/src/pair_spin_long.txt @@ -0,0 +1,84 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +pair_style spin/long command :h3 + +[Syntax:] + +pair_style spin/long cutoff (cutoff) + +cutoff = global cutoff pair (distance in metal units) :ulb,l +:ule + +[Examples:] + +pair_style spin/long 10.0 +pair_coeff * * long 10.0 +pair_coeff 2 3 long 8.0 :pre + +[Description:] + +Style {pair/spin/long} computes interactions between pairs of particles +that each have a magnetic spin. + +:c,image(Eqs/pair_spin_long_range.jpg) + +where si and sj are two magnetic spins of two particles with Lande factors +gi and gj respectively, eij = (ri - rj)/|ri-rj| is the unit vector between +sites i and j, mu0 the vacuum permeability, muB the Bohr magneton (muB = +5.788 eV/T in metal units). + +Style {pair/spin/long} computes magnetic precession vectors: + +:c,image(Eqs/pair_spin_long_range_magforce.jpg) + +with h the Planck constant (in metal units), and a mechanical force: + +:c,image(Eqs/pair_spin_long_range_force.jpg) + + +The following coefficient 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: + +rc (distance units) :ul + +with rc is the radius cutoff of the short-range component of the +long-range interaction (see "(Cerda)"_#Cerda1 for more +explanation). + +:line + +[Restrictions:] + +The {pair/spin/long} style is part of the SPIN 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 {pair/spin/long} style computes the short-range component of +the dipole-dipole interaction. The functions evaluating the +long-range component are part of the KSPACE package. +They can be enabled only if LAMMPS was built with that package. + +[Related commands:] + +"atom_style spin"_atom_style.html, "pair_coeff"_pair_coeff.html, + +[Default:] none + +:line + +:link(Tranchida6) +[(Tranchida)] Tranchida, Plimpton, Thibaudeau and Thompson, +Journal of Computational Physics, (2018). + +:link(Cerda1) +[(Cerda)] Cerda, Ballenegger, Lenz, and Holm, J Chem Phys, 129(23), +234104 (2008). diff --git a/src/KSPACE/pppm_spin.cpp b/src/KSPACE/pppm_dipole.cpp similarity index 67% rename from src/KSPACE/pppm_spin.cpp rename to src/KSPACE/pppm_dipole.cpp index 9b59f9cd7b..a03f5b9980 100644 --- a/src/KSPACE/pppm_spin.cpp +++ b/src/KSPACE/pppm_dipole.cpp @@ -21,7 +21,7 @@ #include #include #include -#include "pppm_spin.h" +#include "pppm_dipole.h" #include "atom.h" #include "comm.h" #include "gridcomm.h" @@ -50,8 +50,8 @@ using namespace MathSpecial; #define SMALL 0.00001 #define EPS_HOC 1.0e-7 -enum{REVERSE_SP}; -enum{FORWARD_SP,FORWARD_SP_PERATOM}; +enum{REVERSE_MU}; +enum{FORWARD_MU,FORWARD_MU_PERATOM}; #ifdef FFT_SINGLE #define ZEROF 0.0f @@ -63,34 +63,34 @@ enum{FORWARD_SP,FORWARD_SP_PERATOM}; /* ---------------------------------------------------------------------- */ -PPPMSpin::PPPMSpin(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg), - densityx_brick_spin(NULL), densityy_brick_spin(NULL), - densityz_brick_spin(NULL), ux_brick_spin(NULL), - uy_brick_spin(NULL), uz_brick_spin(NULL), vdxx_brick_spin(NULL), - vdxy_brick_spin(NULL), vdyy_brick_spin(NULL), - vdxz_brick_spin(NULL), vdyz_brick_spin(NULL), - vdzz_brick_spin(NULL), v0x_brick_spin(NULL), v1x_brick_spin(NULL), - v2x_brick_spin(NULL), v3x_brick_spin(NULL), v4x_brick_spin(NULL), - v5x_brick_spin(NULL), v0y_brick_spin(NULL), v1y_brick_spin(NULL), - v2y_brick_spin(NULL), v3y_brick_spin(NULL), v4y_brick_spin(NULL), - v5y_brick_spin(NULL), v0z_brick_spin(NULL), v1z_brick_spin(NULL), - v2z_brick_spin(NULL), v3z_brick_spin(NULL), v4z_brick_spin(NULL), - v5z_brick_spin(NULL), work3(NULL), work4(NULL), - densityx_fft_spin(NULL), densityy_fft_spin(NULL), - densityz_fft_spin(NULL) +PPPMDipole::PPPMDipole(LAMMPS *lmp, int narg, char **arg) : PPPM(lmp, narg, arg), + densityx_brick_dipole(NULL), densityy_brick_dipole(NULL), + densityz_brick_dipole(NULL), ux_brick_dipole(NULL), + uy_brick_dipole(NULL), uz_brick_dipole(NULL), vdxx_brick_dipole(NULL), + vdxy_brick_dipole(NULL), vdyy_brick_dipole(NULL), + vdxz_brick_dipole(NULL), vdyz_brick_dipole(NULL), + vdzz_brick_dipole(NULL), v0x_brick_dipole(NULL), v1x_brick_dipole(NULL), + v2x_brick_dipole(NULL), v3x_brick_dipole(NULL), v4x_brick_dipole(NULL), + v5x_brick_dipole(NULL), v0y_brick_dipole(NULL), v1y_brick_dipole(NULL), + v2y_brick_dipole(NULL), v3y_brick_dipole(NULL), v4y_brick_dipole(NULL), + v5y_brick_dipole(NULL), v0z_brick_dipole(NULL), v1z_brick_dipole(NULL), + v2z_brick_dipole(NULL), v3z_brick_dipole(NULL), v4z_brick_dipole(NULL), + v5z_brick_dipole(NULL), work3(NULL), work4(NULL), + densityx_fft_dipole(NULL), densityy_fft_dipole(NULL), + densityz_fft_dipole(NULL) { - spinflag = 1; + dipoleflag = 1; group_group_enable = 0; - cg_spin = NULL; - cg_peratom_spin = NULL; + cg_dipole = NULL; + cg_peratom_dipole = NULL; } /* ---------------------------------------------------------------------- free all memory ------------------------------------------------------------------------- */ -PPPMSpin::~PPPMSpin() +PPPMDipole::~PPPMDipole() { if (copymode) return; @@ -99,23 +99,26 @@ PPPMSpin::~PPPMSpin() fft1 = NULL; fft2 = NULL; remap = NULL; - cg_spin = NULL; + cg_dipole = NULL; } /* ---------------------------------------------------------------------- called once before run ------------------------------------------------------------------------- */ -void PPPMSpin::init() +void PPPMDipole::init() { if (me == 0) { - if (screen) fprintf(screen,"PPPMSpin initialization ...\n"); - if (logfile) fprintf(logfile,"PPPMSpin initialization ...\n"); + if (screen) fprintf(screen,"PPPMDipole initialization ...\n"); + if (logfile) fprintf(logfile,"PPPMDipole initialization ...\n"); } // error check - spinflag = atom->sp?1:0; + dipoleflag = atom->mu?1:0; + qsum_qsq(0); + if (dipoleflag && q2) + error->all(FLERR,"Cannot (yet) uses charges with Kspace style PPPMDipole"); triclinic_check(); @@ -123,30 +126,30 @@ void PPPMSpin::init() error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); if (domain->dimension == 2) error->all(FLERR, - "Cannot use PPPMSpin with 2d simulation"); + "Cannot use PPPMDipole with 2d simulation"); if (comm->style != 0) - error->universe_all(FLERR,"PPPMSpin can only currently be used with " + error->universe_all(FLERR,"PPPMDipole can only currently be used with " "comm_style brick"); - if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); + if (!atom->mu) error->all(FLERR,"Kspace style requires atom attribute mu"); - if (atom->sp && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" - " ad with spins"); + if (atom->mu && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" + " ad with dipoles"); - if (spinflag && strcmp(update->unit_style,"metal") != 0) - error->all(FLERR,"'metal' units have to be used with spins"); + if (dipoleflag && strcmp(update->unit_style,"electron") == 0) + error->all(FLERR,"Cannot (yet) use 'electron' units with dipoles"); if (slabflag == 0 && domain->nonperiodic > 0) - error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMSpin"); + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipole"); if (slabflag) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all(FLERR,"Incorrect boundaries with slab PPPMSpin"); + error->all(FLERR,"Incorrect boundaries with slab PPPMDipole"); } if (order < 2 || order > MAXORDER) { char str[128]; - sprintf(str,"PPPMSpin order cannot be < 2 or > than %d",MAXORDER); + sprintf(str,"PPPMDipole order cannot be < 2 or > than %d",MAXORDER); error->all(FLERR,str); } @@ -154,7 +157,7 @@ void PPPMSpin::init() triclinic = domain->triclinic; if (triclinic) - error->all(FLERR,"Cannot yet use triclinic cells with PPPMSpin"); + error->all(FLERR,"Cannot yet use triclinic cells with PPPMDipole"); pair_check(); @@ -167,21 +170,17 @@ void PPPMSpin::init() // kspace TIP4P not yet supported if (tip4pflag) - error->all(FLERR,"Cannot yet use TIP4P with PPPMSpin"); + error->all(FLERR,"Cannot yet use TIP4P with PPPMDipole"); + + // compute qsum & qsqsum and warn if not charge-neutral scale = 1.0; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz - spsum_spsq(); + qqrd2e = force->qqrd2e; + musum_musq(); natoms_original = atom->natoms; // set accuracy (force units) from accuracy_relative or accuracy_absolute - // is two_charge_force still relevant for spin systems? - if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute; else accuracy = accuracy_relative * two_charge_force; @@ -203,11 +202,11 @@ void PPPMSpin::init() while (order >= minorder) { if (iteration && me == 0) - error->warning(FLERR,"Reducing PPPMSpin order b/c stencil extends " + error->warning(FLERR,"Reducing PPPMDipole order b/c stencil extends " "beyond nearest neighbor processor"); compute_gf_denom(); - set_grid_global(); + set_grid_global(mu2); set_grid_local(); if (overlap_allowed) break; @@ -224,9 +223,9 @@ void PPPMSpin::init() iteration++; } - if (order < minorder) error->all(FLERR,"PPPMSpin order < minimum allowed order"); + if (order < minorder) error->all(FLERR,"PPPMDipole order < minimum allowed order"); if (!overlap_allowed && cgtmp->ghost_overlap()) - error->all(FLERR,"PPPMSpin grid stencil extends " + error->all(FLERR,"PPPMDipole grid stencil extends " "beyond nearest neighbor processor"); if (cgtmp) delete cgtmp; @@ -236,7 +235,7 @@ void PPPMSpin::init() // calculate the final accuracy - double estimated_accuracy = final_accuracy_spin(); + double estimated_accuracy = final_accuracy_dipole(mu2); // print stats @@ -282,10 +281,10 @@ void PPPMSpin::init() // don't invoke allocate peratom(), will be allocated when needed allocate(); - cg_spin->ghost_notify(); - cg_spin->setup(); + cg_dipole->ghost_notify(); + cg_dipole->setup(); - // pre-compute Green's function denominator expansion + // pre-compute Green's function denomiator expansion // pre-compute 1d charge distribution coefficients compute_gf_denom(); @@ -293,27 +292,27 @@ void PPPMSpin::init() } /* ---------------------------------------------------------------------- - adjust PPPMSpin coeffs, called initially and whenever volume has changed + adjust PPPMDipole coeffs, called initially and whenever volume has changed ------------------------------------------------------------------------- */ -void PPPMSpin::setup() +void PPPMDipole::setup() { // perform some checks to avoid illegal boundaries with read_data if (slabflag == 0 && domain->nonperiodic > 0) - error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMSpin"); + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipole"); if (slabflag) { if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) - error->all(FLERR,"Incorrect boundaries with slab PPPMSpin"); + error->all(FLERR,"Incorrect boundaries with slab PPPMDipole"); } int i,j,k,n; double *prd; // volume-dependent factors - // adjust z dimension for 2d slab PPPMSpin - // z dimension for 3d PPPMSpin is zprd since slab_volfactor = 1.0 + // adjust z dimension for 2d slab PPPMDipole + // z dimension for 3d PPPMDipole is zprd since slab_volfactor = 1.0 prd = domain->prd; double xprd = prd[0]; @@ -381,7 +380,7 @@ void PPPMSpin::setup() } } - compute_gf_spin(); + compute_gf_dipole(); } /* ---------------------------------------------------------------------- @@ -389,7 +388,7 @@ void PPPMSpin::setup() called by fix balance b/c it changed sizes of processor sub-domains ------------------------------------------------------------------------- */ -void PPPMSpin::setup_grid() +void PPPMDipole::setup_grid() { // free all arrays previously allocated @@ -406,11 +405,11 @@ void PPPMSpin::setup_grid() allocate(); - cg_spin->ghost_notify(); - if (overlap_allowed == 0 && cg_spin->ghost_overlap()) - error->all(FLERR,"PPPMSpin grid stencil extends " + cg_dipole->ghost_notify(); + if (overlap_allowed == 0 && cg_dipole->ghost_overlap()) + error->all(FLERR,"PPPMDipole grid stencil extends " "beyond nearest neighbor processor"); - cg_spin->setup(); + cg_dipole->setup(); // pre-compute Green's function denomiator expansion // pre-compute 1d charge distribution coefficients @@ -424,10 +423,10 @@ void PPPMSpin::setup_grid() } /* ---------------------------------------------------------------------- - compute the PPPMSpin long-range force, energy, virial + compute the PPPMDipole long-range force, energy, virial ------------------------------------------------------------------------- */ -void PPPMSpin::compute(int eflag, int vflag) +void PPPMDipole::compute(int eflag, int vflag) { int i,j; @@ -440,20 +439,20 @@ void PPPMSpin::compute(int eflag, int vflag) if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); - cg_peratom_spin->ghost_notify(); - cg_peratom_spin->setup(); + cg_peratom_dipole->ghost_notify(); + cg_peratom_dipole->setup(); } // if atom count has changed, update qsum and qsqsum if (atom->natoms != natoms_original) { - spsum_spsq(); + musum_musq(); natoms_original = atom->natoms; } - // return if there are no spins + // return if there are no dipoles - if (spsqsum == 0.0) return; + if (musqsum == 0.0) return; // convert atoms from box to lamda coords @@ -464,51 +463,51 @@ void PPPMSpin::compute(int eflag, int vflag) if (atom->nmax > nmax) { memory->destroy(part2grid); nmax = atom->nmax; - memory->create(part2grid,nmax,3,"pppm_spin:part2grid"); + memory->create(part2grid,nmax,3,"pppm_dipole:part2grid"); } // find grid points for all my particles - // map my particle charge onto my local 3d on-grid density + // map my particle charge onto my local 3d density grid particle_map(); - make_rho_spin(); + make_rho_dipole(); // all procs communicate density values from their ghost cells // to fully sum contribution in their 3d bricks // remap from 3d decomposition to FFT decomposition - cg_spin->reverse_comm(this,REVERSE_SP); - brick2fft_spin(); + cg_dipole->reverse_comm(this,REVERSE_MU); + brick2fft_dipole(); // compute potential gradient on my FFT grid and // portion of e_long on this proc's FFT grid // return gradients (electric fields) in 3d brick decomposition // also performs per-atom calculations via poisson_peratom() - poisson_ik_spin(); + poisson_ik_dipole(); // all procs communicate E-field values // to fill ghost cells surrounding their 3d bricks - cg_spin->forward_comm(this,FORWARD_SP); + cg_dipole->forward_comm(this,FORWARD_MU); // extra per-atom energy/virial communication if (evflag_atom) { - cg_peratom_spin->forward_comm(this,FORWARD_SP_PERATOM); + cg_peratom_dipole->forward_comm(this,FORWARD_MU_PERATOM); } // calculate the force on my particles - fieldforce_ik_spin(); + fieldforce_ik_dipole(); // extra per-atom energy/virial communication - if (evflag_atom) fieldforce_peratom_spin(); + if (evflag_atom) fieldforce_peratom_dipole(); // sum global energy across procs and add in volume-dependent term - const double spscale = mub2mu0 * scale; + const double qscale = qqrd2e * scale; const double g3 = g_ewald*g_ewald*g_ewald; if (eflag_global) { @@ -517,8 +516,8 @@ void PPPMSpin::compute(int eflag, int vflag) energy = energy_all; energy *= 0.5*volume; - energy -= spsqsum*2.0*g3/3.0/MY_PIS; - energy *= spscale; + energy -= musqsum*2.0*g3/3.0/MY_PIS; + energy *= qscale; } // sum global virial across procs @@ -526,32 +525,29 @@ void PPPMSpin::compute(int eflag, int vflag) if (vflag_global) { double virial_all[6]; MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); - for (i = 0; i < 6; i++) virial[i] = 0.5*spscale*volume*virial_all[i]; + for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i]; } // per-atom energy/virial // energy includes self-energy correction if (evflag_atom) { - double **sp = atom->sp; - double spx,spy,spz; + double *q = atom->q; + double **mu = atom->mu; int nlocal = atom->nlocal; int ntotal = nlocal; if (eflag_atom) { for (i = 0; i < nlocal; i++) { - spx = sp[i][0]*sp[i][3]; - spy = sp[i][1]*sp[i][3]; - spz = sp[i][2]*sp[i][3]; eatom[i] *= 0.5; - eatom[i] -= (spx*spx + spy*spy + spz*spz)*2.0*g3/3.0/MY_PIS; - eatom[i] *= spscale; + eatom[i] -= (mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2])*2.0*g3/3.0/MY_PIS; + eatom[i] *= qscale; } } if (vflag_atom) { for (i = 0; i < ntotal; i++) - for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*spscale; + for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*qscale; } } @@ -564,59 +560,59 @@ void PPPMSpin::compute(int eflag, int vflag) allocate memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMSpin::allocate() +void PPPMDipole::allocate() { - memory->create3d_offset(densityx_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:densityx_brick_spin"); - memory->create3d_offset(densityy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:densityy_brick_spin"); - memory->create3d_offset(densityz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:densityz_brick_spin"); - - memory->create(densityx_fft_spin,nfft_both,"pppm_spin:densityy_fft_spin"); - memory->create(densityy_fft_spin,nfft_both,"pppm_spin:densityy_fft_spin"); - memory->create(densityz_fft_spin,nfft_both,"pppm_spin:densityz_fft_spin"); - - memory->create(greensfn,nfft_both,"pppm_spin:greensfn"); - memory->create(work1,2*nfft_both,"pppm_spin:work1"); - memory->create(work2,2*nfft_both,"pppm_spin:work2"); - memory->create(work3,2*nfft_both,"pppm_spin:work3"); - memory->create(work4,2*nfft_both,"pppm_spin:work4"); - memory->create(vg,nfft_both,6,"pppm_spin:vg"); - - memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm_spin:fkx"); - memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm_spin:fky"); - memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm_spin:fkz"); - - memory->create3d_offset(ux_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:ux_brick_spin"); - memory->create3d_offset(uy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:uy_brick_spin"); - memory->create3d_offset(uz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:uz_brick_spin"); - - memory->create3d_offset(vdxx_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:vdxx_brick_spin"); - memory->create3d_offset(vdxy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:vdxy_brick_spin"); - memory->create3d_offset(vdyy_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:vdyy_brick_spin"); - memory->create3d_offset(vdxz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:vdxz_brick_spin"); - memory->create3d_offset(vdyz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:vdyz_brick_spin"); - memory->create3d_offset(vdzz_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:vdzz_brick_spin"); + memory->create3d_offset(densityx_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:densityx_brick_dipole"); + memory->create3d_offset(densityy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:densityy_brick_dipole"); + memory->create3d_offset(densityz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:densityz_brick_dipole"); + + memory->create(densityx_fft_dipole,nfft_both,"pppm_dipole:densityy_fft_dipole"); + memory->create(densityy_fft_dipole,nfft_both,"pppm_dipole:densityy_fft_dipole"); + memory->create(densityz_fft_dipole,nfft_both,"pppm_dipole:densityz_fft_dipole"); + + memory->create(greensfn,nfft_both,"pppm_dipole:greensfn"); + memory->create(work1,2*nfft_both,"pppm_dipole:work1"); + memory->create(work2,2*nfft_both,"pppm_dipole:work2"); + memory->create(work3,2*nfft_both,"pppm_dipole:work3"); + memory->create(work4,2*nfft_both,"pppm_dipole:work4"); + memory->create(vg,nfft_both,6,"pppm_dipole:vg"); + + memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm_dipole:fkx"); + memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm_dipole:fky"); + memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm_dipole:fkz"); + + memory->create3d_offset(ux_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:ux_brick_dipole"); + memory->create3d_offset(uy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:uy_brick_dipole"); + memory->create3d_offset(uz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:uz_brick_dipole"); + + memory->create3d_offset(vdxx_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdxx_brick_dipole"); + memory->create3d_offset(vdxy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdxy_brick_dipole"); + memory->create3d_offset(vdyy_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdyy_brick_dipole"); + memory->create3d_offset(vdxz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdxz_brick_dipole"); + memory->create3d_offset(vdyz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdyz_brick_dipole"); + memory->create3d_offset(vdzz_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:vdzz_brick_dipole"); // summation coeffs order_allocated = order; - memory->create(gf_b,order,"pppm_spin:gf_b"); - memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm_spin:rho1d"); - memory->create2d_offset(drho1d,3,-order/2,order/2,"pppm_spin:drho1d"); - memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm_spin:rho_coeff"); + memory->create(gf_b,order,"pppm_dipole:gf_b"); + memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm_dipole:rho1d"); + memory->create2d_offset(drho1d,3,-order/2,order/2,"pppm_dipole:drho1d"); + memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm_dipole:rho_coeff"); memory->create2d_offset(drho_coeff,order,(1-order)/2,order/2, - "pppm_spin:drho_coeff"); + "pppm_dipole:drho_coeff"); // create 2 FFTs and a Remap // 1st FFT keeps data in FFT decompostion @@ -644,7 +640,7 @@ void PPPMSpin::allocate() int (*procneigh)[2] = comm->procneigh; - cg_spin = new GridComm(lmp,world,9,3, + cg_dipole = new GridComm(lmp,world,9,3, nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, procneigh[0][0],procneigh[0][1],procneigh[1][0], @@ -655,26 +651,26 @@ void PPPMSpin::allocate() deallocate memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMSpin::deallocate() +void PPPMDipole::deallocate() { - memory->destroy3d_offset(densityx_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(densityy_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(densityz_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityx_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(densityz_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(ux_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(uy_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(uz_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(ux_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(uy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(uz_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdxx_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdxy_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdyy_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdxz_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdyz_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(vdzz_brick_spin,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxx_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdyy_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdxz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdyz_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(vdzz_brick_dipole,nzlo_out,nylo_out,nxlo_out); - memory->destroy(densityx_fft_spin); - memory->destroy(densityy_fft_spin); - memory->destroy(densityz_fft_spin); + memory->destroy(densityx_fft_dipole); + memory->destroy(densityy_fft_dipole); + memory->destroy(densityz_fft_dipole); memory->destroy(greensfn); memory->destroy(work1); @@ -696,61 +692,61 @@ void PPPMSpin::deallocate() delete fft1; delete fft2; delete remap; - delete cg_spin; + delete cg_dipole; } /* ---------------------------------------------------------------------- allocate per-atom memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMSpin::allocate_peratom() +void PPPMDipole::allocate_peratom() { peratom_allocate_flag = 1; - memory->create3d_offset(v0x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v0x_brick_spin"); - memory->create3d_offset(v1x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v1x_brick_spin"); - memory->create3d_offset(v2x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v2x_brick_spin"); - memory->create3d_offset(v3x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v3x_brick_spin"); - memory->create3d_offset(v4x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v4x_brick_spin"); - memory->create3d_offset(v5x_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v5x_brick_spin"); - - memory->create3d_offset(v0y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v0y_brick_spin"); - memory->create3d_offset(v1y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v1y_brick_spin"); - memory->create3d_offset(v2y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v2y_brick_spin"); - memory->create3d_offset(v3y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v3y_brick_spin"); - memory->create3d_offset(v4y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v4y_brick_spin"); - memory->create3d_offset(v5y_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v5y_brick_spin"); - - memory->create3d_offset(v0z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v0z_brick_spin"); - memory->create3d_offset(v1z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v1z_brick_spin"); - memory->create3d_offset(v2z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v2z_brick_spin"); - memory->create3d_offset(v3z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v3z_brick_spin"); - memory->create3d_offset(v4z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v4z_brick_spin"); - memory->create3d_offset(v5z_brick_spin,nzlo_out,nzhi_out,nylo_out,nyhi_out, - nxlo_out,nxhi_out,"pppm_spin:v5z_brick_spin"); + memory->create3d_offset(v0x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v0x_brick_dipole"); + memory->create3d_offset(v1x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v1x_brick_dipole"); + memory->create3d_offset(v2x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v2x_brick_dipole"); + memory->create3d_offset(v3x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v3x_brick_dipole"); + memory->create3d_offset(v4x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v4x_brick_dipole"); + memory->create3d_offset(v5x_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v5x_brick_dipole"); + + memory->create3d_offset(v0y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v0y_brick_dipole"); + memory->create3d_offset(v1y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v1y_brick_dipole"); + memory->create3d_offset(v2y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v2y_brick_dipole"); + memory->create3d_offset(v3y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v3y_brick_dipole"); + memory->create3d_offset(v4y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v4y_brick_dipole"); + memory->create3d_offset(v5y_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v5y_brick_dipole"); + + memory->create3d_offset(v0z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v0z_brick_dipole"); + memory->create3d_offset(v1z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v1z_brick_dipole"); + memory->create3d_offset(v2z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v2z_brick_dipole"); + memory->create3d_offset(v3z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v3z_brick_dipole"); + memory->create3d_offset(v4z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v4z_brick_dipole"); + memory->create3d_offset(v5z_brick_dipole,nzlo_out,nzhi_out,nylo_out,nyhi_out, + nxlo_out,nxhi_out,"pppm_dipole:v5z_brick_dipole"); // create ghost grid object for rho and electric field communication int (*procneigh)[2] = comm->procneigh; - cg_peratom_spin = + cg_peratom_dipole = new GridComm(lmp,world,18,1, nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, @@ -762,44 +758,44 @@ void PPPMSpin::allocate_peratom() deallocate per-atom memory that depends on # of K-vectors and order ------------------------------------------------------------------------- */ -void PPPMSpin::deallocate_peratom() +void PPPMDipole::deallocate_peratom() { peratom_allocate_flag = 0; - memory->destroy3d_offset(v0x_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v1x_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v2x_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v3x_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v4x_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v5x_brick_spin,nzlo_out,nylo_out,nxlo_out); - - memory->destroy3d_offset(v0y_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v1y_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v2y_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v3y_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v4y_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v5y_brick_spin,nzlo_out,nylo_out,nxlo_out); - - memory->destroy3d_offset(v0z_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v1z_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v2z_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v3z_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v4z_brick_spin,nzlo_out,nylo_out,nxlo_out); - memory->destroy3d_offset(v5z_brick_spin,nzlo_out,nylo_out,nxlo_out); - - delete cg_peratom_spin; + memory->destroy3d_offset(v0x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5x_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(v0y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5y_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + memory->destroy3d_offset(v0z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v1z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v2z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v3z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v4z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + memory->destroy3d_offset(v5z_brick_dipole,nzlo_out,nylo_out,nxlo_out); + + delete cg_peratom_dipole; } /* ---------------------------------------------------------------------- - set global size of PPPMSpin grid = nx,ny,nz_pppm + set global size of PPPMDipole grid = nx,ny,nz_pppm used for charge accumulation, FFTs, and electric field interpolation ------------------------------------------------------------------------- */ -void PPPMSpin::set_grid_global() +void PPPMDipole::set_grid_global(double dipole2) { // use xprd,yprd,zprd - // adjust z dimension for 2d slab PPPMSpin - // 3d PPPMSpin just uses zprd since slab_volfactor = 1.0 + // adjust z dimension for 2d slab PPPMDipole + // 3d PPPMDipole just uses zprd since slab_volfactor = 1.0 double xprd = domain->xprd; double yprd = domain->yprd; @@ -817,14 +813,16 @@ void PPPMSpin::set_grid_global() if (!gewaldflag) { if (accuracy <= 0.0) error->all(FLERR,"KSpace accuracy must be > 0"); - if (sp2 == 0.0) - error->all(FLERR,"Must use kspace_modify gewald for systems with no spins"); + //if (mu2 == 0.0) + if (dipole2 == 0.0) + error->all(FLERR,"Must use kspace_modify gewald for systems with no dipoles"); g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; //Try Newton Solver double g_ewald_new = - find_gewald_spin(g_ewald,cutoff,natoms,xprd*yprd*zprd,sp2); + find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,dipole2); + //find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); if (g_ewald_new > 0.0) g_ewald = g_ewald_new; - else error->warning(FLERR,"PPPMSpin spin Newton solver failed, " + else error->warning(FLERR,"PPPMDipole dipole Newton solver failed, " "using old method to estimate g_ewald"); } @@ -864,7 +862,7 @@ void PPPMSpin::set_grid_global() nzlo_fft = me_z*nz_pppm/npez_fft; nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1; - double df_kspace = compute_df_kspace_spin(); + double df_kspace = compute_df_kspace_dipole(dipole2); count++; @@ -889,31 +887,32 @@ void PPPMSpin::set_grid_global() h_z = zprd_slab/nz_pppm; if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET) - error->all(FLERR,"PPPMSpin grid is too large"); + error->all(FLERR,"PPPMDipole grid is too large"); } /* ---------------------------------------------------------------------- - compute estimated kspace force error for spins + compute estimated kspace force error for dipoles ------------------------------------------------------------------------- */ -double PPPMSpin::compute_df_kspace_spin() +double PPPMDipole::compute_df_kspace_dipole(double dipole2) { double xprd = domain->xprd; double yprd = domain->yprd; double zprd = domain->zprd; double zprd_slab = zprd*slab_volfactor; bigint natoms = atom->natoms; - double qopt = compute_qopt_spin(); - double df_kspace = sqrt(qopt/natoms)*sp2/(3.0*xprd*yprd*zprd_slab); + double qopt = compute_qopt_dipole(); + //double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); + double df_kspace = sqrt(qopt/natoms)*dipole2/(3.0*xprd*yprd*zprd_slab); return df_kspace; } /* ---------------------------------------------------------------------- - compute qopt for spins with ik differentiation + compute qopt for dipoles with ik differentiation ------------------------------------------------------------------------- */ -double PPPMSpin::compute_qopt_spin() +double PPPMDipole::compute_qopt_dipole() { double qopt = 0.0; const double * const prd = domain->prd; @@ -984,7 +983,7 @@ double PPPMSpin::compute_qopt_spin() dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz; dot2 = qx*qx + qy*qy + qz*qz; - //dot1 = dot1*dot1*dot1; // power of 3 for spin forces + //dot1 = dot1*dot1*dot1; // power of 3 for dipole forces //dot2 = dot2*dot2*dot2; u1 = sx*sy*sz; const double w2 = wx*wy*wz; @@ -1009,7 +1008,7 @@ double PPPMSpin::compute_qopt_spin() pre-compute modified (Hockney-Eastwood) Coulomb Green's function ------------------------------------------------------------------------- */ -void PPPMSpin::compute_gf_spin() +void PPPMDipole::compute_gf_dipole() { const double * const prd = domain->prd; @@ -1102,34 +1101,34 @@ void PPPMSpin::compute_gf_spin() calculate f(x) for use in Newton-Raphson solver ------------------------------------------------------------------------- */ -double PPPMSpin::newton_raphson_f() -{ - double xprd = domain->xprd; - double yprd = domain->yprd; - double zprd = domain->zprd; - bigint natoms = atom->natoms; - - double df_rspace,df_kspace; - double vol = xprd*yprd*zprd; - double a = cutoff*g_ewald; - double rg2 = a*a; - double rg4 = rg2*rg2; - double rg6 = rg4*rg2; - double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; - double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - df_rspace = (sp2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * - sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); - df_kspace = compute_df_kspace_spin(); - - return df_rspace - df_kspace; -} +//double PPPMDipole::newton_raphson_f() +//{ +// double xprd = domain->xprd; +// double yprd = domain->yprd; +// double zprd = domain->zprd; +// bigint natoms = atom->natoms; +// +// double df_rspace,df_kspace; +// double vol = xprd*yprd*zprd; +// double a = cutoff*g_ewald; +// double rg2 = a*a; +// double rg4 = rg2*rg2; +// double rg6 = rg4*rg2; +// double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; +// double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; +// df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * +// sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); +// df_kspace = compute_df_kspace_dipole(); +// +// return df_rspace - df_kspace; +//} /* ---------------------------------------------------------------------- - find g_ewald parameter for spins based on desired accuracy + find g_ewald parameter for dipoles based on desired accuracy using a Newton-Raphson solver ------------------------------------------------------------------------- */ -double PPPMSpin::find_gewald_spin(double x, double Rc, +double PPPMDipole::find_gewald_dipole(double x, double Rc, bigint natoms, double vol, double b2) { double dx,tol; @@ -1141,7 +1140,7 @@ double PPPMSpin::find_gewald_spin(double x, double Rc, //Begin algorithm for (int i = 0; i < maxit; i++) { - dx = newton_raphson_f_spin(x,Rc,natoms,vol,b2) / derivf_spin(x,Rc,natoms,vol,b2); + dx = newton_raphson_f_dipole(x,Rc,natoms,vol,b2) / derivf_dipole(x,Rc,natoms,vol,b2); x = x - dx; //Update x if (fabs(dx) < tol) return x; if (x < 0 || x != x) // solver failed @@ -1151,10 +1150,10 @@ double PPPMSpin::find_gewald_spin(double x, double Rc, } /* ---------------------------------------------------------------------- - calculate f(x) objective function for spins + calculate f(x) objective function for dipoles ------------------------------------------------------------------------- */ -double PPPMSpin::newton_raphson_f_spin(double x, double Rc, bigint +double PPPMDipole::newton_raphson_f_dipole(double x, double Rc, bigint natoms, double vol, double b2) { double a = Rc*x; @@ -1171,21 +1170,21 @@ natoms, double vol, double b2) } /* ---------------------------------------------------------------------- - calculate numerical derivative f'(x) of objective function for spins + calculate numerical derivative f'(x) of objective function for dipoles ------------------------------------------------------------------------- */ -double PPPMSpin::derivf_spin(double x, double Rc, +double PPPMDipole::derivf_dipole(double x, double Rc, bigint natoms, double vol, double b2) { double h = 0.000001; //Derivative step-size - return (newton_raphson_f_spin(x + h,Rc,natoms,vol,b2) - newton_raphson_f_spin(x,Rc,natoms,vol,b2)) / h; + return (newton_raphson_f_dipole(x + h,Rc,natoms,vol,b2) - newton_raphson_f_dipole(x,Rc,natoms,vol,b2)) / h; } /* ---------------------------------------------------------------------- calculate the final estimate of the accuracy ------------------------------------------------------------------------- */ -double PPPMSpin::final_accuracy_spin() +double PPPMDipole::final_accuracy_dipole(double dipole2) { double xprd = domain->xprd; double yprd = domain->yprd; @@ -1194,7 +1193,7 @@ double PPPMSpin::final_accuracy_spin() bigint natoms = atom->natoms; if (natoms == 0) natoms = 1; // avoid division by zero - double df_kspace = compute_df_kspace_spin(); + double df_kspace = compute_df_kspace_dipole(mu2); double a = cutoff*g_ewald; double rg2 = a*a; @@ -1202,7 +1201,10 @@ double PPPMSpin::final_accuracy_spin() double rg6 = rg4*rg2; double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - double df_rspace = (sp2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + //double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + // sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * + // exp(-rg2)); + double df_rspace = (dipole2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); @@ -1215,10 +1217,10 @@ double PPPMSpin::final_accuracy_spin() pre-compute Green's function denominator expansion coeffs, Gamma(2n) ------------------------------------------------------------------------- */ -void PPPMSpin::compute_gf_denom() +void PPPMDipole::compute_gf_denom() { if (gf_b) memory->destroy(gf_b); - memory->create(gf_b,order,"pppm_spin:gf_b"); + memory->create(gf_b,order,"pppm_dipole:gf_b"); int k,l,m; @@ -1244,7 +1246,7 @@ void PPPMSpin::compute_gf_denom() in global grid ------------------------------------------------------------------------- */ -void PPPMSpin::make_rho_spin() +void PPPMDipole::make_rho_dipole() { int l,m,n,nx,ny,nz,mx,my,mz; FFT_SCALAR dx,dy,dz; @@ -1254,11 +1256,11 @@ void PPPMSpin::make_rho_spin() // clear 3d density array - memset(&(densityx_brick_spin[nzlo_out][nylo_out][nxlo_out]),0, + memset(&(densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, ngrid*sizeof(FFT_SCALAR)); - memset(&(densityy_brick_spin[nzlo_out][nylo_out][nxlo_out]),0, + memset(&(densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, ngrid*sizeof(FFT_SCALAR)); - memset(&(densityz_brick_spin[nzlo_out][nylo_out][nxlo_out]),0, + memset(&(densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, ngrid*sizeof(FFT_SCALAR)); // loop over my charges, add their contribution to nearby grid points @@ -1266,8 +1268,7 @@ void PPPMSpin::make_rho_spin() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - double **sp = atom->sp; - double spx,spy,spz; + double **mu = atom->mu; double **x = atom->x; int nlocal = atom->nlocal; @@ -1282,12 +1283,9 @@ void PPPMSpin::make_rho_spin() compute_rho1d(dx,dy,dz); - spx = sp[i][0]*sp[i][3]; - spy = sp[i][1]*sp[i][3]; - spz = sp[i][2]*sp[i][3]; - z0 = delvolinv * spx; - z1 = delvolinv * spy; - z2 = delvolinv * spz; + z0 = delvolinv * mu[i][0]; + z1 = delvolinv * mu[i][1]; + z2 = delvolinv * mu[i][2]; for (n = nlower; n <= nupper; n++) { mz = n+nz; y0 = z0*rho1d[2][n]; @@ -1300,9 +1298,9 @@ void PPPMSpin::make_rho_spin() x2 = y2*rho1d[1][m]; for (l = nlower; l <= nupper; l++) { mx = l+nx; - densityx_brick_spin[mz][my][mx] += x0*rho1d[0][l]; - densityy_brick_spin[mz][my][mx] += x1*rho1d[0][l]; - densityz_brick_spin[mz][my][mx] += x2*rho1d[0][l]; + densityx_brick_dipole[mz][my][mx] += x0*rho1d[0][l]; + densityy_brick_dipole[mz][my][mx] += x1*rho1d[0][l]; + densityz_brick_dipole[mz][my][mx] += x2*rho1d[0][l]; } } } @@ -1313,7 +1311,7 @@ void PPPMSpin::make_rho_spin() remap density from 3d brick decomposition to FFT decomposition ------------------------------------------------------------------------- */ -void PPPMSpin::brick2fft_spin() +void PPPMDipole::brick2fft_dipole() { int n,ix,iy,iz; @@ -1325,36 +1323,36 @@ void PPPMSpin::brick2fft_spin() for (iz = nzlo_in; iz <= nzhi_in; iz++) for (iy = nylo_in; iy <= nyhi_in; iy++) for (ix = nxlo_in; ix <= nxhi_in; ix++) { - densityx_fft_spin[n] = densityx_brick_spin[iz][iy][ix]; - densityy_fft_spin[n] = densityy_brick_spin[iz][iy][ix]; - densityz_fft_spin[n] = densityz_brick_spin[iz][iy][ix]; + densityx_fft_dipole[n] = densityx_brick_dipole[iz][iy][ix]; + densityy_fft_dipole[n] = densityy_brick_dipole[iz][iy][ix]; + densityz_fft_dipole[n] = densityz_brick_dipole[iz][iy][ix]; n++; } - remap->perform(densityx_fft_spin,densityx_fft_spin,work1); - remap->perform(densityy_fft_spin,densityy_fft_spin,work1); - remap->perform(densityz_fft_spin,densityz_fft_spin,work1); + remap->perform(densityx_fft_dipole,densityx_fft_dipole,work1); + remap->perform(densityy_fft_dipole,densityy_fft_dipole,work1); + remap->perform(densityz_fft_dipole,densityz_fft_dipole,work1); } /* ---------------------------------------------------------------------- FFT-based Poisson solver for ik ------------------------------------------------------------------------- */ -void PPPMSpin::poisson_ik_spin() +void PPPMDipole::poisson_ik_dipole() { int i,j,k,n,ii; double eng; double wreal,wimg; - // transform spin density (r -> k) + // transform dipole density (r -> k) n = 0; for (i = 0; i < nfft; i++) { - work1[n] = densityx_fft_spin[i]; + work1[n] = densityx_fft_dipole[i]; work1[n+1] = ZEROF; - work2[n] = densityy_fft_spin[i]; + work2[n] = densityy_fft_dipole[i]; work2[n+1] = ZEROF; - work3[n] = densityz_fft_spin[i]; + work3[n] = densityz_fft_dipole[i]; work3[n+1] = ZEROF; n += 2; } @@ -1421,7 +1419,7 @@ void PPPMSpin::poisson_ik_spin() // extra FFTs for per-atom energy/virial - if (vflag_atom) poisson_peratom_spin(); + if (vflag_atom) poisson_peratom_dipole(); // compute electric potential // FFT leaves data in 3d brick decomposition @@ -1443,7 +1441,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - ux_brick_spin[k][j][i] = work4[n]; + ux_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1464,7 +1462,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - uy_brick_spin[k][j][i] = work4[n]; + uy_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1485,7 +1483,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - uz_brick_spin[k][j][i] = work4[n]; + uz_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1506,7 +1504,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdxx_brick_spin[k][j][i] = work4[n]; + vdxx_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1527,7 +1525,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdyy_brick_spin[k][j][i] = work4[n]; + vdyy_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1548,7 +1546,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdzz_brick_spin[k][j][i] = work4[n]; + vdzz_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1569,7 +1567,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdxy_brick_spin[k][j][i] = work4[n]; + vdxy_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1590,7 +1588,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdxz_brick_spin[k][j][i] = work4[n]; + vdxz_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1611,7 +1609,7 @@ void PPPMSpin::poisson_ik_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - vdyz_brick_spin[k][j][i] = work4[n]; + vdyz_brick_dipole[k][j][i] = work4[n]; n += 2; } } @@ -1620,7 +1618,7 @@ void PPPMSpin::poisson_ik_spin() FFT-based Poisson solver for per-atom energy/virial ------------------------------------------------------------------------- */ -void PPPMSpin::poisson_peratom_spin() +void PPPMDipole::poisson_peratom_dipole() { int i,ii,j,k,n; @@ -1647,7 +1645,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v0x_brick_spin[k][j][i] = work4[n]; + v0x_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1670,7 +1668,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v0y_brick_spin[k][j][i] = work4[n]; + v0y_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1693,7 +1691,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v0z_brick_spin[k][j][i] = work4[n]; + v0z_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1716,7 +1714,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v1x_brick_spin[k][j][i] = work4[n]; + v1x_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1739,7 +1737,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v1y_brick_spin[k][j][i] = work4[n]; + v1y_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1762,7 +1760,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v1z_brick_spin[k][j][i] = work4[n]; + v1z_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1785,7 +1783,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v2x_brick_spin[k][j][i] = work4[n]; + v2x_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1808,7 +1806,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v2y_brick_spin[k][j][i] = work4[n]; + v2y_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1831,7 +1829,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v2z_brick_spin[k][j][i] = work4[n]; + v2z_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1854,7 +1852,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v3x_brick_spin[k][j][i] = work4[n]; + v3x_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1877,7 +1875,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v3y_brick_spin[k][j][i] = work4[n]; + v3y_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1900,7 +1898,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v3z_brick_spin[k][j][i] = work4[n]; + v3z_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1923,7 +1921,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v4x_brick_spin[k][j][i] = work4[n]; + v4x_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1946,7 +1944,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v4y_brick_spin[k][j][i] = work4[n]; + v4y_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1969,7 +1967,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v4z_brick_spin[k][j][i] = work4[n]; + v4z_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -1992,7 +1990,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v5x_brick_spin[k][j][i] = work4[n]; + v5x_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -2015,7 +2013,7 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v5y_brick_spin[k][j][i] = work4[n]; + v5y_brick_dipole[k][j][i] = work4[n]; n += 2; } @@ -2038,16 +2036,16 @@ void PPPMSpin::poisson_peratom_spin() for (k = nzlo_in; k <= nzhi_in; k++) for (j = nylo_in; j <= nyhi_in; j++) for (i = nxlo_in; i <= nxhi_in; i++) { - v5z_brick_spin[k][j][i] = work4[n]; + v5z_brick_dipole[k][j][i] = work4[n]; n += 2; } } /* ---------------------------------------------------------------------- - interpolate from grid to get magnetic field & force on my particles for ik + interpolate from grid to get electric field & force on my particles for ik ------------------------------------------------------------------------- */ -void PPPMSpin::fieldforce_ik_spin() +void PPPMDipole::fieldforce_ik_dipole() { int i,l,m,n,nx,ny,nz,mx,my,mz; FFT_SCALAR dx,dy,dz; @@ -2060,11 +2058,11 @@ void PPPMSpin::fieldforce_ik_spin() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - double **sp = atom->sp; - double spx,spy,spz; + + double **mu = atom->mu; double **x = atom->x; double **f = atom->f; - double **fm = atom->fm; + double **t = atom->torque; int nlocal = atom->nlocal; @@ -2089,36 +2087,29 @@ void PPPMSpin::fieldforce_ik_spin() for (l = nlower; l <= nupper; l++) { mx = l+nx; x0 = y0*rho1d[0][l]; - ex -= x0*ux_brick_spin[mz][my][mx]; - ey -= x0*uy_brick_spin[mz][my][mx]; - ez -= x0*uz_brick_spin[mz][my][mx]; - vxx -= x0*vdxx_brick_spin[mz][my][mx]; - vyy -= x0*vdyy_brick_spin[mz][my][mx]; - vzz -= x0*vdzz_brick_spin[mz][my][mx]; - vxy -= x0*vdxy_brick_spin[mz][my][mx]; - vxz -= x0*vdxz_brick_spin[mz][my][mx]; - vyz -= x0*vdyz_brick_spin[mz][my][mx]; + ex -= x0*ux_brick_dipole[mz][my][mx]; + ey -= x0*uy_brick_dipole[mz][my][mx]; + ez -= x0*uz_brick_dipole[mz][my][mx]; + vxx -= x0*vdxx_brick_dipole[mz][my][mx]; + vyy -= x0*vdyy_brick_dipole[mz][my][mx]; + vzz -= x0*vdzz_brick_dipole[mz][my][mx]; + vxy -= x0*vdxy_brick_dipole[mz][my][mx]; + vxz -= x0*vdxz_brick_dipole[mz][my][mx]; + vyz -= x0*vdyz_brick_dipole[mz][my][mx]; } } } - // convert M-field to mech. and mag. forces - - const double spfactor = mub2mu0 * scale; - spx = sp[i][0]*sp[i][3]; - spy = sp[i][1]*sp[i][3]; - spz = sp[i][2]*sp[i][3]; - f[i][0] += spfactor*(vxx*spx + vxy*spy + vxz*spz); - f[i][1] += spfactor*(vxy*spx + vyy*spy + vyz*spz); - f[i][2] += spfactor*(vxz*spx + vyz*spy + vzz*spz); + // convert E-field to torque - const double spfactorh = mub2mu0hbinv * scale; - fm[i][0] += spfactorh*ex; - fm[i][1] += spfactorh*ey; - fm[i][2] += spfactorh*ez; - - // create a new vector (in atom_spin style ?) to store long-range fm tables + const double mufactor = qqrd2e * scale; + f[i][0] += mufactor*(vxx*mu[i][0] + vxy*mu[i][1] + vxz*mu[i][2]); + f[i][1] += mufactor*(vxy*mu[i][0] + vyy*mu[i][1] + vyz*mu[i][2]); + f[i][2] += mufactor*(vxz*mu[i][0] + vyz*mu[i][1] + vzz*mu[i][2]); + t[i][0] += mufactor*(mu[i][1]*ez - mu[i][2]*ey); + t[i][1] += mufactor*(mu[i][2]*ex - mu[i][0]*ez); + t[i][2] += mufactor*(mu[i][0]*ey - mu[i][1]*ex); } } @@ -2126,7 +2117,7 @@ void PPPMSpin::fieldforce_ik_spin() interpolate from grid to get per-atom energy/virial ------------------------------------------------------------------------- */ -void PPPMSpin::fieldforce_peratom_spin() +void PPPMDipole::fieldforce_peratom_dipole() { int i,l,m,n,nx,ny,nz,mx,my,mz; FFT_SCALAR dx,dy,dz,x0,y0,z0; @@ -2140,8 +2131,7 @@ void PPPMSpin::fieldforce_peratom_spin() // (dx,dy,dz) = distance to "lower left" grid pt // (mx,my,mz) = global coords of moving stencil pt - double **sp = atom->sp; - double spx,spy,spz; + double **mu = atom->mu; double **x = atom->x; int nlocal = atom->nlocal; @@ -2170,45 +2160,42 @@ void PPPMSpin::fieldforce_peratom_spin() mx = l+nx; x0 = y0*rho1d[0][l]; if (eflag_atom) { - ux += x0*ux_brick_spin[mz][my][mx]; - uy += x0*uy_brick_spin[mz][my][mx]; - uz += x0*uz_brick_spin[mz][my][mx]; + ux += x0*ux_brick_dipole[mz][my][mx]; + uy += x0*uy_brick_dipole[mz][my][mx]; + uz += x0*uz_brick_dipole[mz][my][mx]; } if (vflag_atom) { - v0x += x0*v0x_brick_spin[mz][my][mx]; - v1x += x0*v1x_brick_spin[mz][my][mx]; - v2x += x0*v2x_brick_spin[mz][my][mx]; - v3x += x0*v3x_brick_spin[mz][my][mx]; - v4x += x0*v4x_brick_spin[mz][my][mx]; - v5x += x0*v5x_brick_spin[mz][my][mx]; - v0y += x0*v0y_brick_spin[mz][my][mx]; - v1y += x0*v1y_brick_spin[mz][my][mx]; - v2y += x0*v2y_brick_spin[mz][my][mx]; - v3y += x0*v3y_brick_spin[mz][my][mx]; - v4y += x0*v4y_brick_spin[mz][my][mx]; - v5y += x0*v5y_brick_spin[mz][my][mx]; - v0z += x0*v0z_brick_spin[mz][my][mx]; - v1z += x0*v1z_brick_spin[mz][my][mx]; - v2z += x0*v2z_brick_spin[mz][my][mx]; - v3z += x0*v3z_brick_spin[mz][my][mx]; - v4z += x0*v4z_brick_spin[mz][my][mx]; - v5z += x0*v5z_brick_spin[mz][my][mx]; + v0x += x0*v0x_brick_dipole[mz][my][mx]; + v1x += x0*v1x_brick_dipole[mz][my][mx]; + v2x += x0*v2x_brick_dipole[mz][my][mx]; + v3x += x0*v3x_brick_dipole[mz][my][mx]; + v4x += x0*v4x_brick_dipole[mz][my][mx]; + v5x += x0*v5x_brick_dipole[mz][my][mx]; + v0y += x0*v0y_brick_dipole[mz][my][mx]; + v1y += x0*v1y_brick_dipole[mz][my][mx]; + v2y += x0*v2y_brick_dipole[mz][my][mx]; + v3y += x0*v3y_brick_dipole[mz][my][mx]; + v4y += x0*v4y_brick_dipole[mz][my][mx]; + v5y += x0*v5y_brick_dipole[mz][my][mx]; + v0z += x0*v0z_brick_dipole[mz][my][mx]; + v1z += x0*v1z_brick_dipole[mz][my][mx]; + v2z += x0*v2z_brick_dipole[mz][my][mx]; + v3z += x0*v3z_brick_dipole[mz][my][mx]; + v4z += x0*v4z_brick_dipole[mz][my][mx]; + v5z += x0*v5z_brick_dipole[mz][my][mx]; } } } } - spx = sp[i][0]*sp[i][3]; - spy = sp[i][1]*sp[i][3]; - spz = sp[i][2]*sp[i][3]; - if (eflag_atom) eatom[i] += spx*ux + spy*uy + spz*uz; + if (eflag_atom) eatom[i] += mu[i][0]*ux + mu[i][1]*uy + mu[i][2]*uz; if (vflag_atom) { - vatom[i][0] += spx*v0x + spy*v0y + spz*v0z; - vatom[i][1] += spx*v1x + spy*v1y + spz*v1z; - vatom[i][2] += spx*v2x + spy*v2y + spz*v2z; - vatom[i][3] += spx*v3x + spy*v3y + spz*v3z; - vatom[i][4] += spx*v4x + spy*v4y + spz*v4z; - vatom[i][5] += spx*v5x + spy*v5y + spz*v5z; + vatom[i][0] += mu[i][0]*v0x + mu[i][1]*v0y + mu[i][2]*v0z; + vatom[i][1] += mu[i][0]*v1x + mu[i][1]*v1y + mu[i][2]*v1z; + vatom[i][2] += mu[i][0]*v2x + mu[i][1]*v2y + mu[i][2]*v2z; + vatom[i][3] += mu[i][0]*v3x + mu[i][1]*v3y + mu[i][2]*v3z; + vatom[i][4] += mu[i][0]*v4x + mu[i][1]*v4y + mu[i][2]*v4z; + vatom[i][5] += mu[i][0]*v5x + mu[i][1]*v5y + mu[i][2]*v5z; } } } @@ -2217,20 +2204,20 @@ void PPPMSpin::fieldforce_peratom_spin() pack own values to buf to send to another proc ------------------------------------------------------------------------- */ -void PPPMSpin::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMDipole::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == FORWARD_SP) { - FFT_SCALAR *src_ux = &ux_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_uy = &uy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_uz = &uz_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vxx = &vdxx_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vyy = &vdyy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vzz = &vdzz_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vxy = &vdxy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vxz = &vdxz_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_vyz = &vdyz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + if (flag == FORWARD_MU) { + FFT_SCALAR *src_ux = &ux_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_uy = &uy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_uz = &uz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxx = &vdxx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vyy = &vdyy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vzz = &vdzz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxy = &vdxy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vxz = &vdxz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_vyz = &vdyz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { buf[n++] = src_ux[list[i]]; buf[n++] = src_uy[list[i]]; @@ -2242,25 +2229,25 @@ void PPPMSpin::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) buf[n++] = src_vxz[list[i]]; buf[n++] = src_vyz[list[i]]; } - } else if (flag == FORWARD_SP_PERATOM) { - FFT_SCALAR *v0xsrc = &v0x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1xsrc = &v1x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2xsrc = &v2x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3xsrc = &v3x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4xsrc = &v4x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5xsrc = &v5x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0ysrc = &v0y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1ysrc = &v1y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2ysrc = &v2y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3ysrc = &v3y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4ysrc = &v4y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5ysrc = &v5y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0zsrc = &v0z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1zsrc = &v1z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2zsrc = &v2z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3zsrc = &v3z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4zsrc = &v4z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5zsrc = &v5z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + } else if (flag == FORWARD_MU_PERATOM) { + FFT_SCALAR *v0xsrc = &v0x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1xsrc = &v1x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2xsrc = &v2x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3xsrc = &v3x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4xsrc = &v4x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5xsrc = &v5x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0ysrc = &v0y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1ysrc = &v1y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2ysrc = &v2y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3ysrc = &v3y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4ysrc = &v4y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5ysrc = &v5y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0zsrc = &v0z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1zsrc = &v1z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2zsrc = &v2z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3zsrc = &v3z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4zsrc = &v4z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5zsrc = &v5z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { buf[n++] = v0xsrc[list[i]]; buf[n++] = v1xsrc[list[i]]; @@ -2288,20 +2275,20 @@ void PPPMSpin::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) unpack another proc's own values from buf and set own ghost values ------------------------------------------------------------------------- */ -void PPPMSpin::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMDipole::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == FORWARD_SP) { - FFT_SCALAR *dest_ux = &ux_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_uy = &uy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_uz = &uz_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vxx = &vdxx_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vyy = &vdyy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vzz = &vdzz_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vxy = &vdxy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vxz = &vdxz_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_vyz = &vdyz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + if (flag == FORWARD_MU) { + FFT_SCALAR *dest_ux = &ux_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_uy = &uy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_uz = &uz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxx = &vdxx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vyy = &vdyy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vzz = &vdzz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxy = &vdxy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vxz = &vdxz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_vyz = &vdyz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { dest_ux[list[i]] = buf[n++]; dest_uy[list[i]] = buf[n++]; @@ -2313,25 +2300,25 @@ void PPPMSpin::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) dest_vxz[list[i]] = buf[n++]; dest_vyz[list[i]] = buf[n++]; } - } else if (flag == FORWARD_SP_PERATOM) { - FFT_SCALAR *v0xsrc = &v0x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1xsrc = &v1x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2xsrc = &v2x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3xsrc = &v3x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4xsrc = &v4x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5xsrc = &v5x_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0ysrc = &v0y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1ysrc = &v1y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2ysrc = &v2y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3ysrc = &v3y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4ysrc = &v4y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5ysrc = &v5y_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v0zsrc = &v0z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v1zsrc = &v1z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v2zsrc = &v2z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v3zsrc = &v3z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v4zsrc = &v4z_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *v5zsrc = &v5z_brick_spin[nzlo_out][nylo_out][nxlo_out]; + } else if (flag == FORWARD_MU_PERATOM) { + FFT_SCALAR *v0xsrc = &v0x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1xsrc = &v1x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2xsrc = &v2x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3xsrc = &v3x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4xsrc = &v4x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5xsrc = &v5x_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0ysrc = &v0y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1ysrc = &v1y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2ysrc = &v2y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3ysrc = &v3y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4ysrc = &v4y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5ysrc = &v5y_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v0zsrc = &v0z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v1zsrc = &v1z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v2zsrc = &v2z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v3zsrc = &v3z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v4zsrc = &v4z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *v5zsrc = &v5z_brick_dipole[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { v0xsrc[list[i]] = buf[n++]; v1xsrc[list[i]] = buf[n++]; @@ -2359,17 +2346,17 @@ void PPPMSpin::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list) pack ghost values into buf to send to another proc ------------------------------------------------------------------------- */ -void PPPMSpin::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMDipole::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == REVERSE_SP) { - FFT_SCALAR *src_spin0 = &densityx_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_spin1 = &densityy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *src_spin2 = &densityz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + if (flag == REVERSE_MU) { + FFT_SCALAR *src_dipole0 = &densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_dipole1 = &densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *src_dipole2 = &densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { - buf[n++] = src_spin0[list[i]]; - buf[n++] = src_spin1[list[i]]; - buf[n++] = src_spin2[list[i]]; + buf[n++] = src_dipole0[list[i]]; + buf[n++] = src_dipole1[list[i]]; + buf[n++] = src_dipole2[list[i]]; } } } @@ -2378,17 +2365,17 @@ void PPPMSpin::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) unpack another proc's ghost values from buf and add to own values ------------------------------------------------------------------------- */ -void PPPMSpin::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) +void PPPMDipole::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) { int n = 0; - if (flag == REVERSE_SP) { - FFT_SCALAR *dest_spin0 = &densityx_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_spin1 = &densityy_brick_spin[nzlo_out][nylo_out][nxlo_out]; - FFT_SCALAR *dest_spin2 = &densityz_brick_spin[nzlo_out][nylo_out][nxlo_out]; + if (flag == REVERSE_MU) { + FFT_SCALAR *dest_dipole0 = &densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_dipole1 = &densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]; + FFT_SCALAR *dest_dipole2 = &densityz_brick_dipole[nzlo_out][nylo_out][nxlo_out]; for (int i = 0; i < nlist; i++) { - dest_spin0[list[i]] += buf[n++]; - dest_spin1[list[i]] += buf[n++]; - dest_spin2[list[i]] += buf[n++]; + dest_dipole0[list[i]] += buf[n++]; + dest_dipole1[list[i]] += buf[n++]; + dest_dipole2[list[i]] += buf[n++]; } } } @@ -2401,50 +2388,57 @@ void PPPMSpin::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list) extended to non-neutral systems (J. Chem. Phys. 131, 094107). ------------------------------------------------------------------------- */ -void PPPMSpin::slabcorr() +void PPPMDipole::slabcorr() { - // compute local contribution to global spin moment + // compute local contribution to global dipole moment double **x = atom->x; double zprd = domain->zprd; int nlocal = atom->nlocal; - double spin = 0.0; - double **sp = atom->sp; - double spx,spy,spz; - for (int i = 0; i < nlocal; i++) { - spz = sp[i][2]*sp[i][3]; - spin += spz; - } + double dipole = 0.0; + double **mu = atom->mu; + for (int i = 0; i < nlocal; i++) dipole += mu[i][2]; + + // sum local contributions to get global dipole moment + + double dipole_all; + MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world); - // sum local contributions to get global spin moment + // need to make non-neutral systems and/or + // per-atom energy translationally invariant - double spin_all; - MPI_Allreduce(&spin,&spin_all,1,MPI_DOUBLE,MPI_SUM,world); + if (eflag_atom || fabs(qsum) > SMALL) { + + error->all(FLERR,"Cannot (yet) use kspace slab correction with " + "long-range dipoles and non-neutral systems or per-atom energy"); + } // compute corrections - const double e_slabcorr = MY_2PI*(spin_all*spin_all/12.0)/volume; - const double spscale = mub2mu0 * scale; + const double e_slabcorr = MY_2PI*(dipole_all*dipole_all/12.0)/volume; + const double qscale = qqrd2e * scale; - if (eflag_global) energy += spscale * e_slabcorr; + if (eflag_global) energy += qscale * e_slabcorr; // per-atom energy if (eflag_atom) { - double efact = spscale * MY_2PI/volume/12.0; - for (int i = 0; i < nlocal; i++) { - spz = sp[i][2]*sp[i][3]; - eatom[i] += efact * spz * spin_all; - } + double efact = qscale * MY_2PI/volume/12.0; + for (int i = 0; i < nlocal; i++) + eatom[i] += efact * mu[i][2]*dipole_all; } - // add on mag. force corrections + // add on torque corrections - double ffact = spscale * (-4.0*MY_PI/volume); - double **fm = atom->fm; - for (int i = 0; i < nlocal; i++) { - fm[i][2] += ffact * spin_all; + if (atom->torque) { + double ffact = qscale * (-4.0*MY_PI/volume); + double **mu = atom->mu; + double **torque = atom->torque; + for (int i = 0; i < nlocal; i++) { + torque[i][0] += ffact * dipole_all * mu[i][1]; + torque[i][1] += -ffact * dipole_all * mu[i][0]; + } } } @@ -2452,7 +2446,7 @@ void PPPMSpin::slabcorr() perform and time the 1d FFTs required for N timesteps ------------------------------------------------------------------------- */ -int PPPMSpin::timing_1d(int n, double &time1d) +int PPPMDipole::timing_1d(int n, double &time1d) { double time1,time2; @@ -2487,7 +2481,7 @@ int PPPMSpin::timing_1d(int n, double &time1d) perform and time the 3d FFTs required for N timesteps ------------------------------------------------------------------------- */ -int PPPMSpin::timing_3d(int n, double &time3d) +int PPPMDipole::timing_3d(int n, double &time3d) { double time1,time2; @@ -2522,7 +2516,7 @@ int PPPMSpin::timing_3d(int n, double &time3d) memory usage of local arrays ------------------------------------------------------------------------- */ -double PPPMSpin::memory_usage() +double PPPMDipole::memory_usage() { double bytes = nmax*3 * sizeof(double); int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) * @@ -2536,43 +2530,37 @@ double PPPMSpin::memory_usage() if (peratom_allocate_flag) bytes += 21 * nbrick * sizeof(FFT_SCALAR); - if (cg_spin) bytes += cg_spin->memory_usage(); - if (cg_peratom_spin) bytes += cg_peratom_spin->memory_usage(); + if (cg_dipole) bytes += cg_dipole->memory_usage(); + if (cg_peratom_dipole) bytes += cg_peratom_dipole->memory_usage(); return bytes; } /* ---------------------------------------------------------------------- - compute spsum,spsqsum,sp2 - called initially, when particle count changes, when spins are changed + compute musum,musqsum,mu2 + called initially, when particle count changes, when dipoles are changed ------------------------------------------------------------------------- */ -void PPPMSpin::spsum_spsq() +void PPPMDipole::musum_musq() { const int nlocal = atom->nlocal; - spsum = spsqsum = sp2 = 0.0; - if (atom->sp_flag) { - double **sp = atom->sp; - double spx, spy, spz; - double spsum_local(0.0), spsqsum_local(0.0); - - // not exactly the good loop: need to add norm of spins + musum = musqsum = mu2 = 0.0; + if (atom->mu_flag) { + double** mu = atom->mu; + double musum_local(0.0), musqsum_local(0.0); for (int i = 0; i < nlocal; i++) { - spx = sp[i][0]*sp[i][3]; - spy = sp[i][1]*sp[i][3]; - spz = sp[i][2]*sp[i][3]; - spsum_local += spx + spy + spz; - spsqsum_local += spx*spx + spy*spy + spz*spz; + musum_local += mu[i][0] + mu[i][1] + mu[i][2]; + musqsum_local += mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]; } - MPI_Allreduce(&spsum_local,&spsum,1,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(&spsqsum_local,&spsqsum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&musum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&musqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); - sp2 = spsqsum * mub2mu0; + mu2 = musqsum * force->qqrd2e; } - if (sp2 == 0 && comm->me == 0) - error->all(FLERR,"Using kspace solver PPPMSpin on system with no spins"); + if (mu2 == 0 && comm->me == 0) + error->all(FLERR,"Using kspace solver PPPMDipole on system with no dipoles"); } diff --git a/src/KSPACE/pppm_dipole.h b/src/KSPACE/pppm_dipole.h new file mode 100644 index 0000000000..8db28b540a --- /dev/null +++ b/src/KSPACE/pppm_dipole.h @@ -0,0 +1,213 @@ +/* -*- 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 KSPACE_CLASS + +KSpaceStyle(pppm/dipole,PPPMDipole) + +#else + +#ifndef LMP_PPPM_DIPOLE_H +#define LMP_PPPM_DIPOLE_H + +#include "pppm.h" + +namespace LAMMPS_NS { + +class PPPMDipole : public PPPM { + public: + PPPMDipole(class LAMMPS *, int, char **); + virtual ~PPPMDipole(); + void init(); + void setup(); + void setup_grid(); + void compute(int, int); + int timing_1d(int, double &); + int timing_3d(int, double &); + double memory_usage(); + + protected: + void set_grid_global(double); + //double newton_raphson_f(); + + void allocate(); + void allocate_peratom(); + void deallocate(); + void deallocate_peratom(); + void compute_gf_denom(); + + void slabcorr(); + + // grid communication + + void pack_forward(int, FFT_SCALAR *, int, int *); + void unpack_forward(int, FFT_SCALAR *, int, int *); + void pack_reverse(int, FFT_SCALAR *, int, int *); + void unpack_reverse(int, FFT_SCALAR *, int, int *); + + // dipole + + FFT_SCALAR ***densityx_brick_dipole,***densityy_brick_dipole,***densityz_brick_dipole; + FFT_SCALAR ***vdxx_brick_dipole,***vdyy_brick_dipole,***vdzz_brick_dipole; + FFT_SCALAR ***vdxy_brick_dipole,***vdxz_brick_dipole,***vdyz_brick_dipole; + FFT_SCALAR ***ux_brick_dipole,***uy_brick_dipole,***uz_brick_dipole; + FFT_SCALAR ***v0x_brick_dipole,***v1x_brick_dipole,***v2x_brick_dipole; + FFT_SCALAR ***v3x_brick_dipole,***v4x_brick_dipole,***v5x_brick_dipole; + FFT_SCALAR ***v0y_brick_dipole,***v1y_brick_dipole,***v2y_brick_dipole; + FFT_SCALAR ***v3y_brick_dipole,***v4y_brick_dipole,***v5y_brick_dipole; + FFT_SCALAR ***v0z_brick_dipole,***v1z_brick_dipole,***v2z_brick_dipole; + FFT_SCALAR ***v3z_brick_dipole,***v4z_brick_dipole,***v5z_brick_dipole; + FFT_SCALAR *work3,*work4; + FFT_SCALAR *densityx_fft_dipole,*densityy_fft_dipole,*densityz_fft_dipole; + class GridComm *cg_dipole; + class GridComm *cg_peratom_dipole; + int only_dipole_flag; + double musum,musqsum,mu2; + double find_gewald_dipole(double, double, bigint, double, double); + double newton_raphson_f_dipole(double, double, bigint, double, double); + double derivf_dipole(double, double, bigint, double, double); + double compute_df_kspace_dipole(double); + double compute_qopt_dipole(); + void compute_gf_dipole(); + void make_rho_dipole(); + void brick2fft_dipole(); + void poisson_ik_dipole(); + void poisson_peratom_dipole(); + void fieldforce_ik_dipole(); + void fieldforce_peratom_dipole(); + double final_accuracy_dipole(double dipole2); + void musum_musq(); + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Cannot (yet) use charges with Kspace style PPPMDipole + +Charge-dipole interactions are not yet implemented in PPPMDipole so this +feature is not yet supported. + +E: Must redefine kspace_style after changing to triclinic box + +Self-explanatory. + +E: Kspace style requires atom attribute mu + +The atom style defined does not have this attribute. + +E: Cannot (yet) use kspace_modify diff ad with dipoles + +This feature is not yet supported. + +E: Cannot (yet) use 'electron' units with dipoles + +This feature is not yet supported. + +E: Cannot yet use triclinic cells with PPPMDipole + +This feature is not yet supported. + +E: Cannot yet use TIP4P with PPPMDipole + +This feature is not yet supported. + +E: Cannot use nonperiodic boundaries with PPPM + +For kspace style pppm, all 3 dimensions must have periodic boundaries +unless you use the kspace_modify command to define a 2d slab with a +non-periodic z dimension. + +E: Incorrect boundaries with slab PPPM + +Must have periodic x,y dimensions and non-periodic z dimension to use +2d slab option with PPPM. + +E: PPPM order cannot be < 2 or > than %d + +This is a limitation of the PPPM implementation in LAMMPS. + +E: KSpace style is incompatible with Pair style + +Setting a kspace style requires that a pair style with matching +long-range dipole components be used. + +W: Reducing PPPM order b/c stencil extends beyond nearest neighbor processor + +This may lead to a larger grid than desired. See the kspace_modify overlap +command to prevent changing of the PPPM order. + +E: PPPM order < minimum allowed order + +The default minimum order is 2. This can be reset by the +kspace_modify minorder command. + +E: PPPM grid stencil extends beyond nearest neighbor processor + +This is not allowed if the kspace_modify overlap setting is no. + +E: KSpace accuracy must be > 0 + +The kspace accuracy designated in the input must be greater than zero. + +E: Could not compute grid size + +The code is unable to compute a grid size consistent with the desired +accuracy. This error should not occur for typical problems. Please +send an email to the developers. + +E: PPPM grid is too large + +The global PPPM grid is larger than OFFSET in one or more dimensions. +OFFSET is currently set to 4096. You likely need to decrease the +requested accuracy. + +E: Could not compute g_ewald + +The Newton-Raphson solver failed to converge to a good value for +g_ewald. This error should not occur for typical problems. Please +send an email to the developers. + +E: Non-numeric box dimensions - simulation unstable + +The box size has apparently blown up. + +E: Out of range atoms - cannot compute PPPM + +One or more atoms are attempting to map their charge to a PPPM grid +point that is not owned by a processor. This is likely for one of two +reasons, both of them bad. First, it may mean that an atom near the +boundary of a processor's sub-domain has moved more than 1/2 the +"neighbor skin distance"_neighbor.html without neighbor lists being +rebuilt and atoms being migrated to new processors. This also means +you may be missing pairwise interactions that need to be computed. +The solution is to change the re-neighboring criteria via the +"neigh_modify"_neigh_modify command. The safest settings are "delay 0 +every 1 check yes". Second, it may mean that an atom has moved far +outside a processor's sub-domain or even the entire simulation box. +This indicates bad physics, e.g. due to highly overlapping atoms, too +large a timestep, etc. + +E: Using kspace solver PPPMDipole on system with no dipoles + +Must have non-zero dipoles with PPPMDipole. + +E: Must use kspace_modify gewald for system with no dipoles + +Self-explanatory. + +*/ diff --git a/src/KSPACE/pppm_dipole_spin.cpp b/src/KSPACE/pppm_dipole_spin.cpp new file mode 100644 index 0000000000..4fde7ba101 --- /dev/null +++ b/src/KSPACE/pppm_dipole_spin.cpp @@ -0,0 +1,750 @@ +/* ---------------------------------------------------------------------- + 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: Stan Moore (SNL) + Julien Tranchida (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include "pppm_dipole_spin.h" +#include "atom.h" +#include "comm.h" +#include "gridcomm.h" +#include "neighbor.h" +#include "force.h" +#include "pair.h" +#include "bond.h" +#include "angle.h" +#include "domain.h" +#include "fft3d_wrap.h" +#include "remap_wrap.h" +#include "memory.h" +#include "error.h" +#include "update.h" + +#include "math_const.h" +#include "math_special.h" + +using namespace LAMMPS_NS; +using namespace MathConst; +using namespace MathSpecial; + +#define MAXORDER 7 +#define OFFSET 16384 +#define LARGE 10000.0 +#define SMALL 0.00001 +#define EPS_HOC 1.0e-7 + +enum{REVERSE_SP}; +enum{FORWARD_SP,FORWARD_SP_PERATOM}; + +#ifdef FFT_SINGLE +#define ZEROF 0.0f +#define ONEF 1.0f +#else +#define ZEROF 0.0 +#define ONEF 1.0 +#endif + +/* ---------------------------------------------------------------------- */ + +PPPMDipoleSpin::PPPMDipoleSpin(LAMMPS *lmp, int narg, char **arg) : + PPPMDipole(lmp, narg, arg) +{ + dipoleflag = 0; + spinflag = 1; + group_group_enable = 0; + + cg_dipole = NULL; + cg_peratom_dipole = NULL; +} + +/* ---------------------------------------------------------------------- + free all memory +------------------------------------------------------------------------- */ + +PPPMDipoleSpin::~PPPMDipoleSpin() +{ + if (copymode) return; + + deallocate(); + if (peratom_allocate_flag) deallocate_peratom(); + fft1 = NULL; + fft2 = NULL; + remap = NULL; + cg_dipole = NULL; +} + +/* ---------------------------------------------------------------------- + called once before run +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::init() +{ + if (me == 0) { + if (screen) fprintf(screen,"PPPMDipoleSpin initialization ...\n"); + if (logfile) fprintf(logfile,"PPPMDipoleSpin initialization ...\n"); + } + + // error check + + spinflag = atom->sp?1:0; + + triclinic_check(); + + if (triclinic != domain->triclinic) + error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); + + if (domain->dimension == 2) error->all(FLERR, + "Cannot use PPPMDipoleSpin with 2d simulation"); + if (comm->style != 0) + error->universe_all(FLERR,"PPPMDipoleSpin can only currently be used with " + "comm_style brick"); + + if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); + + if (atom->sp && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" + " ad with spins"); + + if (spinflag && strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"'metal' units have to be used with spins"); + + if (slabflag == 0 && domain->nonperiodic > 0) + error->all(FLERR,"Cannot use nonperiodic boundaries with PPPMDipoleSpin"); + if (slabflag) { + if (domain->xperiodic != 1 || domain->yperiodic != 1 || + domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) + error->all(FLERR,"Incorrect boundaries with slab PPPMDipoleSpin"); + } + + if (order < 2 || order > MAXORDER) { + char str[128]; + sprintf(str,"PPPMDipoleSpin order cannot be < 2 or > than %d",MAXORDER); + error->all(FLERR,str); + } + + // extract short-range Coulombic cutoff from pair style + + triclinic = domain->triclinic; + if (triclinic) + error->all(FLERR,"Cannot yet use triclinic cells with PPPMDipoleSpin"); + + pair_check(); + + int itmp = 0; + double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); + if (p_cutoff == NULL) + error->all(FLERR,"KSpace style is incompatible with Pair style"); + cutoff = *p_cutoff; + + // kspace TIP4P not yet supported + + if (tip4pflag) + error->all(FLERR,"Cannot yet use TIP4P with PPPMDipoleSpin"); + + scale = 1.0; + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + spsum_spsq(); + natoms_original = atom->natoms; + + // set accuracy (force units) from accuracy_relative or accuracy_absolute + + // is two_charge_force still relevant for spin systems? + + if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute; + else accuracy = accuracy_relative * two_charge_force; + + // free all arrays previously allocated + + deallocate(); + if (peratom_allocate_flag) deallocate_peratom(); + + // setup FFT grid resolution and g_ewald + // normally one iteration thru while loop is all that is required + // if grid stencil does not extend beyond neighbor proc + // or overlap is allowed, then done + // else reduce order and try again + + int (*procneigh)[2] = comm->procneigh; + + GridComm *cgtmp = NULL; + int iteration = 0; + + while (order >= minorder) { + if (iteration && me == 0) + error->warning(FLERR,"Reducing PPPMDipoleSpin order b/c stencil extends " + "beyond nearest neighbor processor"); + + compute_gf_denom(); + set_grid_global(sp2); + set_grid_local(); + if (overlap_allowed) break; + + cgtmp = new GridComm(lmp,world,1,1, + nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in, + nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out, + procneigh[0][0],procneigh[0][1],procneigh[1][0], + procneigh[1][1],procneigh[2][0],procneigh[2][1]); + cgtmp->ghost_notify(); + if (!cgtmp->ghost_overlap()) break; + delete cgtmp; + + order--; + iteration++; + } + + if (order < minorder) error->all(FLERR,"PPPMDipoleSpin order < minimum allowed order"); + if (!overlap_allowed && cgtmp->ghost_overlap()) + error->all(FLERR,"PPPMDipoleSpin grid stencil extends " + "beyond nearest neighbor processor"); + if (cgtmp) delete cgtmp; + + // adjust g_ewald + + if (!gewaldflag) adjust_gewald(); + + // calculate the final accuracy + + double estimated_accuracy = final_accuracy_dipole(sp2); + + // print stats + + int ngrid_max,nfft_both_max; + MPI_Allreduce(&ngrid,&ngrid_max,1,MPI_INT,MPI_MAX,world); + MPI_Allreduce(&nfft_both,&nfft_both_max,1,MPI_INT,MPI_MAX,world); + + if (me == 0) { + +#ifdef FFT_SINGLE + const char fft_prec[] = "single"; +#else + const char fft_prec[] = "double"; +#endif + + if (screen) { + fprintf(screen," G vector (1/distance) = %g\n",g_ewald); + fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); + fprintf(screen," stencil order = %d\n",order); + fprintf(screen," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(screen," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(screen," using %s precision FFTs\n",fft_prec); + fprintf(screen," 3d grid and FFT values/proc = %d %d\n", + ngrid_max,nfft_both_max); + } + if (logfile) { + fprintf(logfile," G vector (1/distance) = %g\n",g_ewald); + fprintf(logfile," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm); + fprintf(logfile," stencil order = %d\n",order); + fprintf(logfile," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(logfile," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(logfile," using %s precision FFTs\n",fft_prec); + fprintf(logfile," 3d grid and FFT values/proc = %d %d\n", + ngrid_max,nfft_both_max); + } + } + + // allocate K-space dependent memory + // don't invoke allocate peratom(), will be allocated when needed + + allocate(); + cg_dipole->ghost_notify(); + cg_dipole->setup(); + + // pre-compute Green's function denominator expansion + // pre-compute 1d charge distribution coefficients + + compute_gf_denom(); + compute_rho_coeff(); +} + +/* ---------------------------------------------------------------------- + compute the PPPMDipoleSpin long-range force, energy, virial +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::compute(int eflag, int vflag) +{ + int i,j; + + // set energy/virial flags + // invoke allocate_peratom() if needed for first time + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = evflag_atom = eflag_global = vflag_global = + eflag_atom = vflag_atom = 0; + + if (evflag_atom && !peratom_allocate_flag) { + allocate_peratom(); + cg_peratom_dipole->ghost_notify(); + cg_peratom_dipole->setup(); + } + + // if atom count has changed, update qsum and qsqsum + + if (atom->natoms != natoms_original) { + spsum_spsq(); + natoms_original = atom->natoms; + } + + // return if there are no spins + + if (spsqsum == 0.0) return; + + // convert atoms from box to lamda coords + + boxlo = domain->boxlo; + + // extend size of per-atom arrays if necessary + + if (atom->nmax > nmax) { + memory->destroy(part2grid); + nmax = atom->nmax; + memory->create(part2grid,nmax,3,"pppm_spin:part2grid"); + } + + // find grid points for all my particles + // map my particle charge onto my local 3d on-grid density + + particle_map(); + make_rho_spin(); + + // all procs communicate density values from their ghost cells + // to fully sum contribution in their 3d bricks + // remap from 3d decomposition to FFT decomposition + + cg_dipole->reverse_comm(this,REVERSE_SP); + brick2fft_dipole(); + + // compute potential gradient on my FFT grid and + // portion of e_long on this proc's FFT grid + // return gradients (electric fields) in 3d brick decomposition + // also performs per-atom calculations via poisson_peratom() + + poisson_ik_dipole(); + + // all procs communicate E-field values + // to fill ghost cells surrounding their 3d bricks + + cg_dipole->forward_comm(this,FORWARD_SP); + + // extra per-atom energy/virial communication + + if (evflag_atom) { + cg_peratom_dipole->forward_comm(this,FORWARD_SP_PERATOM); + } + + // calculate the force on my particles + + fieldforce_ik_spin(); + + // extra per-atom energy/virial communication + + if (evflag_atom) fieldforce_peratom_spin(); + + // sum global energy across procs and add in volume-dependent term + + const double spscale = mub2mu0 * scale; + const double g3 = g_ewald*g_ewald*g_ewald; + + if (eflag_global) { + double energy_all; + MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world); + energy = energy_all; + + energy *= 0.5*volume; + energy -= spsqsum*2.0*g3/3.0/MY_PIS; + energy *= spscale; + } + + // sum global virial across procs + + if (vflag_global) { + double virial_all[6]; + MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world); + for (i = 0; i < 6; i++) virial[i] = 0.5*spscale*volume*virial_all[i]; + } + + // per-atom energy/virial + // energy includes self-energy correction + + if (evflag_atom) { + double **sp = atom->sp; + double spx,spy,spz; + int nlocal = atom->nlocal; + int ntotal = nlocal; + + if (eflag_atom) { + for (i = 0; i < nlocal; i++) { + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + eatom[i] *= 0.5; + eatom[i] -= (spx*spx + spy*spy + spz*spz)*2.0*g3/3.0/MY_PIS; + eatom[i] *= spscale; + } + } + + if (vflag_atom) { + for (i = 0; i < ntotal; i++) + for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*spscale; + } + } + + // 2d slab correction + + if (slabflag == 1) slabcorr(); +} + +/* ---------------------------------------------------------------------- + create discretized "density" on section of global grid due to my particles + density(x,y,z) = charge "density" at grid points of my 3d brick + (nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts) + in global grid +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::make_rho_spin() +{ + int l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz; + FFT_SCALAR x0,y0,z0; + FFT_SCALAR x1,y1,z1; + FFT_SCALAR x2,y2,z2; + + // clear 3d density array + + memset(&(densityx_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + ngrid*sizeof(FFT_SCALAR)); + memset(&(densityy_brick_dipole[nzlo_out][nylo_out][nxlo_out]),0, + ngrid*sizeof(FFT_SCALAR)); + memset(&(densityz_brick_dipole[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 + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + + double **sp = atom->sp; + double spx,spy,spz; + double **x = atom->x; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + z0 = delvolinv * spx; + z1 = delvolinv * spy; + z2 = delvolinv * spz; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + y0 = z0*rho1d[2][n]; + y1 = z1*rho1d[2][n]; + y2 = z2*rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + x0 = y0*rho1d[1][m]; + x1 = y1*rho1d[1][m]; + x2 = y2*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + densityx_brick_dipole[mz][my][mx] += x0*rho1d[0][l]; + densityy_brick_dipole[mz][my][mx] += x1*rho1d[0][l]; + densityz_brick_dipole[mz][my][mx] += x2*rho1d[0][l]; + } + } + } + } +} + +/* ---------------------------------------------------------------------- + interpolate from grid to get magnetic field & force on my particles for ik +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::fieldforce_ik_spin() +{ + int i,l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz; + FFT_SCALAR x0,y0,z0; + FFT_SCALAR ex,ey,ez; + FFT_SCALAR vxx,vyy,vzz,vxy,vxz,vyz; + + // loop over my charges, interpolate electric field from nearby grid points + // (nx,ny,nz) = global coords of grid pt to "lower left" of charge + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + + double **sp = atom->sp; + double spx,spy,spz; + double **x = atom->x; + double **f = atom->f; + double **fm = atom->fm; + + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) { + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + ex = ey = ez = ZEROF; + vxx = vyy = vzz = vxy = vxz = vyz = ZEROF; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + z0 = rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + y0 = z0*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + x0 = y0*rho1d[0][l]; + ex -= x0*ux_brick_dipole[mz][my][mx]; + ey -= x0*uy_brick_dipole[mz][my][mx]; + ez -= x0*uz_brick_dipole[mz][my][mx]; + vxx -= x0*vdxx_brick_dipole[mz][my][mx]; + vyy -= x0*vdyy_brick_dipole[mz][my][mx]; + vzz -= x0*vdzz_brick_dipole[mz][my][mx]; + vxy -= x0*vdxy_brick_dipole[mz][my][mx]; + vxz -= x0*vdxz_brick_dipole[mz][my][mx]; + vyz -= x0*vdyz_brick_dipole[mz][my][mx]; + } + } + } + + // convert M-field to mech. and mag. forces + + const double spfactor = mub2mu0 * scale; + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + f[i][0] += spfactor*(vxx*spx + vxy*spy + vxz*spz); + f[i][1] += spfactor*(vxy*spx + vyy*spy + vyz*spz); + f[i][2] += spfactor*(vxz*spx + vyz*spy + vzz*spz); + + const double spfactorh = mub2mu0hbinv * scale; + fm[i][0] += spfactorh*ex; + fm[i][1] += spfactorh*ey; + fm[i][2] += spfactorh*ez; + + // create a new vector (in atom_spin style ?) to store long-range fm tables + + } +} + +/* ---------------------------------------------------------------------- + interpolate from grid to get per-atom energy/virial +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::fieldforce_peratom_spin() +{ + int i,l,m,n,nx,ny,nz,mx,my,mz; + FFT_SCALAR dx,dy,dz,x0,y0,z0; + FFT_SCALAR ux,uy,uz; + FFT_SCALAR v0x,v1x,v2x,v3x,v4x,v5x; + FFT_SCALAR v0y,v1y,v2y,v3y,v4y,v5y; + FFT_SCALAR v0z,v1z,v2z,v3z,v4z,v5z; + + // loop over my charges, interpolate from nearby grid points + // (nx,ny,nz) = global coords of grid pt to "lower left" of charge + // (dx,dy,dz) = distance to "lower left" grid pt + // (mx,my,mz) = global coords of moving stencil pt + + double **sp = atom->sp; + double spx,spy,spz; + double **x = atom->x; + + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) { + nx = part2grid[i][0]; + ny = part2grid[i][1]; + nz = part2grid[i][2]; + dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv; + dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv; + dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv; + + compute_rho1d(dx,dy,dz); + + ux = uy = uz = ZEROF; + v0x = v1x = v2x = v3x = v4x = v5x = ZEROF; + v0y = v1y = v2y = v3y = v4y = v5y = ZEROF; + v0z = v1z = v2z = v3z = v4z = v5z = ZEROF; + for (n = nlower; n <= nupper; n++) { + mz = n+nz; + z0 = rho1d[2][n]; + for (m = nlower; m <= nupper; m++) { + my = m+ny; + y0 = z0*rho1d[1][m]; + for (l = nlower; l <= nupper; l++) { + mx = l+nx; + x0 = y0*rho1d[0][l]; + if (eflag_atom) { + ux += x0*ux_brick_dipole[mz][my][mx]; + uy += x0*uy_brick_dipole[mz][my][mx]; + uz += x0*uz_brick_dipole[mz][my][mx]; + } + if (vflag_atom) { + v0x += x0*v0x_brick_dipole[mz][my][mx]; + v1x += x0*v1x_brick_dipole[mz][my][mx]; + v2x += x0*v2x_brick_dipole[mz][my][mx]; + v3x += x0*v3x_brick_dipole[mz][my][mx]; + v4x += x0*v4x_brick_dipole[mz][my][mx]; + v5x += x0*v5x_brick_dipole[mz][my][mx]; + v0y += x0*v0y_brick_dipole[mz][my][mx]; + v1y += x0*v1y_brick_dipole[mz][my][mx]; + v2y += x0*v2y_brick_dipole[mz][my][mx]; + v3y += x0*v3y_brick_dipole[mz][my][mx]; + v4y += x0*v4y_brick_dipole[mz][my][mx]; + v5y += x0*v5y_brick_dipole[mz][my][mx]; + v0z += x0*v0z_brick_dipole[mz][my][mx]; + v1z += x0*v1z_brick_dipole[mz][my][mx]; + v2z += x0*v2z_brick_dipole[mz][my][mx]; + v3z += x0*v3z_brick_dipole[mz][my][mx]; + v4z += x0*v4z_brick_dipole[mz][my][mx]; + v5z += x0*v5z_brick_dipole[mz][my][mx]; + } + } + } + } + + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + if (eflag_atom) eatom[i] += spx*ux + spy*uy + spz*uz; + if (vflag_atom) { + vatom[i][0] += spx*v0x + spy*v0y + spz*v0z; + vatom[i][1] += spx*v1x + spy*v1y + spz*v1z; + vatom[i][2] += spx*v2x + spy*v2y + spz*v2z; + vatom[i][3] += spx*v3x + spy*v3y + spz*v3z; + vatom[i][4] += spx*v4x + spy*v4y + spz*v4z; + vatom[i][5] += spx*v5x + spy*v5y + spz*v5z; + } + } +} + +/* ---------------------------------------------------------------------- + Slab-geometry correction term to dampen inter-slab interactions between + periodically repeating slabs. Yields good approximation to 2D Ewald if + adequate empty space is left between repeating slabs (J. Chem. Phys. + 111, 3155). Slabs defined here to be parallel to the xy plane. Also + extended to non-neutral systems (J. Chem. Phys. 131, 094107). +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::slabcorr() +{ + // compute local contribution to global spin moment + + double **x = atom->x; + double zprd = domain->zprd; + int nlocal = atom->nlocal; + + double spin = 0.0; + double **sp = atom->sp; + double spx,spy,spz; + for (int i = 0; i < nlocal; i++) { + spz = sp[i][2]*sp[i][3]; + spin += spz; + } + + // sum local contributions to get global spin moment + + double spin_all; + MPI_Allreduce(&spin,&spin_all,1,MPI_DOUBLE,MPI_SUM,world); + + // compute corrections + + const double e_slabcorr = MY_2PI*(spin_all*spin_all/12.0)/volume; + const double spscale = mub2mu0 * scale; + + if (eflag_global) energy += spscale * e_slabcorr; + + // per-atom energy + + if (eflag_atom) { + double efact = spscale * MY_2PI/volume/12.0; + for (int i = 0; i < nlocal; i++) { + spz = sp[i][2]*sp[i][3]; + eatom[i] += efact * spz * spin_all; + } + } + + // add on mag. force corrections + + double ffact = spscale * (-4.0*MY_PI/volume); + double **fm = atom->fm; + for (int i = 0; i < nlocal; i++) { + fm[i][2] += ffact * spin_all; + } +} + +/* ---------------------------------------------------------------------- + compute spsum,spsqsum,sp2 + called initially, when particle count changes, when spins are changed +------------------------------------------------------------------------- */ + +void PPPMDipoleSpin::spsum_spsq() +{ + const int nlocal = atom->nlocal; + + spsum = spsqsum = sp2 = 0.0; + if (atom->sp_flag) { + double **sp = atom->sp; + double spx, spy, spz; + double spsum_local(0.0), spsqsum_local(0.0); + + // not exactly the good loop: need to add norm of spins + + for (int i = 0; i < nlocal; i++) { + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + spsum_local += spx + spy + spz; + spsqsum_local += spx*spx + spy*spy + spz*spz; + } + + MPI_Allreduce(&spsum_local,&spsum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&spsqsum_local,&spsqsum,1,MPI_DOUBLE,MPI_SUM,world); + + sp2 = spsqsum * mub2mu0; + } + + if (sp2 == 0 && comm->me == 0) + error->all(FLERR,"Using kspace solver PPPMDipoleSpin on system with no spins"); +} diff --git a/src/KSPACE/pppm_spin.h b/src/KSPACE/pppm_dipole_spin.h similarity index 66% rename from src/KSPACE/pppm_spin.h rename to src/KSPACE/pppm_dipole_spin.h index 3b4d42d4ea..347006e586 100644 --- a/src/KSPACE/pppm_spin.h +++ b/src/KSPACE/pppm_dipole_spin.h @@ -13,28 +13,23 @@ #ifdef KSPACE_CLASS -KSpaceStyle(pppm/spin,PPPMSpin) +KSpaceStyle(pppm/dipole/spin,PPPMDipoleSpin) #else -#ifndef LMP_PPPM_DIPOLE_H -#define LMP_PPPM_DIPOLE_H +#ifndef LMP_PPPM_DIPOLE_SPIN_H +#define LMP_PPPM_DIPOLE_SPIN_H -#include "pppm.h" +#include "pppm_dipole.h" namespace LAMMPS_NS { -class PPPMSpin : public PPPM { +class PPPMDipoleSpin : public PPPMDipole { public: - PPPMSpin(class LAMMPS *, int, char **); - virtual ~PPPMSpin(); + PPPMDipoleSpin(class LAMMPS *, int, char **); + virtual ~PPPMDipoleSpin(); void init(); - void setup(); - void setup_grid(); void compute(int, int); - int timing_1d(int, double &); - int timing_3d(int, double &); - double memory_usage(); protected: double hbar; // reduced Planck's constant @@ -42,55 +37,15 @@ class PPPMSpin : public PPPM { double mu_0; // vacuum permeability double mub2mu0; // prefactor for mech force double mub2mu0hbinv; // prefactor for mag force - void set_grid_global(); - double newton_raphson_f(); - - void allocate(); - void allocate_peratom(); - void deallocate(); - void deallocate_peratom(); - void compute_gf_denom(); void slabcorr(); - // grid communication - - void pack_forward(int, FFT_SCALAR *, int, int *); - void unpack_forward(int, FFT_SCALAR *, int, int *); - void pack_reverse(int, FFT_SCALAR *, int, int *); - void unpack_reverse(int, FFT_SCALAR *, int, int *); - // spin - FFT_SCALAR ***densityx_brick_spin,***densityy_brick_spin,***densityz_brick_spin; - FFT_SCALAR ***vdxx_brick_spin,***vdyy_brick_spin,***vdzz_brick_spin; - FFT_SCALAR ***vdxy_brick_spin,***vdxz_brick_spin,***vdyz_brick_spin; - FFT_SCALAR ***ux_brick_spin,***uy_brick_spin,***uz_brick_spin; - FFT_SCALAR ***v0x_brick_spin,***v1x_brick_spin,***v2x_brick_spin; - FFT_SCALAR ***v3x_brick_spin,***v4x_brick_spin,***v5x_brick_spin; - FFT_SCALAR ***v0y_brick_spin,***v1y_brick_spin,***v2y_brick_spin; - FFT_SCALAR ***v3y_brick_spin,***v4y_brick_spin,***v5y_brick_spin; - FFT_SCALAR ***v0z_brick_spin,***v1z_brick_spin,***v2z_brick_spin; - FFT_SCALAR ***v3z_brick_spin,***v4z_brick_spin,***v5z_brick_spin; - FFT_SCALAR *work3,*work4; - FFT_SCALAR *densityx_fft_spin,*densityy_fft_spin,*densityz_fft_spin; - class GridComm *cg_spin; - class GridComm *cg_peratom_spin; - int only_spin_flag; double spsum,spsqsum,sp2; - double find_gewald_spin(double, double, bigint, double, double); - double newton_raphson_f_spin(double, double, bigint, double, double); - double derivf_spin(double, double, bigint, double, double); - double compute_df_kspace_spin(); - double compute_qopt_spin(); - void compute_gf_spin(); void make_rho_spin(); - void brick2fft_spin(); - void poisson_ik_spin(); - void poisson_peratom_spin(); void fieldforce_ik_spin(); void fieldforce_peratom_spin(); - double final_accuracy_spin(); void spsum_spsq(); }; @@ -102,9 +57,9 @@ class PPPMSpin : public PPPM { /* ERROR/WARNING messages: -E: Cannot (yet) use charges with Kspace style PPPMSpin +E: Cannot (yet) use charges with Kspace style PPPMDipoleSpin -Charge-spin interactions are not yet implemented in PPPMSpin so this +Charge-spin interactions are not yet implemented in PPPMDipoleSpin so this feature is not yet supported. E: Must redefine kspace_style after changing to triclinic box @@ -123,11 +78,11 @@ E: Cannot (yet) use 'electron' units with spins This feature is not yet supported. -E: Cannot yet use triclinic cells with PPPMSpin +E: Cannot yet use triclinic cells with PPPMDipoleSpin This feature is not yet supported. -E: Cannot yet use TIP4P with PPPMSpin +E: Cannot yet use TIP4P with PPPMDipoleSpin This feature is not yet supported. @@ -207,9 +162,9 @@ outside a processor's sub-domain or even the entire simulation box. This indicates bad physics, e.g. due to highly overlapping atoms, too large a timestep, etc. -E: Using kspace solver PPPMSpin on system with no spins +E: Using kspace solver PPPMDipoleSpin on system with no spins -Must have non-zero spins with PPPMSpin. +Must have non-zero spins with PPPMDipoleSpin. E: Must use kspace_modify gewald for system with no spins diff --git a/src/SPIN/atom_vec_spin.cpp b/src/SPIN/atom_vec_spin.cpp index 6460a6185f..fb2b6dd797 100644 --- a/src/SPIN/atom_vec_spin.cpp +++ b/src/SPIN/atom_vec_spin.cpp @@ -48,7 +48,7 @@ AtomVecSpin::AtomVecSpin(LAMMPS *lmp) : AtomVec(lmp) comm_x_only = 0; comm_f_only = 0; size_forward = 7; - size_reverse = 6; + size_reverse = 9; size_border = 10; size_velocity = 3; size_data_atom = 9; @@ -58,7 +58,6 @@ AtomVecSpin::AtomVecSpin(LAMMPS *lmp) : AtomVec(lmp) atom->sp_flag = 1; } - /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by a chunk @@ -88,6 +87,7 @@ void AtomVecSpin::grow(int n) sp = memory->grow(atom->sp,nmax,4,"atom:sp"); fm = memory->grow(atom->fm,nmax*comm->nthreads,3,"atom:fm"); + fm_long = memory->grow(atom->fm_long,nmax*comm->nthreads,3,"atom:fm_long"); if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) @@ -103,7 +103,7 @@ void AtomVecSpin::grow_reset() tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; - sp = atom->sp; fm = atom->fm; + sp = atom->sp; fm = atom->fm; fm_long = atom->fm_long; } @@ -342,6 +342,9 @@ int AtomVecSpin::pack_reverse(int n, int first, double *buf) buf[m++] = fm[i][0]; buf[m++] = fm[i][1]; buf[m++] = fm[i][2]; + buf[m++] = fm_long[i][0]; + buf[m++] = fm_long[i][1]; + buf[m++] = fm_long[i][2]; } return m; @@ -361,6 +364,9 @@ void AtomVecSpin::unpack_reverse(int n, int *list, double *buf) fm[j][0] += buf[m++]; fm[j][1] += buf[m++]; fm[j][2] += buf[m++]; + fm_long[j][0] += buf[m++]; + fm_long[j][1] += buf[m++]; + fm_long[j][2] += buf[m++]; } } @@ -939,6 +945,7 @@ bigint AtomVecSpin::memory_usage() if (atom->memcheck("sp")) bytes += memory->usage(sp,nmax,4); if (atom->memcheck("fm")) bytes += memory->usage(fm,nmax*comm->nthreads,3); + if (atom->memcheck("fm_long")) bytes += memory->usage(fm_long,nmax*comm->nthreads,3); return bytes; } @@ -947,6 +954,7 @@ void AtomVecSpin::force_clear(int n, size_t nbytes) { memset(&atom->f[0][0],0,3*nbytes); memset(&atom->fm[0][0],0,3*nbytes); + memset(&atom->fm_long[0][0],0,3*nbytes); } diff --git a/src/SPIN/atom_vec_spin.h b/src/SPIN/atom_vec_spin.h index 34bc55b99f..1f1c34df52 100644 --- a/src/SPIN/atom_vec_spin.h +++ b/src/SPIN/atom_vec_spin.h @@ -68,10 +68,12 @@ class AtomVecSpin : public AtomVec { int *type,*mask; imageint *image; double **x,**v,**f; // lattice quantities - double **sp,**fm; // spin quantities - // sp[i][0-2] direction of the spin i + + // spin quantities + double **sp; // sp[i][0-2] direction of the spin i // sp[i][3] atomic magnetic moment of the spin i - + double **fm; // fm[i][0-2] direction of magnetic precession + double **fm_long; // storage of long-range spin prec. components }; } diff --git a/src/SPIN/pair_spin_exchange.cpp b/src/SPIN/pair_spin_exchange.cpp index cc074bb97d..74570afbce 100644 --- a/src/SPIN/pair_spin_exchange.cpp +++ b/src/SPIN/pair_spin_exchange.cpp @@ -441,8 +441,6 @@ void PairSpinExchange::allocate() memory->create(cutsq,n+1,n+1,"pair:cutsq"); } - - /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ @@ -527,4 +525,3 @@ void PairSpinExchange::read_restart_settings(FILE *fp) MPI_Bcast(&offset_flag,1,MPI_INT,0,world); MPI_Bcast(&mix_flag,1,MPI_INT,0,world); } - diff --git a/src/SPIN/pair_spin_long.cpp b/src/SPIN/pair_spin_long.cpp index 95c4e6b5a9..ca4f3d5e24 100644 --- a/src/SPIN/pair_spin_long.cpp +++ b/src/SPIN/pair_spin_long.cpp @@ -13,19 +13,19 @@ /* ------------------------------------------------------------------------ Contributing authors: Julien Tranchida (SNL) - Stan Moore (SNL) - + Aidan Thompson (SNL) + Please cite the related publication: - Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). - Massively parallel symplectic algorithm for coupled magnetic spin dynamics - and molecular dynamics. arXiv preprint arXiv:1801.10233. + Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). + Massively parallel symplectic algorithm for coupled magnetic spin dynamics + and molecular dynamics. Journal of Computational Physics. ------------------------------------------------------------------------- */ - #include #include #include #include + #include "pair_spin_long.h" #include "atom.h" #include "comm.h" @@ -80,8 +80,152 @@ PairSpinLong::~PairSpinLong() { if (allocated) { memory->destroy(setflag); - memory->destroy(cutsq); + memory->destroy(cut_spin_long); + } +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairSpinLong::settings(int narg, char **arg) +{ + if (narg < 1 || narg > 2) + error->all(FLERR,"Incorrect args in pair_style command"); + + if (strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"Spin simulations require metal unit style"); + + cut_spin_long_global = force->numeric(FLERR,arg[0]); + //cut_spin = force->numeric(FLERR,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_spin_long[i][j] = cut_spin_long_global; + } + } + } + } + +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairSpinLong::coeff(int narg, char **arg) +{ + if (!allocated) allocate(); + + // check if args correct + + if (strcmp(arg[2],"long") != 0) + error->all(FLERR,"Incorrect args in pair_style command"); + if (narg != 3) + error->all(FLERR,"Incorrect args in pair_style command"); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double spin_long_cut_one = force->numeric(FLERR,arg[3]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + setflag[i][j] = 1; + cut_spin_long[i][j] = spin_long_cut_one; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSpinLong::init_style() +{ + if (!atom->sp_flag) + error->all(FLERR,"Pair spin requires atom/spin style"); + + // need a full neighbor list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + + // checking if nve/spin is a listed fix + + int ifix = 0; + while (ifix < modify->nfix) { + if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + ifix++; + } + if (ifix == modify->nfix) + error->all(FLERR,"pair/spin style requires nve/spin"); + + // get the lattice_flag from nve/spin + + for (int i = 0; i < modify->nfix; i++) { + if (strcmp(modify->fix[i]->style,"nve/spin") == 0) { + lockfixnvespin = (FixNVESpin *) modify->fix[i]; + lattice_flag = lockfixnvespin->lattice_flag; + } + } + + // insure use of KSpace long-range solver, set g_ewald + + if (force->kspace == NULL) + error->all(FLERR,"Pair style requires a KSpace style"); + + g_ewald = force->kspace->g_ewald; + +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairSpinLong::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + cut_spin_long[j][i] = cut_spin_long[i][j]; + + return cut_spin_long_global; +} + +/* ---------------------------------------------------------------------- + extract the larger cutoff if "cut" or "cut_coul" +------------------------------------------------------------------------- */ + +void *PairSpinLong::extract(const char *str, int &dim) +{ + if (strcmp(str,"cut") == 0) { + dim = 0; + return (void *) &cut_spin_long_global; + } else if (strcmp(str,"cut_coul") == 0) { + dim = 0; + return (void *) &cut_spin_long_global; + } else if (strcmp(str,"ewald_order") == 0) { + ewald_order = 0; + ewald_order |= 1<<1; + ewald_order |= 1<<3; + dim = 0; + return (void *) &ewald_order; + } else if (strcmp(str,"ewald_mix") == 0) { + dim = 0; + return (void *) &mix_flag; } + return NULL; } /* ---------------------------------------------------------------------- */ @@ -95,6 +239,7 @@ void PairSpinLong::compute(int eflag, int vflag) double evdwl,ecoul; double xi[3],rij[3]; double spi[4],spj[4],fi[3],fmi[3]; + double local_cut2; double pre1,pre2,pre3; int *ilist,*jlist,*numneigh,**firstneigh; @@ -156,26 +301,25 @@ void PairSpinLong::compute(int eflag, int vflag) rij[2] = x[j][2] - xi[2]; rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; - if (rsq < cutsq[itype][jtype]) { + local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + + if (rsq < local_cut2) { r2inv = 1.0/rsq; rinv = sqrt(r2inv); - if (rsq < cut_spinsq) { - 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; - - bij[0] = erfc * rinv; - bij[1] = (bij[0] + pre1*expm2) * r2inv; - bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; - bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; - - compute_long(i,j,rij,bij,fmi,spi,spj); - compute_long_mech(i,j,rij,bij,fmi,spi,spj); - - } + 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; + + bij[0] = erfc * rinv; + bij[1] = (bij[0] + pre1*expm2) * r2inv; + bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + + compute_long(i,j,rij,bij,fmi,spi,spj); + compute_long_mech(i,j,rij,bij,fmi,spi,spj); } // force accumulation @@ -194,7 +338,7 @@ void PairSpinLong::compute(int eflag, int vflag) } if (eflag) { - if (rsq <= cut_spinsq) { + if (rsq <= local_cut2) { evdwl -= spi[0]*fmi[0] + spi[1]*fmi[1] + spi[2]*fmi[2]; evdwl *= hbar; @@ -219,6 +363,7 @@ void PairSpinLong::compute_single_pair(int ii, double fmi[3]) double r,rinv,r2inv,rsq; double grij,expm2,t,erfc; double bij[4],xi[3],rij[3],spi[4],spj[4]; + double local_cut2; double pre1,pre2,pre3; int *ilist,*jlist,*numneigh,**firstneigh; @@ -267,25 +412,24 @@ void PairSpinLong::compute_single_pair(int ii, double fmi[3]) rij[2] = x[j][2] - xi[2]; rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; - if (rsq < cutsq[itype][jtype]) { + local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + + if (rsq < local_cut2) { r2inv = 1.0/rsq; rinv = sqrt(r2inv); - if (rsq < cut_spinsq) { - 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; + 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; - bij[0] = erfc * rinv; - bij[1] = (bij[0] + pre1*expm2) * r2inv; - bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; - bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + bij[0] = erfc * rinv; + bij[1] = (bij[0] + pre1*expm2) * r2inv; + bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; - compute_long(i,j,rij,bij,fmi,spi,spj); - - } + compute_long(i,j,rij,bij,fmi,spi,spj); } } @@ -361,111 +505,7 @@ void PairSpinLong::allocate() for (int j = i; j <= n; j++) setflag[i][j] = 0; - memory->create(cutsq,n+1,n+1,"pair:cutsq"); -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairSpinLong::settings(int narg, char **arg) -{ - if (narg < 1 || narg > 2) - error->all(FLERR,"Incorrect args in pair_style command"); - - if (strcmp(update->unit_style,"metal") != 0) - error->all(FLERR,"Spin simulations require metal unit style"); - - cut_spin = force->numeric(FLERR,arg[0]); - -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairSpinLong::coeff(int narg, char **arg) -{ - if (narg < 4 || narg > 5) - error->all(FLERR,"Incorrect args for pair coefficients"); - if (!allocated) allocate(); - - // check if args correct - - if (strcmp(arg[2],"long") != 0) - error->all(FLERR,"Incorrect args in pair_style command"); - if (narg != 3) - error->all(FLERR,"Incorrect args in pair_style command"); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - 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 PairSpinLong::init_one(int i, int j) -{ - if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - - double cut = cut_spin; - return cut; -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairSpinLong::init_style() -{ - if (!atom->sp_flag) - error->all(FLERR,"Pair spin requires atom/spin style"); - - // need a full neighbor list - - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full = 1; - - // checking if nve/spin is a listed fix - - int ifix = 0; - while (ifix < modify->nfix) { - if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; - ifix++; - } - if (ifix == modify->nfix) - error->all(FLERR,"pair/spin style requires nve/spin"); - - // get the lattice_flag from nve/spin - - for (int i = 0; i < modify->nfix; i++) { - if (strcmp(modify->fix[i]->style,"nve/spin") == 0) { - lockfixnvespin = (FixNVESpin *) modify->fix[i]; - lattice_flag = lockfixnvespin->lattice_flag; - } - } - - // insure use of KSpace long-range solver, set g_ewald - - if (force->kspace == NULL) - error->all(FLERR,"Pair style requires a KSpace style"); - - g_ewald = force->kspace->g_ewald; - - cut_spinsq = cut_spin * cut_spin; + memory->create(cut_spin_long,n+1,n+1,"pair:cut_spin_long"); } /* ---------------------------------------------------------------------- @@ -477,10 +517,14 @@ void PairSpinLong::write_restart(FILE *fp) write_restart_settings(fp); int i,j; - for (i = 1; i <= atom->ntypes; i++) + 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_spin_long[i][j],sizeof(int),1,fp); + } } + } } /* ---------------------------------------------------------------------- @@ -495,11 +539,18 @@ void PairSpinLong::read_restart(FILE *fp) int i,j; int me = comm->me; - for (i = 1; i <= atom->ntypes; i++) + 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_spin_long[i][j],sizeof(int),1,fp); + } + MPI_Bcast(&cut_spin_long[i][j],1,MPI_INT,0,world); + } } + } } /* ---------------------------------------------------------------------- @@ -508,7 +559,7 @@ void PairSpinLong::read_restart(FILE *fp) void PairSpinLong::write_restart_settings(FILE *fp) { - fwrite(&cut_spin,sizeof(double),1,fp); + fwrite(&cut_spin_long_global,sizeof(double),1,fp); fwrite(&mix_flag,sizeof(int),1,fp); } @@ -519,32 +570,9 @@ void PairSpinLong::write_restart_settings(FILE *fp) void PairSpinLong::read_restart_settings(FILE *fp) { if (comm->me == 0) { - fread(&cut_spin,sizeof(double),1,fp); + fread(&cut_spin_long_global,sizeof(double),1,fp); fread(&mix_flag,sizeof(int),1,fp); } - MPI_Bcast(&cut_spin,1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut_spin_long_global,1,MPI_DOUBLE,0,world); MPI_Bcast(&mix_flag,1,MPI_INT,0,world); } - -/* ---------------------------------------------------------------------- */ - -void *PairSpinLong::extract(const char *str, int &dim) -{ - if (strcmp(str,"cut") == 0) { - dim = 0; - return (void *) &cut_spin; - } else if (strcmp(str,"cut_coul") == 0) { - dim = 0; - return (void *) &cut_spin; - } else if (strcmp(str,"ewald_order") == 0) { - ewald_order = 0; - ewald_order |= 1<<1; - ewald_order |= 1<<3; - dim = 0; - return (void *) &ewald_order; - } else if (strcmp(str,"ewald_mix") == 0) { - dim = 0; - return (void *) &mix_flag; - } - return NULL; -} diff --git a/src/SPIN/pair_spin_long.h b/src/SPIN/pair_spin_long.h index 867b771f74..0cdf6d2b80 100644 --- a/src/SPIN/pair_spin_long.h +++ b/src/SPIN/pair_spin_long.h @@ -49,6 +49,8 @@ class PairSpinLong : public PairSpin { void read_restart(FILE *); void write_restart_settings(FILE *); void read_restart_settings(FILE *); + + double cut_spin_long_global; // global long cutoff distance protected: double hbar; // reduced Planck's constant @@ -56,7 +58,8 @@ class PairSpinLong : public PairSpin { double mu_0; // vacuum permeability double mub2mu0; // prefactor for mech force double mub2mu0hbinv; // prefactor for mag force - double cut_spin, cut_spinsq; + + double **cut_spin_long; // cutoff distance long double g_ewald; int ewald_order; -- GitLab From cf1d421e10cf384098210c32cf3ea2374baf55e9 Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 23 Aug 2018 15:18:30 -0600 Subject: [PATCH 0039/1243] Commit JT 082318 - corrected memory errors in pppm_dipole and pppm_dipole_spin - created fm_long in atom_vec_spin - fm_long added to fm in initial_integrate (in ComputeInteractionsSpin) --- .../SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy | 1 + .../exchange_fit_hcp_co/exchange_fit.py | 32 +++++++ .../exchange_fit_hcp_co/exchange_hcp_co.dat | 9 ++ examples/SPIN/pppm_spin/in.dipole.pppm_dipole | 55 +++++++++++ examples/SPIN/pppm_spin/in.spin.pppm_spin | 61 ++++++++++++ src/KSPACE/pppm.cpp | 6 +- src/KSPACE/pppm_dipole.cpp | 93 +++++++++---------- src/KSPACE/pppm_dipole.h | 8 +- src/KSPACE/pppm_dipole_spin.cpp | 84 +++++++++-------- src/KSPACE/pppm_dipole_spin.h | 1 - src/SPIN/atom_vec_spin.cpp | 1 - src/SPIN/fix_nve_spin.cpp | 18 ++++ src/SPIN/fix_nve_spin.h | 3 +- src/SPIN/pair_spin_long.cpp | 11 ++- src/atom.cpp | 3 +- src/atom.h | 1 + src/pair.h | 2 +- 17 files changed, 288 insertions(+), 101 deletions(-) create mode 120000 examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy create mode 100644 examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_fit.py create mode 100644 examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_hcp_co.dat create mode 100644 examples/SPIN/pppm_spin/in.dipole.pppm_dipole create mode 100644 examples/SPIN/pppm_spin/in.spin.pppm_spin diff --git a/examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy b/examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy new file mode 120000 index 0000000000..6a47c9eebe --- /dev/null +++ b/examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy @@ -0,0 +1 @@ +../cobalt_fcc/Co_PurjaPun_2012.eam.alloy \ No newline at end of file diff --git a/examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_fit.py b/examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_fit.py new file mode 100644 index 0000000000..fa7dba417e --- /dev/null +++ b/examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_fit.py @@ -0,0 +1,32 @@ +#Program fitting the exchange interaction +#Model curve: Bethe-Slater function +import numpy as np, pylab, tkinter +import matplotlib.pyplot as plt +from scipy.optimize import curve_fit +from decimal import * + +print("Loop begin") + +#Definition of the Bethe-Slater function +def func(x,a,b,c): + return 4*a*((x/c)**2)*(1-b*(x/c)**2)*np.exp(-(x/c)**2) + +#Exchange coeff table (data to fit) +rdata, Jdata = np.loadtxt('exchange_hcp_co.dat', usecols=(0,1), unpack=True) +plt.plot(rdata, Jdata, 'b-', label='data') + +#Perform the fit +popt, pcov = curve_fit(func, rdata, Jdata, bounds=(0, [500.,5.,5.])) +plt.plot(rdata, func(rdata, *popt), 'r--', label='fit') + +#Print the fitted params +print("Parameters: a={:.10} (in meV), b={:.10} (adim), c={:.10} (in Ang)".format(*popt)) + +#Ploting the result +plt.xlabel('r_ij') +pylab.xlim([0,6.5]) +plt.ylabel('J_ij') +plt.legend() +plt.show() + +print("Loop end") diff --git a/examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_hcp_co.dat b/examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_hcp_co.dat new file mode 100644 index 0000000000..0968fa3edb --- /dev/null +++ b/examples/SPIN/pppm_spin/exchange_fit_hcp_co/exchange_hcp_co.dat @@ -0,0 +1,9 @@ +2.25569176882662 73.37931034482759 +2.3817863397548162 47.99999999999999 +2.4518388791593697 34.39080459770115 +2.507880910683012 31.816091954022987 +2.5359019264448337 28.137931034482747 +2.5779334500875657 25.011494252873554 +2.6339754816112086 19.126436781609186 +2.760070052539404 13.241379310344826 +3.5446584938704033 6.068965517241367 diff --git a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole new file mode 100644 index 0000000000..804ddad1e2 --- /dev/null +++ b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole @@ -0,0 +1,55 @@ +# 3d Lennard-Jones melt + +units lj +#atom_style charge +atom_style hybrid sphere dipole +processors * 1 1 + +lattice fcc 0.8442 +#region box block 0 10 0 10 0 10 +region box block 0 5 0 5 0 5 +create_box 3 box +create_atoms 1 box +mass * 1.0 + +region long block 3 6 0 10 0 10 +set region long type 2 +set group all dipole/random 98934 0.75 +#set type 1:2 charge 0.0 + +velocity all create 1.0 87287 + +#pair_style lj/long/coul/long long off 2.5 +#pair_coeff * * 1.0 1.0 2.5 +#pair_coeff * 2 1.0 1.0 5.0 +pair_style lj/cut/dipole/long 3.0 +pair_coeff * * 1.0 1.0 + +#kspace_style pppm/disp 1.0e-4 +kspace_style pppm/dipole 1.0e-4 +kspace_modify gewald/disp 0.1 + +neighbor 0.3 bin +neigh_modify every 2 delay 4 check yes + +group fast type 1 +group slow type 2 +fix 0 all balance 20 1.0 shift x 5 1.0 & + weight group 2 fast 1.0 slow 2.0 weight time 0.66 + +fix 1 all nve + +#dump id all atom 50 dump.melt + +#dump 2 all image 25 image.*.jpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 2 pad 3 + +#dump 3 all movie 25 movie.mpg type type & +# axes yes 0.8 0.02 view 60 -30 +#dump_modify 3 pad 3 + +#thermo 50 +thermo 1 +#run 500 +run 5 diff --git a/examples/SPIN/pppm_spin/in.spin.pppm_spin b/examples/SPIN/pppm_spin/in.spin.pppm_spin new file mode 100644 index 0000000000..87d18f4d16 --- /dev/null +++ b/examples/SPIN/pppm_spin/in.spin.pppm_spin @@ -0,0 +1,61 @@ +# hcp cobalt in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary p p p + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice hcp 2.5071 +region box block 0.0 20.0 0.0 20.0 0.0 8.0 +create_box 1 box +create_atoms 1 box + +# setting mass, mag. moments, and interactions for hcp cobalt + +mass 1 58.93 + +#set group all spin/random 31 1.72 +set group all spin 1.72 0.0 0.0 1.0 +velocity all create 100 4928459 rot yes dist gaussian + +pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 +pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +pair_coeff * * spin/long long 8.0 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +kspace_style pppm/dipole/spin 1.0e-4 + +#fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.0 21 +fix 3 all nve/spin lattice yes + +timestep 0.0001 + + +compute out_mag all compute/spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo_style custom step time v_magnorm v_emag temp etotal +thermo 10 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +run 20000 diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 132389b7d6..8eec8e2542 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -100,6 +100,9 @@ PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg), nyhi_in = nylo_in = nyhi_out = nylo_out = 0; nzhi_in = nzlo_in = nzhi_out = nzlo_out = 0; + // test + nlower = nupper = 0; + density_brick = vdx_brick = vdy_brick = vdz_brick = NULL; density_fft = NULL; u_brick = NULL; @@ -1428,12 +1431,13 @@ void PPPM::set_grid_local() double zprd = prd[2]; double zprd_slab = zprd*slab_volfactor; - double dist[3]; + double dist[3] = {0.0,0.0,0.0}; double cuthalf = 0.5*neighbor->skin + qdist; if (triclinic == 0) dist[0] = dist[1] = dist[2] = cuthalf; else kspacebbox(cuthalf,&dist[0]); int nlo,nhi; + nlo = nhi = 0; nlo = static_cast ((sublo[0]-dist[0]-boxlo[0]) * nx_pppm/xprd + shift) - OFFSET; diff --git a/src/KSPACE/pppm_dipole.cpp b/src/KSPACE/pppm_dipole.cpp index a03f5b9980..4d2b594af8 100644 --- a/src/KSPACE/pppm_dipole.cpp +++ b/src/KSPACE/pppm_dipole.cpp @@ -116,9 +116,10 @@ void PPPMDipole::init() // error check dipoleflag = atom->mu?1:0; - qsum_qsq(0); + qsum_qsq(0); // q[i] might not be declared ? + if (dipoleflag && q2) - error->all(FLERR,"Cannot (yet) uses charges with Kspace style PPPMDipole"); + error->all(FLERR,"Cannot (yet) use charges with Kspace style PPPMDipole"); triclinic_check(); @@ -168,7 +169,9 @@ void PPPMDipole::init() cutoff = *p_cutoff; // kspace TIP4P not yet supported + // qdist = offset only for TIP4P fictitious charge + qdist = 0.0; if (tip4pflag) error->all(FLERR,"Cannot yet use TIP4P with PPPMDipole"); @@ -206,7 +209,7 @@ void PPPMDipole::init() "beyond nearest neighbor processor"); compute_gf_denom(); - set_grid_global(mu2); + set_grid_global(); set_grid_local(); if (overlap_allowed) break; @@ -235,7 +238,7 @@ void PPPMDipole::init() // calculate the final accuracy - double estimated_accuracy = final_accuracy_dipole(mu2); + double estimated_accuracy = final_accuracy_dipole(); // print stats @@ -607,7 +610,7 @@ void PPPMDipole::allocate() // summation coeffs order_allocated = order; - memory->create(gf_b,order,"pppm_dipole:gf_b"); + if (!gf_b) memory->create(gf_b,order,"pppm_dipole:gf_b"); memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm_dipole:rho1d"); memory->create2d_offset(drho1d,3,-order/2,order/2,"pppm_dipole:drho1d"); memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm_dipole:rho_coeff"); @@ -791,7 +794,8 @@ void PPPMDipole::deallocate_peratom() used for charge accumulation, FFTs, and electric field interpolation ------------------------------------------------------------------------- */ -void PPPMDipole::set_grid_global(double dipole2) +//void PPPMDipole::set_grid_global(double dipole2) +void PPPMDipole::set_grid_global() { // use xprd,yprd,zprd // adjust z dimension for 2d slab PPPMDipole @@ -813,14 +817,11 @@ void PPPMDipole::set_grid_global(double dipole2) if (!gewaldflag) { if (accuracy <= 0.0) error->all(FLERR,"KSpace accuracy must be > 0"); - //if (mu2 == 0.0) - if (dipole2 == 0.0) + if (mu2 == 0.0) error->all(FLERR,"Must use kspace_modify gewald for systems with no dipoles"); g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; - //Try Newton Solver double g_ewald_new = - find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,dipole2); - //find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); + find_gewald_dipole(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); if (g_ewald_new > 0.0) g_ewald = g_ewald_new; else error->warning(FLERR,"PPPMDipole dipole Newton solver failed, " "using old method to estimate g_ewald"); @@ -837,6 +838,7 @@ void PPPMDipole::set_grid_global(double dipole2) while (1) { // set grid dimension + nx_pppm = static_cast (xprd/h_x); ny_pppm = static_cast (yprd/h_y); nz_pppm = static_cast (zprd_slab/h_z); @@ -845,7 +847,8 @@ void PPPMDipole::set_grid_global(double dipole2) if (ny_pppm <= 1) ny_pppm = 2; if (nz_pppm <= 1) nz_pppm = 2; - //set local grid dimension + // set local grid dimension + int npey_fft,npez_fft; if (nz_pppm >= nprocs) { npey_fft = 1; @@ -862,7 +865,7 @@ void PPPMDipole::set_grid_global(double dipole2) nzlo_fft = me_z*nz_pppm/npez_fft; nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1; - double df_kspace = compute_df_kspace_dipole(dipole2); + double df_kspace = compute_df_kspace_dipole(); count++; @@ -895,7 +898,7 @@ void PPPMDipole::set_grid_global(double dipole2) compute estimated kspace force error for dipoles ------------------------------------------------------------------------- */ -double PPPMDipole::compute_df_kspace_dipole(double dipole2) +double PPPMDipole::compute_df_kspace_dipole() { double xprd = domain->xprd; double yprd = domain->yprd; @@ -903,8 +906,7 @@ double PPPMDipole::compute_df_kspace_dipole(double dipole2) double zprd_slab = zprd*slab_volfactor; bigint natoms = atom->natoms; double qopt = compute_qopt_dipole(); - //double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); - double df_kspace = sqrt(qopt/natoms)*dipole2/(3.0*xprd*yprd*zprd_slab); + double df_kspace = sqrt(qopt/natoms)*mu2/(3.0*xprd*yprd*zprd_slab); return df_kspace; } @@ -1101,27 +1103,27 @@ void PPPMDipole::compute_gf_dipole() calculate f(x) for use in Newton-Raphson solver ------------------------------------------------------------------------- */ -//double PPPMDipole::newton_raphson_f() -//{ -// double xprd = domain->xprd; -// double yprd = domain->yprd; -// double zprd = domain->zprd; -// bigint natoms = atom->natoms; -// -// double df_rspace,df_kspace; -// double vol = xprd*yprd*zprd; -// double a = cutoff*g_ewald; -// double rg2 = a*a; -// double rg4 = rg2*rg2; -// double rg6 = rg4*rg2; -// double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; -// double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; -// df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * -// sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); -// df_kspace = compute_df_kspace_dipole(); -// -// return df_rspace - df_kspace; -//} +double PPPMDipole::newton_raphson_f() +{ + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + bigint natoms = atom->natoms; + + double df_rspace,df_kspace; + double vol = xprd*yprd*zprd; + double a = cutoff*g_ewald; + double rg2 = a*a; + double rg4 = rg2*rg2; + double rg6 = rg4*rg2; + double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; + double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; + df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); + df_kspace = compute_df_kspace_dipole(); + + return df_rspace - df_kspace; +} /* ---------------------------------------------------------------------- find g_ewald parameter for dipoles based on desired accuracy @@ -1184,7 +1186,7 @@ double PPPMDipole::derivf_dipole(double x, double Rc, calculate the final estimate of the accuracy ------------------------------------------------------------------------- */ -double PPPMDipole::final_accuracy_dipole(double dipole2) +double PPPMDipole::final_accuracy_dipole() { double xprd = domain->xprd; double yprd = domain->yprd; @@ -1193,7 +1195,7 @@ double PPPMDipole::final_accuracy_dipole(double dipole2) bigint natoms = atom->natoms; if (natoms == 0) natoms = 1; // avoid division by zero - double df_kspace = compute_df_kspace_dipole(mu2); + double df_kspace = compute_df_kspace_dipole(); double a = cutoff*g_ewald; double rg2 = a*a; @@ -1201,10 +1203,7 @@ double PPPMDipole::final_accuracy_dipole(double dipole2) double rg6 = rg4*rg2; double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; - //double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * - // sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * - // exp(-rg2)); - double df_rspace = (dipole2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * + double df_rspace = (mu2/(sqrt(vol*powint(g_ewald,4)*powint(cutoff,9)*natoms)) * sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * exp(-rg2)); @@ -2521,11 +2520,11 @@ double PPPMDipole::memory_usage() double bytes = nmax*3 * sizeof(double); int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) * (nzhi_out-nzlo_out+1); - bytes += 6 * nfft_both * sizeof(double); // vg - bytes += nfft_both * sizeof(double); // greensfn + bytes += 6 * nfft_both * sizeof(double); // vg + bytes += nfft_both * sizeof(double); // greensfn bytes += nfft_both*5 * sizeof(FFT_SCALAR); // work*2*2 - bytes += 9 * nbrick * sizeof(FFT_SCALAR); // ubrick*3 + vdbrick*6 - bytes += nfft_both*7 * sizeof(FFT_SCALAR); //density_ffx*3 + work*2*2 + bytes += 9 * nbrick * sizeof(FFT_SCALAR); // ubrick*3 + vdbrick*6 + bytes += nfft_both*7 * sizeof(FFT_SCALAR); // density_ffx*3 + work*2*2 if (peratom_allocate_flag) bytes += 21 * nbrick * sizeof(FFT_SCALAR); diff --git a/src/KSPACE/pppm_dipole.h b/src/KSPACE/pppm_dipole.h index 8db28b540a..52bd2e5a9d 100644 --- a/src/KSPACE/pppm_dipole.h +++ b/src/KSPACE/pppm_dipole.h @@ -37,8 +37,8 @@ class PPPMDipole : public PPPM { double memory_usage(); protected: - void set_grid_global(double); - //double newton_raphson_f(); + void set_grid_global(); + double newton_raphson_f(); void allocate(); void allocate_peratom(); @@ -76,7 +76,7 @@ class PPPMDipole : public PPPM { double find_gewald_dipole(double, double, bigint, double, double); double newton_raphson_f_dipole(double, double, bigint, double, double); double derivf_dipole(double, double, bigint, double, double); - double compute_df_kspace_dipole(double); + double compute_df_kspace_dipole(); double compute_qopt_dipole(); void compute_gf_dipole(); void make_rho_dipole(); @@ -85,7 +85,7 @@ class PPPMDipole : public PPPM { void poisson_peratom_dipole(); void fieldforce_ik_dipole(); void fieldforce_peratom_dipole(); - double final_accuracy_dipole(double dipole2); + double final_accuracy_dipole(); void musum_musq(); }; diff --git a/src/KSPACE/pppm_dipole_spin.cpp b/src/KSPACE/pppm_dipole_spin.cpp index 4fde7ba101..a5aee7150c 100644 --- a/src/KSPACE/pppm_dipole_spin.cpp +++ b/src/KSPACE/pppm_dipole_spin.cpp @@ -50,8 +50,8 @@ using namespace MathSpecial; #define SMALL 0.00001 #define EPS_HOC 1.0e-7 -enum{REVERSE_SP}; -enum{FORWARD_SP,FORWARD_SP_PERATOM}; +enum{REVERSE_MU}; +enum{FORWARD_MU,FORWARD_MU_PERATOM}; #ifdef FFT_SINGLE #define ZEROF 0.0f @@ -68,10 +68,12 @@ PPPMDipoleSpin::PPPMDipoleSpin(LAMMPS *lmp, int narg, char **arg) : { dipoleflag = 0; spinflag = 1; - group_group_enable = 0; - - cg_dipole = NULL; - cg_peratom_dipole = NULL; + + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } /* ---------------------------------------------------------------------- @@ -104,7 +106,10 @@ void PPPMDipoleSpin::init() // error check spinflag = atom->sp?1:0; - + //qsum_qsq(0); // q[i] is probably not declared ? + //if (spinflag && q2) + // error->all(FLERR,"Cannot use charges with Kspace style PPPMDipoleSpin"); + triclinic_check(); if (triclinic != domain->triclinic) @@ -118,8 +123,8 @@ void PPPMDipoleSpin::init() if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); - if (atom->sp && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use kspace_modify diff" - " ad with spins"); + if (atom->sp && differentiation_flag == 1) error->all(FLERR,"Cannot (yet) use" + " kspace_modify diff ad with spins"); if (spinflag && strcmp(update->unit_style,"metal") != 0) error->all(FLERR,"'metal' units have to be used with spins"); @@ -148,21 +153,19 @@ void PPPMDipoleSpin::init() int itmp = 0; double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); + // probably not the correct extract here if (p_cutoff == NULL) error->all(FLERR,"KSpace style is incompatible with Pair style"); cutoff = *p_cutoff; // kspace TIP4P not yet supported - + // qdist = offset only for TIP4P fictitious charge + + qdist = 0.0; if (tip4pflag) error->all(FLERR,"Cannot yet use TIP4P with PPPMDipoleSpin"); scale = 1.0; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz spsum_spsq(); natoms_original = atom->natoms; @@ -188,14 +191,14 @@ void PPPMDipoleSpin::init() GridComm *cgtmp = NULL; int iteration = 0; - + while (order >= minorder) { if (iteration && me == 0) error->warning(FLERR,"Reducing PPPMDipoleSpin order b/c stencil extends " "beyond nearest neighbor processor"); compute_gf_denom(); - set_grid_global(sp2); + set_grid_global(); set_grid_local(); if (overlap_allowed) break; @@ -224,7 +227,7 @@ void PPPMDipoleSpin::init() // calculate the final accuracy - double estimated_accuracy = final_accuracy_dipole(sp2); + double estimated_accuracy = final_accuracy_dipole(); // print stats @@ -310,7 +313,7 @@ void PPPMDipoleSpin::compute(int eflag, int vflag) // return if there are no spins - if (spsqsum == 0.0) return; + if (musqsum == 0.0) return; // convert atoms from box to lamda coords @@ -334,7 +337,7 @@ void PPPMDipoleSpin::compute(int eflag, int vflag) // to fully sum contribution in their 3d bricks // remap from 3d decomposition to FFT decomposition - cg_dipole->reverse_comm(this,REVERSE_SP); + cg_dipole->reverse_comm(this,REVERSE_MU); brick2fft_dipole(); // compute potential gradient on my FFT grid and @@ -347,12 +350,12 @@ void PPPMDipoleSpin::compute(int eflag, int vflag) // all procs communicate E-field values // to fill ghost cells surrounding their 3d bricks - cg_dipole->forward_comm(this,FORWARD_SP); + cg_dipole->forward_comm(this,FORWARD_MU); // extra per-atom energy/virial communication if (evflag_atom) { - cg_peratom_dipole->forward_comm(this,FORWARD_SP_PERATOM); + cg_peratom_dipole->forward_comm(this,FORWARD_MU_PERATOM); } // calculate the force on my particles @@ -374,7 +377,7 @@ void PPPMDipoleSpin::compute(int eflag, int vflag) energy = energy_all; energy *= 0.5*volume; - energy -= spsqsum*2.0*g3/3.0/MY_PIS; + energy -= musqsum*2.0*g3/3.0/MY_PIS; energy *= spscale; } @@ -510,7 +513,7 @@ void PPPMDipoleSpin::fieldforce_ik_spin() double spx,spy,spz; double **x = atom->x; double **f = atom->f; - double **fm = atom->fm; + double **fm_long = atom->fm_long; int nlocal = atom->nlocal; @@ -548,7 +551,7 @@ void PPPMDipoleSpin::fieldforce_ik_spin() } } - // convert M-field to mech. and mag. forces + // convert M-field and store mech. forces const double spfactor = mub2mu0 * scale; spx = sp[i][0]*sp[i][3]; @@ -558,13 +561,12 @@ void PPPMDipoleSpin::fieldforce_ik_spin() f[i][1] += spfactor*(vxy*spx + vyy*spy + vyz*spz); f[i][2] += spfactor*(vxz*spx + vyz*spy + vzz*spz); + // store long-range mag. precessions + const double spfactorh = mub2mu0hbinv * scale; - fm[i][0] += spfactorh*ex; - fm[i][1] += spfactorh*ey; - fm[i][2] += spfactorh*ez; - - // create a new vector (in atom_spin style ?) to store long-range fm tables - + fm_long[i][0] += spfactorh*ex; + fm_long[i][1] += spfactorh*ey; + fm_long[i][2] += spfactorh*ez; } } @@ -708,9 +710,11 @@ void PPPMDipoleSpin::slabcorr() // add on mag. force corrections double ffact = spscale * (-4.0*MY_PI/volume); - double **fm = atom->fm; + //double **fm = atom->fm; + double **fm_long = atom->fm_long; for (int i = 0; i < nlocal; i++) { - fm[i][2] += ffact * spin_all; + //fm[i][2] += ffact * spin_all; + fm_long[i][2] += ffact * spin_all; } } @@ -723,13 +727,13 @@ void PPPMDipoleSpin::spsum_spsq() { const int nlocal = atom->nlocal; - spsum = spsqsum = sp2 = 0.0; + musum = musqsum = mu2 = 0.0; if (atom->sp_flag) { double **sp = atom->sp; double spx, spy, spz; double spsum_local(0.0), spsqsum_local(0.0); - // not exactly the good loop: need to add norm of spins + // sum (direction x norm) of all spins for (int i = 0; i < nlocal; i++) { spx = sp[i][0]*sp[i][3]; @@ -739,12 +743,14 @@ void PPPMDipoleSpin::spsum_spsq() spsqsum_local += spx*spx + spy*spy + spz*spz; } - MPI_Allreduce(&spsum_local,&spsum,1,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(&spsqsum_local,&spsqsum,1,MPI_DOUBLE,MPI_SUM,world); + // store results into pppm_dipole quantities + + MPI_Allreduce(&spsum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&spsqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); - sp2 = spsqsum * mub2mu0; + mu2 = musqsum * mub2mu0; } - if (sp2 == 0 && comm->me == 0) + if (mu2 == 0 && comm->me == 0) error->all(FLERR,"Using kspace solver PPPMDipoleSpin on system with no spins"); } diff --git a/src/KSPACE/pppm_dipole_spin.h b/src/KSPACE/pppm_dipole_spin.h index 347006e586..8d6c5d4eb2 100644 --- a/src/KSPACE/pppm_dipole_spin.h +++ b/src/KSPACE/pppm_dipole_spin.h @@ -42,7 +42,6 @@ class PPPMDipoleSpin : public PPPMDipole { // spin - double spsum,spsqsum,sp2; void make_rho_spin(); void fieldforce_ik_spin(); void fieldforce_peratom_spin(); diff --git a/src/SPIN/atom_vec_spin.cpp b/src/SPIN/atom_vec_spin.cpp index fb2b6dd797..477da613d2 100644 --- a/src/SPIN/atom_vec_spin.cpp +++ b/src/SPIN/atom_vec_spin.cpp @@ -106,7 +106,6 @@ void AtomVecSpin::grow_reset() sp = atom->sp; fm = atom->fm; fm_long = atom->fm_long; } - /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ diff --git a/src/SPIN/fix_nve_spin.cpp b/src/SPIN/fix_nve_spin.cpp index b75f03212a..996bd3c2da 100644 --- a/src/SPIN/fix_nve_spin.cpp +++ b/src/SPIN/fix_nve_spin.cpp @@ -126,6 +126,7 @@ FixNVESpin::FixNVESpin(LAMMPS *lmp, int narg, char **arg) : // initialize the magnetic interaction flags pair_spin_flag = 0; + long_spin_flag = 0; precession_spin_flag = 0; maglangevin_flag = 0; tdamp_flag = temp_flag = 0; @@ -209,8 +210,16 @@ void FixNVESpin::init() if (count != npairspin) error->all(FLERR,"Incorrect number of spin pairs"); + // set pair/spin and long/spin flags + if (npairspin >= 1) pair_spin_flag = 1; + for (int i = 0; ipair_match("spin/long",0,i)) { + long_spin_flag = 1; + } + } + // ptrs FixPrecessionSpin classes int iforce; @@ -425,6 +434,7 @@ void FixNVESpin::ComputeInteractionsSpin(int i) double **sp = atom->sp; double **fm = atom->fm; + double **fm_long = atom->fm_long; // force computation for spin i @@ -442,6 +452,14 @@ void FixNVESpin::ComputeInteractionsSpin(int i) } } + // update magnetic long-range components + + if (long_spin_flag) { + fmi[0] += fm_long[i][0]; + fmi[1] += fm_long[i][1]; + fmi[2] += fm_long[i][2]; + } + // update magnetic precession interactions if (precession_spin_flag) { diff --git a/src/SPIN/fix_nve_spin.h b/src/SPIN/fix_nve_spin.h index afc1db14d6..565de13e92 100644 --- a/src/SPIN/fix_nve_spin.h +++ b/src/SPIN/fix_nve_spin.h @@ -58,7 +58,8 @@ friend class PairSpin; int nlocal_max; // max value of nlocal (for lists size) int pair_spin_flag; // magnetic pair flags - int precession_spin_flag; // magnetic precession flags + int long_spin_flag; // magnetic long-range flag + int precession_spin_flag; // magnetic precession flags int maglangevin_flag; // magnetic langevin flags int tdamp_flag, temp_flag; diff --git a/src/SPIN/pair_spin_long.cpp b/src/SPIN/pair_spin_long.cpp index ca4f3d5e24..efedea3247 100644 --- a/src/SPIN/pair_spin_long.cpp +++ b/src/SPIN/pair_spin_long.cpp @@ -81,6 +81,7 @@ PairSpinLong::~PairSpinLong() if (allocated) { memory->destroy(setflag); memory->destroy(cut_spin_long); + memory->destroy(cutsq); } } @@ -97,7 +98,6 @@ void PairSpinLong::settings(int narg, char **arg) error->all(FLERR,"Spin simulations require metal unit style"); cut_spin_long_global = force->numeric(FLERR,arg[0]); - //cut_spin = force->numeric(FLERR,arg[0]); // reset cutoffs that have been explicitly set @@ -126,7 +126,7 @@ void PairSpinLong::coeff(int narg, char **arg) if (strcmp(arg[2],"long") != 0) error->all(FLERR,"Incorrect args in pair_style command"); - if (narg != 3) + if (narg < 1 || narg > 4) error->all(FLERR,"Incorrect args in pair_style command"); int ilo,ihi,jlo,jhi; @@ -197,9 +197,9 @@ void PairSpinLong::init_style() double PairSpinLong::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - + cut_spin_long[j][i] = cut_spin_long[i][j]; - + return cut_spin_long_global; } @@ -505,7 +505,8 @@ void PairSpinLong::allocate() for (int j = i; j <= n; j++) setflag[i][j] = 0; - memory->create(cut_spin_long,n+1,n+1,"pair:cut_spin_long"); + memory->create(cut_spin_long,n+1,n+1,"pair/spin/long:cut_spin_long"); + memory->create(cutsq,n+1,n+1,"pair/spin/long:cutsq"); } /* ---------------------------------------------------------------------- diff --git a/src/atom.cpp b/src/atom.cpp index cf4d20a71e..58b00712f7 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -98,7 +98,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) // SPIN package - sp = fm = NULL; + sp = fm = fm_long = NULL; // USER-DPD @@ -277,6 +277,7 @@ Atom::~Atom() memory->destroy(sp); memory->destroy(fm); + memory->destroy(fm_long); memory->destroy(vfrac); memory->destroy(s0); diff --git a/src/atom.h b/src/atom.h index 7e003dff5e..95c4a9c30f 100644 --- a/src/atom.h +++ b/src/atom.h @@ -65,6 +65,7 @@ class Atom : protected Pointers { double **sp; double **fm; + double **fm_long; // PERI package diff --git a/src/pair.h b/src/pair.h index f830b7c035..0b46d58782 100644 --- a/src/pair.h +++ b/src/pair.h @@ -61,7 +61,7 @@ class Pair : protected Pointers { int dispersionflag; // 1 if compatible with LJ/dispersion solver int tip4pflag; // 1 if compatible with TIP4P solver int dipoleflag; // 1 if compatible with dipole solver - int spinflag; // 1 if compatible with spin long solver + int spinflag; // 1 if compatible with spin solver int reinitflag; // 1 if compatible with fix adapt and alike int tail_flag; // pair_modify flag for LJ tail correction -- GitLab From 16911adcea92142dc01a550a733499fc1efea7b2 Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 30 Aug 2018 07:33:25 -0600 Subject: [PATCH 0040/1243] Commit1 JT 083018 - started to work on ewald_dipole (not yet triclinic) - compiles and runs (no memory issue) - check the energy accuracy --- examples/SPIN/pppm_spin/in.dipole.pppm_dipole | 7 +- examples/SPIN/pppm_spin/in.spin.pppm_spin | 7 +- src/KSPACE/ewald_dipole.cpp | 847 ++++++++++++++++++ src/KSPACE/ewald_dipole.h | 104 +++ src/KSPACE/pppm.cpp | 3 - src/KSPACE/pppm_dipole.cpp | 8 +- src/KSPACE/pppm_dipole_spin.cpp | 2 - 7 files changed, 963 insertions(+), 15 deletions(-) create mode 100644 src/KSPACE/ewald_dipole.cpp create mode 100644 src/KSPACE/ewald_dipole.h diff --git a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole index 804ddad1e2..c2c49e3caf 100644 --- a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole +++ b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole @@ -23,11 +23,12 @@ velocity all create 1.0 87287 #pair_coeff * * 1.0 1.0 2.5 #pair_coeff * 2 1.0 1.0 5.0 pair_style lj/cut/dipole/long 3.0 -pair_coeff * * 1.0 1.0 +pair_coeff * * 0.0 0.0 #kspace_style pppm/disp 1.0e-4 -kspace_style pppm/dipole 1.0e-4 -kspace_modify gewald/disp 0.1 +#kspace_style pppm/dipole 1.0e-4 +kspace_style ewald/dipole 1.0e-4 +kspace_modify gewald 0.1 neighbor 0.3 bin neigh_modify every 2 delay 4 check yes diff --git a/examples/SPIN/pppm_spin/in.spin.pppm_spin b/examples/SPIN/pppm_spin/in.spin.pppm_spin index 87d18f4d16..f7e462c343 100644 --- a/examples/SPIN/pppm_spin/in.spin.pppm_spin +++ b/examples/SPIN/pppm_spin/in.spin.pppm_spin @@ -11,7 +11,7 @@ boundary p p p atom_modify map array lattice hcp 2.5071 -region box block 0.0 20.0 0.0 20.0 0.0 8.0 +region box block 0.0 8.0 0.0 8.0 0.0 8.0 create_box 1 box create_atoms 1 box @@ -33,7 +33,7 @@ neighbor 0.1 bin neigh_modify every 10 check yes delay 20 kspace_style pppm/dipole/spin 1.0e-4 - +kspace_modify mesh 32 32 32 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 fix 2 all langevin/spin 0.0 0.0 21 @@ -58,4 +58,5 @@ thermo 10 compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] -run 20000 +#run 20000 +run 1 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp new file mode 100644 index 0000000000..d03d93a7c5 --- /dev/null +++ b/src/KSPACE/ewald_dipole.cpp @@ -0,0 +1,847 @@ +/* ---------------------------------------------------------------------- + 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: Julien Tranchida (SNL) + Stan Moore (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include "ewald_dipole.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "pair.h" +#include "domain.h" +#include "math_const.h" +#include "memory.h" +#include "error.h" +#include "update.h" + +#include "math_const.h" +#include "math_special.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define SMALL 0.00001 + +/* ---------------------------------------------------------------------- */ + +EwaldDipole::EwaldDipole(LAMMPS *lmp, int narg, char **arg) : Ewald(lmp, narg, arg) +{ + ewaldflag = dipoleflag = 1; + group_group_enable = 0; + muk = NULL; +} + +/* ---------------------------------------------------------------------- + free all memory +------------------------------------------------------------------------- */ + +EwaldDipole::~EwaldDipole() +{ + memory->destroy(muk); +} + +/* ---------------------------------------------------------------------- + called once before run +------------------------------------------------------------------------- */ + +void EwaldDipole::init() +{ + if (comm->me == 0) { + if (screen) fprintf(screen,"EwaldDipole initialization ...\n"); + if (logfile) fprintf(logfile,"EwaldDipole initialization ...\n"); + } + + // error check + + dipoleflag = atom->mu?1:0; + qsum_qsq(0); // q[i] might not be declared ? + + if (dipoleflag && q2) + error->all(FLERR,"Cannot (yet) use charges with Kspace style EwaldDipole"); + + triclinic_check(); + + // set triclinic to 0 for now (no triclinic calc.) + triclinic = 0; + + if (triclinic) + error->all(FLERR,"Cannot (yet) use EwaldDipole with triclinic box"); + + if (domain->dimension == 2) + error->all(FLERR,"Cannot use EwaldDipole with 2d simulation"); + + if (!atom->mu) error->all(FLERR,"Kspace style requires atom attribute mu"); +//if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); + + if (dipoleflag && strcmp(update->unit_style,"electron") == 0) + error->all(FLERR,"Cannot (yet) use 'electron' units with dipoles"); + + if (slabflag == 0 && domain->nonperiodic > 0) + error->all(FLERR,"Cannot use nonperiodic boundaries with EwaldDipole"); + if (slabflag) { + if (domain->xperiodic != 1 || domain->yperiodic != 1 || + domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) + error->all(FLERR,"Incorrect boundaries with slab EwaldDipole"); + //if (domain->triclinic) + // error->all(FLERR,"Cannot (yet) use EwaldDipole with triclinic box " + // "and slab correction"); + } + + // extract short-range Coulombic cutoff from pair style + + triclinic = domain->triclinic; + if (triclinic) + error->all(FLERR,"Cannot yet use triclinic cells with EwaldDipole"); + + pair_check(); + + int itmp; + double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); + if (p_cutoff == NULL) + error->all(FLERR,"KSpace style is incompatible with Pair style"); + double cutoff = *p_cutoff; + + // kspace TIP4P not yet supported + // qdist = offset only for TIP4P fictitious charge + + //qdist = 0.0; + if (tip4pflag) + error->all(FLERR,"Cannot yet use TIP4P with EwaldDipole"); + + // compute musum & musqsum and warn if no dipole + + scale = 1.0; + qqrd2e = force->qqrd2e; + musum_musq(); + natoms_original = atom->natoms; + + // set accuracy (force units) from accuracy_relative or accuracy_absolute + + if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute; + else accuracy = accuracy_relative * two_charge_force; + + // setup K-space resolution + + bigint natoms = atom->natoms; + + // use xprd,yprd,zprd even if triclinic so grid size is the same + // adjust z dimension for 2d slab EwaldDipole + // 3d EwaldDipole just uses zprd since slab_volfactor = 1.0 + + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + double zprd_slab = zprd*slab_volfactor; + + // make initial g_ewald estimate + // based on desired accuracy and real space cutoff + // fluid-occupied volume used to estimate real-space error + // zprd used rather than zprd_slab + + if (!gewaldflag) { + if (accuracy <= 0.0) + error->all(FLERR,"KSpace accuracy must be > 0"); + if (q2 == 0.0) + error->all(FLERR,"Must use 'kspace_modify gewald' for uncharged system"); + g_ewald = accuracy*sqrt(natoms*cutoff*xprd*yprd*zprd) / (2.0*q2); + if (g_ewald >= 1.0) g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; + else g_ewald = sqrt(-log(g_ewald)) / cutoff; + } + + // setup EwaldDipole coefficients so can print stats + + setup(); + + // final RMS accuracy + + double lprx = rms(kxmax_orig,xprd,natoms,q2); + double lpry = rms(kymax_orig,yprd,natoms,q2); + double lprz = rms(kzmax_orig,zprd_slab,natoms,q2); + double lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0); + double q2_over_sqrt = q2 / sqrt(natoms*cutoff*xprd*yprd*zprd_slab); + double spr = 2.0 *q2_over_sqrt * exp(-g_ewald*g_ewald*cutoff*cutoff); + double tpr = estimate_table_accuracy(q2_over_sqrt,spr); + double estimated_accuracy = sqrt(lpr*lpr + spr*spr + tpr*tpr); + + // stats + + if (comm->me == 0) { + if (screen) { + fprintf(screen," G vector (1/distance) = %g\n",g_ewald); + fprintf(screen," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(screen," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(screen," KSpace vectors: actual max1d max3d = %d %d %d\n", + kcount,kmax,kmax3d); + fprintf(screen," kxmax kymax kzmax = %d %d %d\n", + kxmax,kymax,kzmax); + } + if (logfile) { + fprintf(logfile," G vector (1/distance) = %g\n",g_ewald); + fprintf(logfile," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(logfile," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(logfile," KSpace vectors: actual max1d max3d = %d %d %d\n", + kcount,kmax,kmax3d); + fprintf(logfile," kxmax kymax kzmax = %d %d %d\n", + kxmax,kymax,kzmax); + } + } +} + +/* ---------------------------------------------------------------------- + adjust EwaldDipole coeffs, called initially and whenever volume has changed +------------------------------------------------------------------------- */ + +void EwaldDipole::setup() +{ + // volume-dependent factors + + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + + // adjustment of z dimension for 2d slab EwaldDipole + // 3d EwaldDipole just uses zprd since slab_volfactor = 1.0 + + double zprd_slab = zprd*slab_volfactor; + volume = xprd * yprd * zprd_slab; + + unitk[0] = 2.0*MY_PI/xprd; + unitk[1] = 2.0*MY_PI/yprd; + unitk[2] = 2.0*MY_PI/zprd_slab; + + int kmax_old = kmax; + + if (kewaldflag == 0) { + + // determine kmax + // function of current box size, accuracy, G_ewald (short-range cutoff) + + bigint natoms = atom->natoms; + double err; + kxmax = 1; + kymax = 1; + kzmax = 1; + + // set kmax in 3 directions to respect accuracy + + err = rms_dipole(kxmax,xprd,natoms); + while (err > accuracy) { + kxmax++; + err = rms_dipole(kxmax,xprd,natoms); + } + + err = rms_dipole(kxmax,xprd,natoms); + while (err > accuracy) { + kymax++; + err = rms_dipole(kxmax,xprd,natoms); + } + + err = rms_dipole(kxmax,xprd,natoms); + while (err > accuracy) { + kzmax++; + err = rms_dipole(kxmax,xprd,natoms); + } + + kmax = MAX(kxmax,kymax); + kmax = MAX(kmax,kzmax); + kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; + + double gsqxmx = unitk[0]*unitk[0]*kxmax*kxmax; + double gsqymx = unitk[1]*unitk[1]*kymax*kymax; + double gsqzmx = unitk[2]*unitk[2]*kzmax*kzmax; + gsqmx = MAX(gsqxmx,gsqymx); + gsqmx = MAX(gsqmx,gsqzmx); + + kxmax_orig = kxmax; + kymax_orig = kymax; + kzmax_orig = kzmax; + + // scale lattice vectors for triclinic skew + + //if (triclinic) { + // double tmp[3]; + // tmp[0] = kxmax/xprd; + // tmp[1] = kymax/yprd; + // tmp[2] = kzmax/zprd; + // lamda2xT(&tmp[0],&tmp[0]); + // kxmax = MAX(1,static_cast(tmp[0])); + // kymax = MAX(1,static_cast(tmp[1])); + // kzmax = MAX(1,static_cast(tmp[2])); + + // kmax = MAX(kxmax,kymax); + // kmax = MAX(kmax,kzmax); + // kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; + //} + + } else { + + kxmax = kx_ewald; + kymax = ky_ewald; + kzmax = kz_ewald; + + kxmax_orig = kxmax; + kymax_orig = kymax; + kzmax_orig = kzmax; + + kmax = MAX(kxmax,kymax); + kmax = MAX(kmax,kzmax); + kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; + + double gsqxmx = unitk[0]*unitk[0]*kxmax*kxmax; + double gsqymx = unitk[1]*unitk[1]*kymax*kymax; + double gsqzmx = unitk[2]*unitk[2]*kzmax*kzmax; + gsqmx = MAX(gsqxmx,gsqymx); + gsqmx = MAX(gsqmx,gsqzmx); + } + + gsqmx *= 1.00001; + + // if size has grown, reallocate k-dependent and nlocal-dependent arrays + + if (kmax > kmax_old) { + deallocate(); + allocate(); + group_allocate_flag = 0; + + memory->destroy(ek); + memory->destroy3d_offset(cs,-kmax_created); + memory->destroy3d_offset(sn,-kmax_created); + memory->destroy(muk); + nmax = atom->nmax; + memory->create(ek,nmax,3,"ewald:ek"); + memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs"); + memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn"); + memory->create(muk,kmax3d,nmax,"ewald:muk"); + kmax_created = kmax; + } + + // pre-compute EwaldDipole coefficients + + coeffs(); + //if (triclinic == 0) + // coeffs(); + //else + // coeffs_triclinic(); +} + +/* ---------------------------------------------------------------------- + compute dipole RMS accuracy for a dimension +------------------------------------------------------------------------- */ + +double EwaldDipole::rms_dipole(int km, double prd, bigint natoms) +{ + if (natoms == 0) natoms = 1; // avoid division by zero + + // error from eq.(46), Wang et al., JCP 115, 6351 (2001) + + double value = 8*MY_PI*mu2*g_ewald/volume * + sqrt(2*MY_PI*km*km*km/(15.0*natoms)) * + exp(-MY_PI*MY_PI*km*km/(g_ewald*g_ewald*prd*prd)); + + return value; +} + +/* ---------------------------------------------------------------------- + compute the EwaldDipole long-range force, energy, virial +------------------------------------------------------------------------- */ + +void EwaldDipole::compute(int eflag, int vflag) +{ + int i,j,k; + + // set energy/virial flags + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = evflag_atom = eflag_global = vflag_global = + eflag_atom = vflag_atom = 0; + + // if atom count has changed, update qsum and qsqsum + + if (atom->natoms != natoms_original) { + //qsum_qsq(); + musum_musq(); + natoms_original = atom->natoms; + } + + // return if there are no charges + + if (qsqsum == 0.0) return; + + // extend size of per-atom arrays if necessary + + if (atom->nmax > nmax) { + memory->destroy(ek); + memory->destroy3d_offset(cs,-kmax_created); + memory->destroy3d_offset(sn,-kmax_created); + memory->destroy(muk); + nmax = atom->nmax; + memory->create(ek,nmax,3,"ewald:ek"); + memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs"); + memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn"); + memory->create(muk,kmax3d,nmax,"ewald:muk"); + kmax_created = kmax; + } + + // partial structure factors on each processor + // total structure factor by summing over procs + + //if (triclinic == 0) + // eik_dot_r(); + //else + // eik_dot_r_triclinic(); + eik_dot_r(); + + MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(sfacim,sfacim_all,kcount,MPI_DOUBLE,MPI_SUM,world); + + // K-space portion of electric field + // double loop over K-vectors and local atoms + // perform per-atom calculations if needed + + double **f = atom->f; + double *q = atom->q; + int nlocal = atom->nlocal; + + int kx,ky,kz; + double cypz,sypz,exprl,expim,partial,partial_peratom; + + for (i = 0; i < nlocal; i++) { + ek[i][0] = 0.0; + ek[i][1] = 0.0; + ek[i][2] = 0.0; + } + + for (k = 0; k < kcount; k++) { + kx = kxvecs[k]; + ky = kyvecs[k]; + kz = kzvecs[k]; + + for (i = 0; i < nlocal; i++) { + cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i]; + sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i]; + exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; + expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; + partial = expim*sfacrl_all[k] - exprl*sfacim_all[k]; + ek[i][0] += partial*eg[k][0]; + ek[i][1] += partial*eg[k][1]; + ek[i][2] += partial*eg[k][2]; + + if (evflag_atom) { + partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; + //if (eflag_atom) eatom[i] += q[i]*ug[k]*partial_peratom; + if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; + if (vflag_atom) + for (j = 0; j < 6; j++) + vatom[i][j] += ug[k]*vg[k][j]*partial_peratom; + } + } + } + + // convert E-field to force + + const double qscale = qqrd2e * scale; + const double muscale = qqrd2e * scale; + + for (i = 0; i < nlocal; i++) { + for (k = 0; k < kcount; k++) { + //f[i][0] += qscale * q[i]*ek[i][0]; + //f[i][1] += qscale * q[i]*ek[i][1]; + //if (slabflag != 2) f[i][2] += qscale * q[i]*ek[i][2]; + f[i][0] += muscale * muk[k][i] * ek[i][0]; + f[i][1] += muscale * muk[k][i] * ek[i][1]; + if (slabflag != 2) f[i][2] += muscale * muk[k][i] * ek[i][2]; + } + } + + // sum global energy across Kspace vevs and add in volume-dependent term + + if (eflag_global) { + 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/MY_PIS + + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); + energy *= qscale; + } + + // global virial + + if (vflag_global) { + double uk; + for (k = 0; k < kcount; k++) { + uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); + for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j]; + } + for (j = 0; j < 6; j++) virial[j] *= qscale; + } + + // per-atom energy/virial + // energy includes self-energy correction + + if (evflag_atom) { + if (eflag_atom) { + for (i = 0; i < nlocal; i++) { + eatom[i] -= g_ewald*q[i]*q[i]/MY_PIS + MY_PI2*q[i]*qsum / + (g_ewald*g_ewald*volume); + eatom[i] *= qscale; + } + } + + if (vflag_atom) + for (i = 0; i < nlocal; i++) + for (j = 0; j < 6; j++) vatom[i][j] *= q[i]*qscale; + } + + // 2d slab correction + + if (slabflag == 1) slabcorr(); +} + +/* ---------------------------------------------------------------------- */ + +void EwaldDipole::eik_dot_r() +{ + int i,k,l,m,n,ic; + double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4; + double sqk,clpm,slpm; + double mux, muy, muz; + + double **x = atom->x; + //double *q = atom->q; + double **mu = atom->mu; + int nlocal = atom->nlocal; + + n = 0; + mux = muy = muz = 0.0; + + // loop on different k-directions + // loop on n kpoints and nlocal atoms + // store (n x nlocal) tab. of values of (mu_i dot k) + // store n values of sum_j[ (mu_j dot k) exp(-k dot r_j) ] + + // (k,0,0), (0,l,0), (0,0,m) + + // loop 1: k=1, l=1, m=1 + // define first val. of cos and sin + + for (ic = 0; ic < 3; ic++) { + sqk = (unitk[ic] * unitk[ic]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + for (i = 0; i < nlocal; i++) { + cs[0][ic][i] = 1.0; + sn[0][ic][i] = 0.0; + cs[1][ic][i] = cos(unitk[ic]*x[i][ic]); + sn[1][ic][i] = sin(unitk[ic]*x[i][ic]); + cs[-1][ic][i] = cs[1][0][i]; + sn[-1][ic][i] = -sn[1][0][i]; + muk[n][i] = (mu[i][ic]*unitk[ic]); + cstr1 += muk[n][i]*cs[1][ic][i]; + sstr1 += muk[n][i]*sn[1][ic][i]; + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + } + } + + // loop 2: k>1, l>1, m>1 + + for (m = 2; m <= kmax; m++) { + for (ic = 0; ic < 3; ic++) { + sqk = m*unitk[ic] * m*unitk[ic]; + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + for (i = 0; i < nlocal; i++) { + cs[m][ic][i] = cs[m-1][ic][i]*cs[1][ic][i] - + sn[m-1][ic][i]*sn[1][ic][i]; + sn[m][ic][i] = sn[m-1][ic][i]*cs[1][ic][i] + + cs[m-1][ic][i]*sn[1][ic][i]; + cs[-m][ic][i] = cs[m][ic][i]; + sn[-m][ic][i] = -sn[m][ic][i]; + muk[n][i] = (mu[i][ic]*m*unitk[ic]); + cstr1 += muk[n][i]*cs[1][ic][i]; + sstr1 += muk[n][i]*sn[1][ic][i]; + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + } + } + } + + // 1 = (k,l,0), 2 = (k,-l,0) + + for (k = 1; k <= kxmax; k++) { + for (l = 1; l <= kymax; l++) { + sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + for (i = 0; i < nlocal; i++) { + mux = mu[i][0]; + muy = mu[i][1]; + + // dir 1: (k,l,0) + muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1]); + cstr1 += muk[n][i]*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); + sstr1 += muk[n][i]*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); + + // dir 2: (k,-l,0) + muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1]); + cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); + sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + } + } + } + + // 1 = (0,l,m), 2 = (0,l,-m) + + for (l = 1; l <= kymax; l++) { + for (m = 1; m <= kzmax; m++) { + sqk = (l*unitk[1] * l*unitk[1]) + (m*unitk[2] * m*unitk[2]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + for (i = 0; i < nlocal; i++) { + muy = mu[i][1]; + muz = mu[i][2]; + + // dir 1: (0,l,m) + muk[n][i] = (muy*l*unitk[1] + muz*m*unitk[2]); + cstr1 += muk[n][i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); + sstr1 += muk[n][i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); + + // dir 2: (0,l,-m) + muk[n+1][i] = (muy*l*unitk[1] - muz*m*unitk[2]); + cstr2 += muk[n+1][i]*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); + sstr2 += muk[n+1][i]*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + } + } + } + + // 1 = (k,0,m), 2 = (k,0,-m) + + for (k = 1; k <= kxmax; k++) { + for (m = 1; m <= kzmax; m++) { + sqk = (k*unitk[0] * k*unitk[0]) + (m*unitk[2] * m*unitk[2]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + for (i = 0; i < nlocal; i++) { + mux = mu[i][0]; + muz = mu[i][2]; + + // dir 1: (k,0,m) + muk[n][i] = (mux*k*unitk[0] + muz*m*unitk[2]); + cstr1 += muk[n][i]*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); + sstr1 += muk[n][i]*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); + + // dir 2: (k,0,-m) + muk[n+1][i] = (mux*k*unitk[0] - muz*m*unitk[2]); + cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); + sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + } + } + } + + // 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m) + + for (k = 1; k <= kxmax; k++) { + for (l = 1; l <= kymax; l++) { + for (m = 1; m <= kzmax; m++) { + sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]) + + (m*unitk[2] * m*unitk[2]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + cstr3 = 0.0; + sstr3 = 0.0; + cstr4 = 0.0; + sstr4 = 0.0; + for (i = 0; i < nlocal; i++) { + mux = mu[i][0]; + muy = mu[i][1]; + muz = mu[i][2]; + + // dir 1: (k,l,m) + muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1] + muz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; + slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; + cstr1 += muk[n][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr1 += muk[n][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + + // dir 2: (k,-l,m) + muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1] + muz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; + slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; + cstr2 += muk[n+1][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr2 += muk[n+1][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + + // dir 3: (k,l,-m) + muk[n+2][i] = (mux*k*unitk[0] + muy*l*unitk[1] - muz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; + slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; + cstr3 += muk[n+2][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr3 += muk[n+2][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + + // dir 4: (k,-l,-m) + muk[n+3][i] = (mux*k*unitk[0] - muy*l*unitk[1] - muz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; + slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; + cstr4 += muk[n+3][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr4 += muk[n+3][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + sfacrl[n] = cstr3; + sfacim[n++] = sstr3; + sfacrl[n] = cstr4; + sfacim[n++] = sstr4; + } + } + } + } +} + +/* ---------------------------------------------------------------------- + Slab-geometry correction term to dampen inter-slab interactions between + periodically repeating slabs. Yields good approximation to 2D EwaldDipole if + adequate empty space is left between repeating slabs (J. Chem. Phys. + 111, 3155). Slabs defined here to be parallel to the xy plane. Also + extended to non-neutral systems (J. Chem. Phys. 131, 094107). +------------------------------------------------------------------------- */ + +void EwaldDipole::slabcorr() +{ + // compute local contribution to global dipole moment + + double *q = atom->q; + double **x = atom->x; + double zprd = domain->zprd; + int nlocal = atom->nlocal; + + double dipole = 0.0; + for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2]; + + // sum local contributions to get global dipole moment + + double dipole_all; + MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world); + + // need to make non-neutral systems and/or + // per-atom energy translationally invariant + + double dipole_r2 = 0.0; + if (eflag_atom || fabs(qsum) > SMALL) { + for (int i = 0; i < nlocal; i++) + dipole_r2 += q[i]*x[i][2]*x[i][2]; + + // sum local contributions + + double tmp; + MPI_Allreduce(&dipole_r2,&tmp,1,MPI_DOUBLE,MPI_SUM,world); + dipole_r2 = tmp; + } + + // compute corrections + + const double e_slabcorr = MY_2PI*(dipole_all*dipole_all - + qsum*dipole_r2 - qsum*qsum*zprd*zprd/12.0)/volume; + const double qscale = qqrd2e * scale; + + if (eflag_global) energy += qscale * e_slabcorr; + + // per-atom energy + + if (eflag_atom) { + double efact = qscale * MY_2PI/volume; + for (int i = 0; i < nlocal; i++) + eatom[i] += efact * q[i]*(x[i][2]*dipole_all - 0.5*(dipole_r2 + + qsum*x[i][2]*x[i][2]) - qsum*zprd*zprd/12.0); + } + + // add on force corrections + + double ffact = qscale * (-4.0*MY_PI/volume); + double **f = atom->f; + + for (int i = 0; i < nlocal; i++) f[i][2] += ffact * q[i]*(dipole_all - qsum*x[i][2]); +} + +/* ---------------------------------------------------------------------- + compute musum,musqsum,mu2 + called initially, when particle count changes, when dipoles are changed +------------------------------------------------------------------------- */ + +void EwaldDipole::musum_musq() +{ + const int nlocal = atom->nlocal; + + musum = musqsum = mu2 = 0.0; + if (atom->mu_flag) { + double** mu = atom->mu; + double musum_local(0.0), musqsum_local(0.0); + + for (int i = 0; i < nlocal; i++) { + musum_local += mu[i][0] + mu[i][1] + mu[i][2]; + musqsum_local += mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]; + } + + MPI_Allreduce(&musum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&musqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); + + mu2 = musqsum * force->qqrd2e; + } + + if (mu2 == 0 && comm->me == 0) + error->all(FLERR,"Using kspace solver PPPMDipole on system with no dipoles"); +} diff --git a/src/KSPACE/ewald_dipole.h b/src/KSPACE/ewald_dipole.h new file mode 100644 index 0000000000..5cd969bbee --- /dev/null +++ b/src/KSPACE/ewald_dipole.h @@ -0,0 +1,104 @@ +/* -*- 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 KSPACE_CLASS + +KSpaceStyle(ewald/dipole,EwaldDipole) + +#else + +#ifndef LMP_EWALD_DIPOLE_H +#define LMP_EWALD_DIPOLE_H + +#include "ewald.h" + +namespace LAMMPS_NS { + +class EwaldDipole : public Ewald { + public: + EwaldDipole(class LAMMPS *, int, char **); + virtual ~EwaldDipole(); + void init(); + void setup(); + virtual void compute(int, int); + + protected: + double musum,musqsum,mu2; + double **muk; // mu_i dot k + + void musum_musq(); + double rms_dipole(int, double, bigint); + virtual void eik_dot_r(); + void slabcorr(); + + // triclinic + + //void eik_dot_r_triclinic(); + +}; + +} + +#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. + +E: Cannot use EwaldDipole with 2d simulation + +The kspace style ewald cannot be used in 2d simulations. You can use +2d EwaldDipole in a 3d simulation; see the kspace_modify command. + +E: Kspace style requires atom attribute q + +The atom style defined does not have these attributes. + +E: Cannot use nonperiodic boundaries with EwaldDipole + +For kspace style ewald, all 3 dimensions must have periodic boundaries +unless you use the kspace_modify command to define a 2d slab with a +non-periodic z dimension. + +E: Incorrect boundaries with slab EwaldDipole + +Must have periodic x,y dimensions and non-periodic z dimension to use +2d slab option with EwaldDipole. + +E: Cannot (yet) use EwaldDipole with triclinic box and slab correction + +This feature is not yet supported. + +E: KSpace style is incompatible with Pair style + +Setting a kspace style requires that a pair style with matching +long-range Coulombic or dispersion components be used. + +E: KSpace accuracy must be > 0 + +The kspace accuracy designated in the input must be greater than zero. + +E: Must use 'kspace_modify gewald' for uncharged system + +UNDOCUMENTED + +E: Cannot (yet) use K-space slab correction with compute group/group for triclinic systems + +This option is not yet supported. + +*/ diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 8eec8e2542..694860521e 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -100,9 +100,6 @@ PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg), nyhi_in = nylo_in = nyhi_out = nylo_out = 0; nzhi_in = nzlo_in = nzhi_out = nzlo_out = 0; - // test - nlower = nupper = 0; - density_brick = vdx_brick = vdy_brick = vdz_brick = NULL; density_fft = NULL; u_brick = NULL; diff --git a/src/KSPACE/pppm_dipole.cpp b/src/KSPACE/pppm_dipole.cpp index 4d2b594af8..fd986f5eb1 100644 --- a/src/KSPACE/pppm_dipole.cpp +++ b/src/KSPACE/pppm_dipole.cpp @@ -126,8 +126,9 @@ void PPPMDipole::init() if (triclinic != domain->triclinic) error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); - if (domain->dimension == 2) error->all(FLERR, - "Cannot use PPPMDipole with 2d simulation"); + if (domain->dimension == 2) + error->all(FLERR,"Cannot use PPPMDipole with 2d simulation"); + if (comm->style != 0) error->universe_all(FLERR,"PPPMDipole can only currently be used with " "comm_style brick"); @@ -175,7 +176,7 @@ void PPPMDipole::init() if (tip4pflag) error->all(FLERR,"Cannot yet use TIP4P with PPPMDipole"); - // compute qsum & qsqsum and warn if not charge-neutral + // compute musum & musqsum and warn if no dipoles scale = 1.0; qqrd2e = force->qqrd2e; @@ -794,7 +795,6 @@ void PPPMDipole::deallocate_peratom() used for charge accumulation, FFTs, and electric field interpolation ------------------------------------------------------------------------- */ -//void PPPMDipole::set_grid_global(double dipole2) void PPPMDipole::set_grid_global() { // use xprd,yprd,zprd diff --git a/src/KSPACE/pppm_dipole_spin.cpp b/src/KSPACE/pppm_dipole_spin.cpp index a5aee7150c..aa85c5d289 100644 --- a/src/KSPACE/pppm_dipole_spin.cpp +++ b/src/KSPACE/pppm_dipole_spin.cpp @@ -710,10 +710,8 @@ void PPPMDipoleSpin::slabcorr() // add on mag. force corrections double ffact = spscale * (-4.0*MY_PI/volume); - //double **fm = atom->fm; double **fm_long = atom->fm_long; for (int i = 0; i < nlocal; i++) { - //fm[i][2] += ffact * spin_all; fm_long[i][2] += ffact * spin_all; } } -- GitLab From 634ed487a5048b72147acdb09443218a5386fd60 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Tue, 4 Sep 2018 22:43:55 -0500 Subject: [PATCH 0041/1243] Use pkg-config to find kim-api-v2 library settings --- lib/kim/Makefile.lammps | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/kim/Makefile.lammps b/lib/kim/Makefile.lammps index c7c9d9fd2f..1c2ab417d5 100644 --- a/lib/kim/Makefile.lammps +++ b/lib/kim/Makefile.lammps @@ -5,8 +5,6 @@ # The KIM API package can be downloaded from https://openkim.org/kim-api # Follow the instructions in the INSTALL file to build and install the # KIM API. Add the openkim.org Models you are interested in using. -# Make sure the directory where the "kim-api-build-conifg" utility is -# located is on the PATH. # # As long as you have followed the KIM API build and install instructions, # there should not be any reason to change this file. @@ -15,18 +13,5 @@ # Settings that the LAMMPS build will import when this package is installed - -include ../../lib/kim/Makefile.KIM_DIR - -ifeq ($(wildcard $(KIM_INSTALL_DIR)/bin/kim-api-v2-build-config),) - KIM_CONFIG_HELPER = kim-api-v2-build-config -else - KIM_CONFIG_HELPER = $(KIM_INSTALL_DIR)/bin/kim-api-v2-build-config -endif -ifeq ($(shell $(KIM_CONFIG_HELPER) --version 2> /dev/null),) - $(error $(KIM_CONFIG_HELPER) utility is not available. Something is wrong with your KIM API package setup) -endif - -kim_SYSINC = $(shell $(KIM_CONFIG_HELPER) --includes) -kim_SYSLIB = $(shell $(KIM_CONFIG_HELPER) --ldlibs) -kim_SYSPATH = $(shell $(KIM_CONFIG_HELPER) --ldflags) +kim_SYSINC = $(shell pkg-config --cflags libkim-api-v2) +kim_SYSLIB = $(shell pkg-config --libs libkim-api-v2) -- GitLab From e6b5112ddc80ed86a97ed05176aae2b01ccb9e8b Mon Sep 17 00:00:00 2001 From: "Stan Gerald Moore (stamoor)" Date: Thu, 13 Sep 2018 14:36:54 -0600 Subject: [PATCH 0042/1243] Fix issues in ewald_dipole --- src/KSPACE/ewald_dipole.cpp | 86 +++++++++++++++++++++++++++++++------ src/KSPACE/ewald_dipole.h | 3 ++ 2 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index d03d93a7c5..43c4717096 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -28,6 +28,7 @@ #include "pair.h" #include "domain.h" #include "math_const.h" +#include "math_special.h" #include "memory.h" #include "error.h" #include "update.h" @@ -37,6 +38,7 @@ using namespace LAMMPS_NS; using namespace MathConst; +using namespace MathSpecial; #define SMALL 0.00001 @@ -157,13 +159,11 @@ void EwaldDipole::init() // zprd used rather than zprd_slab if (!gewaldflag) { - if (accuracy <= 0.0) - error->all(FLERR,"KSpace accuracy must be > 0"); - if (q2 == 0.0) - error->all(FLERR,"Must use 'kspace_modify gewald' for uncharged system"); - g_ewald = accuracy*sqrt(natoms*cutoff*xprd*yprd*zprd) / (2.0*q2); - if (g_ewald >= 1.0) g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; - else g_ewald = sqrt(-log(g_ewald)) / cutoff; + double g_ewald_new = + NewtonSolve(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); + if (g_ewald_new > 0.0) g_ewald = g_ewald_new; + else error->warning(FLERR,"Ewald/disp Newton solver failed, " + "using old method to estimate g_ewald"); } // setup EwaldDipole coefficients so can print stats @@ -252,16 +252,16 @@ void EwaldDipole::setup() err = rms_dipole(kxmax,xprd,natoms); } - err = rms_dipole(kxmax,xprd,natoms); + err = rms_dipole(kymax,yprd,natoms); while (err > accuracy) { kymax++; - err = rms_dipole(kxmax,xprd,natoms); + err = rms_dipole(kymax,yprd,natoms); } - err = rms_dipole(kxmax,xprd,natoms); + err = rms_dipole(kzmax,zprd,natoms); while (err > accuracy) { kzmax++; - err = rms_dipole(kxmax,xprd,natoms); + err = rms_dipole(kzmax,zprd,natoms); } kmax = MAX(kxmax,kymax); @@ -387,7 +387,7 @@ void EwaldDipole::compute(int eflag, int vflag) // return if there are no charges - if (qsqsum == 0.0) return; + if (musqsum == 0.0) return; // extend size of per-atom arrays if necessary @@ -482,8 +482,8 @@ void EwaldDipole::compute(int eflag, int vflag) energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - energy -= g_ewald*qsqsum/MY_PIS + - MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); + const double g3 = g_ewald*g_ewald*g_ewald; + energy -= musqsum*2.0*g3/3.0/MY_PIS; energy *= qscale; } @@ -845,3 +845,61 @@ void EwaldDipole::musum_musq() if (mu2 == 0 && comm->me == 0) error->all(FLERR,"Using kspace solver PPPMDipole on system with no dipoles"); } + +/* ---------------------------------------------------------------------- + Newton solver used to find g_ewald for LJ systems +------------------------------------------------------------------------- */ + +double EwaldDipole::NewtonSolve(double x, double Rc, + bigint natoms, double vol, double b2) +{ + double dx,tol; + int maxit; + + maxit = 10000; //Maximum number of iterations + tol = 0.00001; //Convergence tolerance + + //Begin algorithm + + for (int i = 0; i < maxit; i++) { + dx = f(x,Rc,natoms,vol,b2) / derivf(x,Rc,natoms,vol,b2); + x = x - dx; //Update x + if (fabs(dx) < tol) return x; + if (x < 0 || x != x) // solver failed + return -1; + } + return -1; +} + +/* ---------------------------------------------------------------------- + Calculate f(x) + ------------------------------------------------------------------------- */ + +double EwaldDipole::f(double x, double Rc, bigint natoms, double vol, double b2) +{ + double a = Rc*x; + double f = 0.0; + + double rg2 = a*a; + double rg4 = rg2*rg2; + double rg6 = rg4*rg2; + double Cc = 4.0*rg4 + 6.0*rg2 + 3.0; + double Dc = 8.0*rg6 + 20.0*rg4 + 30.0*rg2 + 15.0; + f = (b2/(sqrt(vol*powint(x,4)*powint(Rc,9)*natoms)) * + sqrt(13.0/6.0*Cc*Cc + 2.0/15.0*Dc*Dc - 13.0/15.0*Cc*Dc) * + exp(-rg2)) - accuracy; + + return f; +} + +/* ---------------------------------------------------------------------- + Calculate numerical derivative f'(x) + ------------------------------------------------------------------------- */ + +double EwaldDipole::derivf(double x, double Rc, + bigint natoms, double vol, double b2) +{ + double h = 0.000001; //Derivative step-size + return (f(x + h,Rc,natoms,vol,b2) - f(x,Rc,natoms,vol,b2)) / h; +} + diff --git a/src/KSPACE/ewald_dipole.h b/src/KSPACE/ewald_dipole.h index 5cd969bbee..77f6a2817c 100644 --- a/src/KSPACE/ewald_dipole.h +++ b/src/KSPACE/ewald_dipole.h @@ -40,6 +40,9 @@ class EwaldDipole : public Ewald { double rms_dipole(int, double, bigint); virtual void eik_dot_r(); void slabcorr(); + double NewtonSolve(double, double, bigint, double, double); + double f(double, double, bigint, double, double); + double derivf(double, double, bigint, double, double); // triclinic -- GitLab From a76457ef22d0864b78dc4b48f1c249a3fd153a47 Mon Sep 17 00:00:00 2001 From: "Stan Gerald Moore (stamoor)" Date: Fri, 14 Sep 2018 13:05:48 -0600 Subject: [PATCH 0043/1243] Fix bug in ewald_dipole structure factor --- src/KSPACE/ewald_dipole.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index 43c4717096..d7c3aad206 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -584,8 +584,8 @@ void EwaldDipole::eik_dot_r() cs[-m][ic][i] = cs[m][ic][i]; sn[-m][ic][i] = -sn[m][ic][i]; muk[n][i] = (mu[i][ic]*m*unitk[ic]); - cstr1 += muk[n][i]*cs[1][ic][i]; - sstr1 += muk[n][i]*sn[1][ic][i]; + cstr1 += muk[n][i]*cs[m][ic][i]; + sstr1 += muk[n][i]*sn[m][ic][i]; } sfacrl[n] = cstr1; sfacim[n++] = sstr1; -- GitLab From 82a5346ab1f1ddfa8ad114a7dceff47d0cdbe0ee Mon Sep 17 00:00:00 2001 From: julient31 Date: Fri, 14 Sep 2018 15:09:59 -0600 Subject: [PATCH 0044/1243] Commit JT 091418 - created pair_spin_long_qsymp - modified ewald_dipole --- examples/SPIN/pppm_spin/in.spin.pppm_spin | 7 +- src/KSPACE/ewald_dipole.cpp | 100 ++-- src/KSPACE/ewald_dipole.h | 6 +- src/SPIN/fix_nve_spin.cpp | 17 +- src/SPIN/fix_nve_spin.h | 1 - src/SPIN/pair_spin_long.cpp | 24 +- src/SPIN/pair_spin_long_qsymp.cpp | 655 ++++++++++++++++++++++ src/SPIN/pair_spin_long_qsymp.h | 100 ++++ 8 files changed, 828 insertions(+), 82 deletions(-) create mode 100644 src/SPIN/pair_spin_long_qsymp.cpp create mode 100644 src/SPIN/pair_spin_long_qsymp.h diff --git a/examples/SPIN/pppm_spin/in.spin.pppm_spin b/examples/SPIN/pppm_spin/in.spin.pppm_spin index f7e462c343..9e57797f55 100644 --- a/examples/SPIN/pppm_spin/in.spin.pppm_spin +++ b/examples/SPIN/pppm_spin/in.spin.pppm_spin @@ -23,17 +23,20 @@ mass 1 58.93 set group all spin 1.72 0.0 0.0 1.0 velocity all create 100 4928459 rot yes dist gaussian -pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 +pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long/qsymp 8.0 #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 -pair_coeff * * spin/long long 8.0 +pair_coeff * * spin/long/qsymp long 8.0 +#pair_coeff * * spin/long long 8.0 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 kspace_style pppm/dipole/spin 1.0e-4 kspace_modify mesh 32 32 32 + #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 fix 2 all langevin/spin 0.0 0.0 21 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index d03d93a7c5..3b3e3b93db 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -79,9 +79,9 @@ void EwaldDipole::init() triclinic_check(); - // set triclinic to 0 for now (no triclinic calc.) - triclinic = 0; - + // no triclinic ewald dipole (yet) + + triclinic = domain->triclinic; if (triclinic) error->all(FLERR,"Cannot (yet) use EwaldDipole with triclinic box"); @@ -100,9 +100,6 @@ void EwaldDipole::init() if (domain->xperiodic != 1 || domain->yperiodic != 1 || domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) error->all(FLERR,"Incorrect boundaries with slab EwaldDipole"); - //if (domain->triclinic) - // error->all(FLERR,"Cannot (yet) use EwaldDipole with triclinic box " - // "and slab correction"); } // extract short-range Coulombic cutoff from pair style @@ -278,23 +275,6 @@ void EwaldDipole::setup() kymax_orig = kymax; kzmax_orig = kzmax; - // scale lattice vectors for triclinic skew - - //if (triclinic) { - // double tmp[3]; - // tmp[0] = kxmax/xprd; - // tmp[1] = kymax/yprd; - // tmp[2] = kzmax/zprd; - // lamda2xT(&tmp[0],&tmp[0]); - // kxmax = MAX(1,static_cast(tmp[0])); - // kymax = MAX(1,static_cast(tmp[1])); - // kzmax = MAX(1,static_cast(tmp[2])); - - // kmax = MAX(kxmax,kymax); - // kmax = MAX(kmax,kzmax); - // kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; - //} - } else { kxmax = kx_ewald; @@ -340,10 +320,6 @@ void EwaldDipole::setup() // pre-compute EwaldDipole coefficients coeffs(); - //if (triclinic == 0) - // coeffs(); - //else - // coeffs_triclinic(); } /* ---------------------------------------------------------------------- @@ -380,7 +356,6 @@ void EwaldDipole::compute(int eflag, int vflag) // if atom count has changed, update qsum and qsqsum if (atom->natoms != natoms_original) { - //qsum_qsq(); musum_musq(); natoms_original = atom->natoms; } @@ -407,10 +382,6 @@ void EwaldDipole::compute(int eflag, int vflag) // partial structure factors on each processor // total structure factor by summing over procs - //if (triclinic == 0) - // eik_dot_r(); - //else - // eik_dot_r_triclinic(); eik_dot_r(); MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world); @@ -421,7 +392,8 @@ void EwaldDipole::compute(int eflag, int vflag) // perform per-atom calculations if needed double **f = atom->f; - double *q = atom->q; + //double *q = atom->q; + double **mu = atom->mu; int nlocal = atom->nlocal; int kx,ky,kz; @@ -439,21 +411,34 @@ void EwaldDipole::compute(int eflag, int vflag) kz = kzvecs[k]; for (i = 0; i < nlocal; i++) { + + // calculating exp(i*k*ri) + cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i]; sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i]; exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; + + // taking im-part of struct_fact x exp(i*k*ri) (for force calc.) + partial = expim*sfacrl_all[k] - exprl*sfacim_all[k]; - ek[i][0] += partial*eg[k][0]; - ek[i][1] += partial*eg[k][1]; - ek[i][2] += partial*eg[k][2]; + //ek[i][0] += partial*eg[k][0]; + //ek[i][1] += partial*eg[k][1]; + //ek[i][2] += partial*eg[k][2]; + ek[i][0] += kx*partial*eg[k][0]; + ek[i][1] += ky*partial*eg[k][1]; + ek[i][2] += kz*partial*eg[k][2]; if (evflag_atom) { + + // taking re-part of struct_fact x exp(i*k*ri) (for energy calc.) + partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; //if (eflag_atom) eatom[i] += q[i]*ug[k]*partial_peratom; if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; if (vflag_atom) for (j = 0; j < 6; j++) + // to be done vatom[i][j] += ug[k]*vg[k][j]*partial_peratom; } } @@ -461,30 +446,33 @@ void EwaldDipole::compute(int eflag, int vflag) // convert E-field to force - const double qscale = qqrd2e * scale; + //const double qscale = qqrd2e * scale; const double muscale = qqrd2e * scale; for (i = 0; i < nlocal; i++) { - for (k = 0; k < kcount; k++) { - //f[i][0] += qscale * q[i]*ek[i][0]; - //f[i][1] += qscale * q[i]*ek[i][1]; - //if (slabflag != 2) f[i][2] += qscale * q[i]*ek[i][2]; - f[i][0] += muscale * muk[k][i] * ek[i][0]; - f[i][1] += muscale * muk[k][i] * ek[i][1]; - if (slabflag != 2) f[i][2] += muscale * muk[k][i] * ek[i][2]; - } + //f[i][0] += qscale * q[i]*ek[i][0]; + //f[i][1] += qscale * q[i]*ek[i][1]; + //if (slabflag != 2) f[i][2] += qscale * q[i]*ek[i][2]; + f[i][0] += muscale * mu[i][0] * ek[i][0]; + f[i][1] += muscale * mu[i][1] * ek[i][1]; + if (slabflag != 2) f[i][2] += muscale * mu[i][2] * ek[i][2]; } // sum global energy across Kspace vevs and add in volume-dependent term if (eflag_global) { - for (k = 0; k < kcount; k++) + for (k = 0; k < kcount; k++) { + + // taking the re-part of struct_fact_i x struct_fact_j + energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); + } + + // substracting self energy and scaling - energy -= g_ewald*qsqsum/MY_PIS + - MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); - energy *= qscale; + energy -= musqsum*2.0*g3/3.0/MY_PIS; + energy *= muscale; } // global virial @@ -495,7 +483,8 @@ void EwaldDipole::compute(int eflag, int vflag) uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j]; } - for (j = 0; j < 6; j++) virial[j] *= qscale; + //for (j = 0; j < 6; j++) virial[j] *= qscale; + for (j = 0; j < 6; j++) virial[j] *= muscale; } // per-atom energy/virial @@ -504,9 +493,9 @@ void EwaldDipole::compute(int eflag, int vflag) if (evflag_atom) { if (eflag_atom) { for (i = 0; i < nlocal; i++) { - eatom[i] -= g_ewald*q[i]*q[i]/MY_PIS + MY_PI2*q[i]*qsum / - (g_ewald*g_ewald*volume); - eatom[i] *= qscale; + eatom[i] -= (mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2]) + *2.0*g3/3.0/MY_PIS; + eatom[i] *= muscale; } } @@ -520,7 +509,9 @@ void EwaldDipole::compute(int eflag, int vflag) if (slabflag == 1) slabcorr(); } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + compute the +------------------------------------------------------------------------- */ void EwaldDipole::eik_dot_r() { @@ -530,7 +521,6 @@ void EwaldDipole::eik_dot_r() double mux, muy, muz; double **x = atom->x; - //double *q = atom->q; double **mu = atom->mu; int nlocal = atom->nlocal; diff --git a/src/KSPACE/ewald_dipole.h b/src/KSPACE/ewald_dipole.h index 5cd969bbee..401742ed3a 100644 --- a/src/KSPACE/ewald_dipole.h +++ b/src/KSPACE/ewald_dipole.h @@ -34,17 +34,13 @@ class EwaldDipole : public Ewald { protected: double musum,musqsum,mu2; - double **muk; // mu_i dot k + double **muk; // store mu_i dot k void musum_musq(); double rms_dipole(int, double, bigint); virtual void eik_dot_r(); void slabcorr(); - // triclinic - - //void eik_dot_r_triclinic(); - }; } diff --git a/src/SPIN/fix_nve_spin.cpp b/src/SPIN/fix_nve_spin.cpp index 996bd3c2da..5e972cd14d 100644 --- a/src/SPIN/fix_nve_spin.cpp +++ b/src/SPIN/fix_nve_spin.cpp @@ -295,6 +295,13 @@ void FixNVESpin::initial_integrate(int vflag) } } + // update fm_kspace if long-range + // remove short-range comp. of fm_kspace + + if (long_spin_flag) { + + } + // update half s for all atoms if (sector_flag) { // sectoring seq. update @@ -434,7 +441,7 @@ void FixNVESpin::ComputeInteractionsSpin(int i) double **sp = atom->sp; double **fm = atom->fm; - double **fm_long = atom->fm_long; + //double **fm_long = atom->fm_long; // force computation for spin i @@ -452,14 +459,6 @@ void FixNVESpin::ComputeInteractionsSpin(int i) } } - // update magnetic long-range components - - if (long_spin_flag) { - fmi[0] += fm_long[i][0]; - fmi[1] += fm_long[i][1]; - fmi[2] += fm_long[i][2]; - } - // update magnetic precession interactions if (precession_spin_flag) { diff --git a/src/SPIN/fix_nve_spin.h b/src/SPIN/fix_nve_spin.h index 565de13e92..9fcbfb3803 100644 --- a/src/SPIN/fix_nve_spin.h +++ b/src/SPIN/fix_nve_spin.h @@ -48,7 +48,6 @@ friend class PairSpin; int lattice_flag; // lattice_flag = 0 if spins only // lattice_flag = 1 if spin-lattice calc. - protected: int sector_flag; // sector_flag = 0 if serial algorithm // sector_flag = 1 if parallel algorithm diff --git a/src/SPIN/pair_spin_long.cpp b/src/SPIN/pair_spin_long.cpp index efedea3247..d7ecdf5edd 100644 --- a/src/SPIN/pair_spin_long.cpp +++ b/src/SPIN/pair_spin_long.cpp @@ -362,13 +362,15 @@ void PairSpinLong::compute_single_pair(int ii, double fmi[3]) int i,j,jj,jnum,itype,jtype; double r,rinv,r2inv,rsq; double grij,expm2,t,erfc; - double bij[4],xi[3],rij[3],spi[4],spj[4]; + double bij[4],xi[3],rij[3]; + double spi[4],spj[4]; double local_cut2; double pre1,pre2,pre3; int *ilist,*jlist,*numneigh,**firstneigh; double **x = atom->x; double **sp = atom->sp; + double **fm_long = atom->fm_long; int *type = atom->type; ilist = list->ilist; @@ -433,15 +435,16 @@ void PairSpinLong::compute_single_pair(int ii, double fmi[3]) } } - // force accumulation + // adding the kspace components to fm + + fmi[0] += fm_long[i][0]; + fmi[1] += fm_long[i][1]; + fmi[2] += fm_long[i][2]; - fmi[0] *= mub2mu0hbinv; - fmi[1] *= mub2mu0hbinv; - fmi[2] *= mub2mu0hbinv; } /* ---------------------------------------------------------------------- - compute exchange interaction between spins i and j + compute dipolar interaction between spins i and j ------------------------------------------------------------------------- */ void PairSpinLong::compute_long(int i, int j, double rij[3], @@ -456,13 +459,14 @@ void PairSpinLong::compute_long(int i, int j, double rij[3], b1 = bij[1]; b2 = bij[2]; - fmi[0] += gigj * (b2 * sjdotr *rij[0] - b1 * spj[0]); - fmi[1] += gigj * (b2 * sjdotr *rij[1] - b1 * spj[1]); - fmi[2] += gigj * (b2 * sjdotr *rij[2] - b1 * spj[2]); + fmi[0] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[0] - b1 * spj[0]); + fmi[1] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[1] - b1 * spj[1]); + fmi[2] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[2] - b1 * spj[2]); } /* ---------------------------------------------------------------------- - compute the mechanical force due to the exchange interaction between atom i and atom j + compute the mechanical force due to the dipolar interaction between + atom i and atom j ------------------------------------------------------------------------- */ void PairSpinLong::compute_long_mech(int i, int j, double rij[3], diff --git a/src/SPIN/pair_spin_long_qsymp.cpp b/src/SPIN/pair_spin_long_qsymp.cpp new file mode 100644 index 0000000000..3b499d0ef7 --- /dev/null +++ b/src/SPIN/pair_spin_long_qsymp.cpp @@ -0,0 +1,655 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + www.cs.sandia.gov/~sjplimp/lammps.html + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + 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: Julien Tranchida (SNL) + Aidan Thompson (SNL) + + Please cite the related publication: + Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). + Massively parallel symplectic algorithm for coupled magnetic spin dynamics + and molecular dynamics. Journal of Computational Physics. +------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +#include "pair_spin_long_qsymp.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "fix_nve_spin.h" +#include "force.h" +#include "kspace.h" +#include "math_const.h" +#include "memory.h" +#include "modify.h" +#include "error.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace MathConst; + +#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 + +/* ---------------------------------------------------------------------- */ + +PairSpinLongQsymp::PairSpinLongQsymp(LAMMPS *lmp) : PairSpin(lmp), +lockfixnvespin(NULL) +{ + single_enable = 0; + ewaldflag = pppmflag = spinflag = 1; + respa_enable = 0; + no_virial_fdotr_compute = 1; + lattice_flag = 0; + + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairSpinLongQsymp::~PairSpinLongQsymp() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cut_spin_long); + memory->destroy(cutsq); + } +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::settings(int narg, char **arg) +{ + if (narg < 1 || narg > 2) + error->all(FLERR,"Incorrect args in pair_style command"); + + if (strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"Spin simulations require metal unit style"); + + cut_spin_long_global = force->numeric(FLERR,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_spin_long[i][j] = cut_spin_long_global; + } + } + } + } + +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::coeff(int narg, char **arg) +{ + if (!allocated) allocate(); + + // check if args correct + + if (strcmp(arg[2],"long") != 0) + error->all(FLERR,"Incorrect args in pair_style command"); + if (narg < 1 || narg > 4) + error->all(FLERR,"Incorrect args in pair_style command"); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double spin_long_cut_one = force->numeric(FLERR,arg[3]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + setflag[i][j] = 1; + cut_spin_long[i][j] = spin_long_cut_one; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::init_style() +{ + if (!atom->sp_flag) + error->all(FLERR,"Pair spin requires atom/spin style"); + + // need a full neighbor list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + + // checking if nve/spin is a listed fix + + int ifix = 0; + while (ifix < modify->nfix) { + if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + ifix++; + } + if (ifix == modify->nfix) + error->all(FLERR,"pair/spin style requires nve/spin"); + + // get the lattice_flag from nve/spin + + for (int i = 0; i < modify->nfix; i++) { + if (strcmp(modify->fix[i]->style,"nve/spin") == 0) { + lockfixnvespin = (FixNVESpin *) modify->fix[i]; + lattice_flag = lockfixnvespin->lattice_flag; + } + } + + // insure use of KSpace long-range solver, set g_ewald + + if (force->kspace == NULL) + error->all(FLERR,"Pair style requires a KSpace style"); + + g_ewald = force->kspace->g_ewald; + +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairSpinLongQsymp::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + cut_spin_long[j][i] = cut_spin_long[i][j]; + + return cut_spin_long_global; +} + +/* ---------------------------------------------------------------------- + extract the larger cutoff if "cut" or "cut_coul" +------------------------------------------------------------------------- */ + +void *PairSpinLongQsymp::extract(const char *str, int &dim) +{ + if (strcmp(str,"cut") == 0) { + dim = 0; + return (void *) &cut_spin_long_global; + } else if (strcmp(str,"cut_coul") == 0) { + dim = 0; + return (void *) &cut_spin_long_global; + } else if (strcmp(str,"ewald_order") == 0) { + ewald_order = 0; + ewald_order |= 1<<1; + ewald_order |= 1<<3; + dim = 0; + return (void *) &ewald_order; + } else if (strcmp(str,"ewald_mix") == 0) { + dim = 0; + return (void *) &mix_flag; + } + return NULL; +} + +/* ---------------------------------------------------------------------- */ + +void PairSpinLongQsymp::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double r,rinv,r2inv,rsq; + double grij,expm2,t,erfc,erf; + double sjdotr,gigj; + double bij[4]; + double cij[4]; + double evdwl,ecoul; + double xi[3],rij[3]; + double spi[4],spj[4],fi[3],fmi[3]; + double fmx_erf_s,fmy_erf_s,fmz_erf_s; + double local_cut2; + double pre1,pre2,pre3; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + double **fm = atom->fm; + double **fm_long = atom->fm_long; + double **sp = atom->sp; + 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; + + pre1 = 2.0 * g_ewald / MY_PIS; + pre2 = 4.0 * pow(g_ewald,3.0) / MY_PIS; + pre3 = 8.0 * pow(g_ewald,5.0) / MY_PIS; + + // computation of the exchange interaction + // loop over atoms and their neighbors + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spi[3] = sp[i][3]; + itype = type[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + spj[3] = sp[j][3]; + + evdwl = 0.0; + + fi[0] = fi[1] = fi[2] = 0.0; + fmi[0] = fmi[1] = fmi[2] = 0.0; + fmx_erf_s = fmy_erf_s = fmz_erf_s = 0.0; + bij[0] = bij[1] = bij[2] = bij[3] = 0.0; + cij[0] = cij[1] = cij[2] = cij[3] = 0.0; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + + local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + + if (rsq < local_cut2) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + + 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; + erf = 1.0 - t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + + // evaluating erfc for mech. force and energy calc. + + bij[0] = erfc * rinv; + bij[1] = (bij[0] + pre1*expm2) * r2inv; + bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + + compute_long(i,j,rij,bij,fmi,spi,spj); + compute_long_mech(i,j,rij,bij,fmi,spi,spj); + + // evaluating erf comp. for fm_kspace correction + + cij[0] = erf * rinv; + cij[1] = (bij[0] + pre1*expm2) * r2inv; + cij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + //cij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + + gigj = spi[3] * spj[3]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + // evaluating short-range correction to the kspace part on [0,rc] + + fmx_erf_s += gigj * (cij[2] * sjdotr * rij[0] - cij[1] * spj[0]); + fmy_erf_s += gigj * (cij[2] * sjdotr * rij[1] - cij[1] * spj[1]); + fmz_erf_s += gigj * (cij[2] * sjdotr * rij[2] - cij[1] * spj[2]); + + } + + // force accumulation + + f[i][0] += fi[0] * mub2mu0; + f[i][1] += fi[1] * mub2mu0; + f[i][2] += fi[2] * mub2mu0; + fm[i][0] += fmi[0] * mub2mu0hbinv; + fm[i][1] += fmi[1] * mub2mu0hbinv; + fm[i][2] += fmi[2] * mub2mu0hbinv; + + // correction of the fm_kspace + + fm_long[i][0] -= mub2mu0hbinv * fmx_erf_s; + fm_long[i][1] -= mub2mu0hbinv * fmy_erf_s; + fm_long[i][2] -= mub2mu0hbinv * fmz_erf_s; + + if (newton_pair || j < nlocal) { + f[j][0] -= fi[0]; + f[j][1] -= fi[1]; + f[j][2] -= fi[2]; + } + + if (eflag) { + if (rsq <= local_cut2) { + evdwl -= spi[0]*fmi[0] + spi[1]*fmi[1] + + spi[2]*fmi[2]; + evdwl *= hbar; + } + } else evdwl = 0.0; + + + if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, + evdwl,ecoul,fi[0],fi[1],fi[2],rij[0],rij[1],rij[2]); + + } + } +} + +/* ---------------------------------------------------------------------- + update the pair interaction fmi acting on the spin ii + adding 1/r (for r in [0,rc]) contribution to the pair + removing erf(r)/r (for r in [0,rc]) from the kspace force +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) +{ + int i,j,jj,jnum,itype,jtype; + double r,rinv,r2inv,r3inv,rsq; + double grij,expm2,t,erf; + double sjdotr,sjdotrr3inv; + double b1,b2,gigj; + double bij[4],xi[3],rij[3]; + double spi[4],spj[4]; + double local_cut2; + double pre1,pre2,pre3; + int *ilist,*jlist,*numneigh,**firstneigh; + //double fmx_erf_s,fmy_erf_s,fmz_erf_s; + double fmx_s,fmy_s,fmz_s; + //double fmx_long,fmy_long,fmz_long; + + double **x = atom->x; + double **sp = atom->sp; + double **fm_long = atom->fm_long; + int *type = atom->type; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + pre1 = 2.0 * g_ewald / MY_PIS; + pre2 = 4.0 * pow(g_ewald,3.0) / MY_PIS; + pre3 = 8.0 * pow(g_ewald,5.0) / MY_PIS; + + // computation of the exchange interaction + // loop over neighbors of atom i + + i = ilist[ii]; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spi[3] = sp[i][3]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + itype = type[i]; + + //fmx_long = fmy_long = fmz_long = 0.0; + //fmx_erf_s = fmy_erf_s = fmz_erf_s = 0.0; + fmx_s = fmy_s = fmz_s = 0.0; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + spj[3] = sp[j][3]; + + bij[0] = bij[1] = bij[2] = bij[3] = 0.0; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + + local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + + if (rsq < local_cut2) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + r3inv = r2inv*rinv; + + r = sqrt(rsq); + //grij = g_ewald * r; + //expm2 = exp(-grij*grij); + //t = 1.0 / (1.0 + EWALD_P*grij); + + // evaluating erf instead of erfc + + //erf = 1.0 - t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; + + //bij[0] = erf * rinv; + //bij[1] = (bij[0] + pre1*expm2) * r2inv; + //bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; + //bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; + + //gigj = spi[3] * spj[3]; + //sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + //b1 = bij[1]; + //b2 = bij[2]; + + // evaluating short-range correction to the kspace part on [0,rc] + + //fmx_erf_s += mub2mu0hbinv * gigj * (b2 * sjdotr * rij[0] - b1 * spj[0]); + //fmy_erf_s += mub2mu0hbinv * gigj * (b2 * sjdotr * rij[1] - b1 * spj[1]); + //fmz_erf_s += mub2mu0hbinv * gigj * (b2 * sjdotr * rij[2] - b1 * spj[2]); + + // evaluating real dipolar interaction on [0,rc] + + sjdotrr3inv = 3.0 * sjdotr * r3inv; + fmx_s += mub2mu0hbinv * gigj * (sjdotrr3inv * rij[0] - sp[i][0]/r3inv); + fmy_s += mub2mu0hbinv * gigj * (sjdotrr3inv * rij[1] - sp[i][1]/r3inv); + fmz_s += mub2mu0hbinv * gigj * (sjdotrr3inv * rij[2] - sp[i][2]/r3inv); + + } + } + + // removing short-range erf function from kspace force + + //fmx_long = fm_long[i][0] - fmx_erf_s; + //fmy_long = fm_long[i][1] - fmy_erf_s; + //fmz_long = fm_long[i][2] - fmz_erf_s; + + // adding truncated kspace force and short-range full force + + //fmi[0] += fmx_s + fmx_long; + //fmi[1] += fmy_s + fmy_long; + //fmi[2] += fmz_s + fmz_long; + fmi[0] += (fmx_s + fm_long[i][0]); + fmi[1] += (fmy_s + fm_long[i][1]); + fmi[2] += (fmz_s + fm_long[i][2]); +} + +/* ---------------------------------------------------------------------- + compute dipolar interaction between spins i and j +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::compute_long(int i, int j, double rij[3], + double bij[4], double fmi[3], double spi[4], double spj[4]) +{ + double sjdotr; + double b1,b2,gigj; + + gigj = spi[3] * spj[3]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + b1 = bij[1]; + b2 = bij[2]; + + fmi[0] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[0] - b1 * spj[0]); + fmi[1] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[1] - b1 * spj[1]); + fmi[2] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[2] - b1 * spj[2]); +} + +/* ---------------------------------------------------------------------- + compute the mechanical force due to the dipolar interaction between + atom i and atom j +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::compute_long_mech(int i, int j, double rij[3], + double bij[4], double fi[3], double spi[3], double spj[3]) +{ + double sdots,sidotr,sjdotr,b2,b3; + double g1,g2,g1b2_g2b3,gigj; + + gigj = spi[3] * spj[3]; + sdots = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; + sidotr = spi[0]*rij[0] + spi[1]*rij[1] + spi[2]*rij[2]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + b2 = bij[2]; + b3 = bij[3]; + g1 = sdots; + g2 = -sidotr*sjdotr; + g1b2_g2b3 = g1*b2 + g2*b3; + + fi[0] += gigj * (rij[0] * g1b2_g2b3 + + b2 * (sjdotr*spi[0] + sidotr*spj[0])); + fi[1] += gigj * (rij[1] * g1b2_g2b3 + + b2 * (sjdotr*spi[1] + sidotr*spj[1])); + fi[2] += gigj * (rij[2] * g1b2_g2b3 + + b2 * (sjdotr*spi[2] + sidotr*spj[2])); +} + + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::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(cut_spin_long,n+1,n+1,"pair/spin/long:cut_spin_long"); + memory->create(cutsq,n+1,n+1,"pair/spin/long:cutsq"); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::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_spin_long[i][j],sizeof(int),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::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_spin_long[i][j],sizeof(int),1,fp); + } + MPI_Bcast(&cut_spin_long[i][j],1,MPI_INT,0,world); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::write_restart_settings(FILE *fp) +{ + fwrite(&cut_spin_long_global,sizeof(double),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairSpinLongQsymp::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_spin_long_global,sizeof(double),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&cut_spin_long_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); +} diff --git a/src/SPIN/pair_spin_long_qsymp.h b/src/SPIN/pair_spin_long_qsymp.h new file mode 100644 index 0000000000..ae8c5a3864 --- /dev/null +++ b/src/SPIN/pair_spin_long_qsymp.h @@ -0,0 +1,100 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + www.cs.sandia.gov/~sjplimp/lammps.html + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + 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(spin/long/qsymp,PairSpinLongQsymp) + +#else + +#ifndef LMP_PAIR_SPIN_LONG_QSYMP_H +#define LMP_PAIR_SPIN_LONG_QSYMP_H + +#include "pair_spin.h" + +namespace LAMMPS_NS { + +class PairSpinLongQsymp : public PairSpin { + public: + double cut_coul; + double **sigma; + + PairSpinLongQsymp(class LAMMPS *); + ~PairSpinLongQsymp(); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + void init_style(); + void *extract(const char *, int &); + + void compute(int, int); + void compute_single_pair(int, double *); + + void compute_long(int, int, double *, double *, double *, + double *, double *); + void compute_long_mech(int, int, double *, double *, double *, + double *, double *); + + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + + double cut_spin_long_global; // global long cutoff distance + + protected: + double hbar; // reduced Planck's constant + double mub; // Bohr's magneton + double mu_0; // vacuum permeability + double mub2mu0; // prefactor for mech force + double mub2mu0hbinv; // prefactor for mag force + + double **cut_spin_long; // cutoff distance long + + double g_ewald; + int ewald_order; + + int lattice_flag; // flag for mech force computation + class FixNVESpin *lockfixnvespin; // ptr for setups + + void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Incorrect args in pair_style command + +Self-explanatory. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair dipole/long requires atom attributes q, mu, torque + +The atom style defined does not have these attributes. + +E: Cannot (yet) use 'electron' units with dipoles + +This feature is not yet supported. + +E: Pair style requires a KSpace style + +No kspace style is defined. + +*/ -- GitLab From b9e33e631f81fac627b09fefcb0e285b1148668c Mon Sep 17 00:00:00 2001 From: "Stan Gerald Moore (stamoor)" Date: Sat, 15 Sep 2018 13:34:24 -0600 Subject: [PATCH 0045/1243] Fix bug in ewald_dipole forces --- src/KSPACE/ewald_dipole.cpp | 84 ++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index d7c3aad206..f5746ec31c 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -443,7 +443,7 @@ void EwaldDipole::compute(int eflag, int vflag) sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i]; exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; - partial = expim*sfacrl_all[k] - exprl*sfacim_all[k]; + partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); ek[i][0] += partial*eg[k][0]; ek[i][1] += partial*eg[k][1]; ek[i][2] += partial*eg[k][2]; @@ -465,14 +465,12 @@ void EwaldDipole::compute(int eflag, int vflag) const double muscale = qqrd2e * scale; for (i = 0; i < nlocal; i++) { - for (k = 0; k < kcount; k++) { - //f[i][0] += qscale * q[i]*ek[i][0]; - //f[i][1] += qscale * q[i]*ek[i][1]; - //if (slabflag != 2) f[i][2] += qscale * q[i]*ek[i][2]; - f[i][0] += muscale * muk[k][i] * ek[i][0]; - f[i][1] += muscale * muk[k][i] * ek[i][1]; - if (slabflag != 2) f[i][2] += muscale * muk[k][i] * ek[i][2]; - } + //f[i][0] += qscale * q[i]*ek[i][0]; + //f[i][1] += qscale * q[i]*ek[i][1]; + //if (slabflag != 2) f[i][2] += qscale * q[i]*ek[i][2]; + f[i][0] += muscale * ek[i][0]; + f[i][1] += muscale * ek[i][1]; + if (slabflag != 2) f[i][2] += muscale * ek[i][2]; } // sum global energy across Kspace vevs and add in volume-dependent term @@ -548,7 +546,7 @@ void EwaldDipole::eik_dot_r() // define first val. of cos and sin for (ic = 0; ic < 3; ic++) { - sqk = (unitk[ic] * unitk[ic]); + sqk = unitk[ic]*unitk[ic]; if (sqk <= gsqmx) { cstr1 = 0.0; sstr1 = 0.0; @@ -557,8 +555,8 @@ void EwaldDipole::eik_dot_r() sn[0][ic][i] = 0.0; cs[1][ic][i] = cos(unitk[ic]*x[i][ic]); sn[1][ic][i] = sin(unitk[ic]*x[i][ic]); - cs[-1][ic][i] = cs[1][0][i]; - sn[-1][ic][i] = -sn[1][0][i]; + cs[-1][ic][i] = cs[1][ic][i]; + sn[-1][ic][i] = -sn[1][ic][i]; muk[n][i] = (mu[i][ic]*unitk[ic]); cstr1 += muk[n][i]*cs[1][ic][i]; sstr1 += muk[n][i]*sn[1][ic][i]; @@ -583,7 +581,7 @@ void EwaldDipole::eik_dot_r() cs[m-1][ic][i]*sn[1][ic][i]; cs[-m][ic][i] = cs[m][ic][i]; sn[-m][ic][i] = -sn[m][ic][i]; - muk[n][i] = (mu[i][ic]*m*unitk[ic]); + muk[n][i] = (mu[i][ic]*m*unitk[ic]); cstr1 += muk[n][i]*cs[m][ic][i]; sstr1 += muk[n][i]*sn[m][ic][i]; } @@ -604,16 +602,16 @@ void EwaldDipole::eik_dot_r() cstr2 = 0.0; sstr2 = 0.0; for (i = 0; i < nlocal; i++) { - mux = mu[i][0]; - muy = mu[i][1]; + mux = mu[i][0]; + muy = mu[i][1]; - // dir 1: (k,l,0) - muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1]); + // dir 1: (k,l,0) + muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1]); cstr1 += muk[n][i]*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); sstr1 += muk[n][i]*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); - // dir 2: (k,-l,0) - muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1]); + // dir 2: (k,-l,0) + muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1]); cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); } @@ -636,16 +634,16 @@ void EwaldDipole::eik_dot_r() cstr2 = 0.0; sstr2 = 0.0; for (i = 0; i < nlocal; i++) { - muy = mu[i][1]; - muz = mu[i][2]; + muy = mu[i][1]; + muz = mu[i][2]; - // dir 1: (0,l,m) - muk[n][i] = (muy*l*unitk[1] + muz*m*unitk[2]); + // dir 1: (0,l,m) + muk[n][i] = (muy*l*unitk[1] + muz*m*unitk[2]); cstr1 += muk[n][i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); sstr1 += muk[n][i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); - // dir 2: (0,l,-m) - muk[n+1][i] = (muy*l*unitk[1] - muz*m*unitk[2]); + // dir 2: (0,l,-m) + muk[n+1][i] = (muy*l*unitk[1] - muz*m*unitk[2]); cstr2 += muk[n+1][i]*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); sstr2 += muk[n+1][i]*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); } @@ -656,7 +654,7 @@ void EwaldDipole::eik_dot_r() } } } - + // 1 = (k,0,m), 2 = (k,0,-m) for (k = 1; k <= kxmax; k++) { @@ -668,16 +666,16 @@ void EwaldDipole::eik_dot_r() cstr2 = 0.0; sstr2 = 0.0; for (i = 0; i < nlocal; i++) { - mux = mu[i][0]; - muz = mu[i][2]; + mux = mu[i][0]; + muz = mu[i][2]; - // dir 1: (k,0,m) - muk[n][i] = (mux*k*unitk[0] + muz*m*unitk[2]); + // dir 1: (k,0,m) + muk[n][i] = (mux*k*unitk[0] + muz*m*unitk[2]); cstr1 += muk[n][i]*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); sstr1 += muk[n][i]*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); - // dir 2: (k,0,-m) - muk[n+1][i] = (mux*k*unitk[0] - muz*m*unitk[2]); + // dir 2: (k,0,-m) + muk[n+1][i] = (mux*k*unitk[0] - muz*m*unitk[2]); cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); } @@ -706,33 +704,33 @@ void EwaldDipole::eik_dot_r() cstr4 = 0.0; sstr4 = 0.0; for (i = 0; i < nlocal; i++) { - mux = mu[i][0]; - muy = mu[i][1]; - muz = mu[i][2]; + mux = mu[i][0]; + muy = mu[i][1]; + muz = mu[i][2]; - // dir 1: (k,l,m) - muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1] + muz*m*unitk[2]); + // dir 1: (k,l,m) + muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1] + muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; cstr1 += muk[n][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); sstr1 += muk[n][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - // dir 2: (k,-l,m) - muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1] + muz*m*unitk[2]); + // dir 2: (k,-l,m) + muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1] + muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; cstr2 += muk[n+1][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); sstr2 += muk[n+1][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - // dir 3: (k,l,-m) - muk[n+2][i] = (mux*k*unitk[0] + muy*l*unitk[1] - muz*m*unitk[2]); + // dir 3: (k,l,-m) + muk[n+2][i] = (mux*k*unitk[0] + muy*l*unitk[1] - muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; cstr3 += muk[n+2][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); sstr3 += muk[n+2][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); - // dir 4: (k,-l,-m) - muk[n+3][i] = (mux*k*unitk[0] - muy*l*unitk[1] - muz*m*unitk[2]); + // dir 4: (k,-l,-m) + muk[n+3][i] = (mux*k*unitk[0] - muy*l*unitk[1] - muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; cstr4 += muk[n+3][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); -- GitLab From cce9fe4a34b39e81ec17e863bd9b42e3248edbb5 Mon Sep 17 00:00:00 2001 From: julient31 Date: Fri, 21 Sep 2018 09:55:41 -0600 Subject: [PATCH 0046/1243] Commit2 JT 092118 - created pair_spin_dipolar_cut - real-space short-range calc of the spin dipolar interaction - run and check valgrind ok --- .../SPIN/pppm_spin/in.spin.spin_dipolar_cut | 62 ++ src/SPIN/pair_spin_dipolar_cut.cpp | 528 ++++++++++++++++++ src/SPIN/pair_spin_dipolar_cut.h | 100 ++++ 3 files changed, 690 insertions(+) create mode 100644 examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut create mode 100644 src/SPIN/pair_spin_dipolar_cut.cpp create mode 100644 src/SPIN/pair_spin_dipolar_cut.h diff --git a/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut b/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut new file mode 100644 index 0000000000..838181e6d8 --- /dev/null +++ b/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut @@ -0,0 +1,62 @@ +# hcp cobalt in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary p p p + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice hcp 2.5071 +region box block 0.0 8.0 0.0 8.0 0.0 8.0 +create_box 1 box +create_atoms 1 box + +# setting mass, mag. moments, and interactions for hcp cobalt + +mass 1 58.93 + +#set group all spin/random 31 1.72 +set group all spin 1.72 0.0 0.0 1.0 +velocity all create 100 4928459 rot yes dist gaussian + +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 +pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/cut 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 +pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +pair_coeff * * spin/dipolar/cut long 8.0 +#pair_coeff * * spin/long long 8.0 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +#fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.0 21 +fix 3 all nve/spin lattice yes + +timestep 0.0001 + + +compute out_mag all compute/spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo_style custom step time v_magnorm v_emag temp etotal +thermo 10 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +#run 20000 +run 10 diff --git a/src/SPIN/pair_spin_dipolar_cut.cpp b/src/SPIN/pair_spin_dipolar_cut.cpp new file mode 100644 index 0000000000..f686d12926 --- /dev/null +++ b/src/SPIN/pair_spin_dipolar_cut.cpp @@ -0,0 +1,528 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + www.cs.sandia.gov/~sjplimp/lammps.html + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + 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: Julien Tranchida (SNL) + Aidan Thompson (SNL) + + Please cite the related publication: + Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). + Massively parallel symplectic algorithm for coupled magnetic spin dynamics + and molecular dynamics. Journal of Computational Physics. +------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +#include "pair_spin_dipolar_cut.h" +#include "atom.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "fix_nve_spin.h" +#include "force.h" +#include "kspace.h" +#include "math_const.h" +#include "memory.h" +#include "modify.h" +#include "error.h" +#include "update.h" + + +using namespace LAMMPS_NS; +using namespace MathConst; + +#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 + +/* ---------------------------------------------------------------------- */ + +PairSpinDipolarCut::PairSpinDipolarCut(LAMMPS *lmp) : PairSpin(lmp), +lockfixnvespin(NULL) +{ + single_enable = 0; + spinflag = 1; + respa_enable = 0; + no_virial_fdotr_compute = 1; + lattice_flag = 0; + + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + +} + +/* ---------------------------------------------------------------------- + free all arrays +------------------------------------------------------------------------- */ + +PairSpinDipolarCut::~PairSpinDipolarCut() +{ + if (allocated) { + memory->destroy(setflag); + memory->destroy(cut_spin_long); + memory->destroy(cutsq); + } +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::settings(int narg, char **arg) +{ + if (narg < 1 || narg > 2) + error->all(FLERR,"Incorrect args in pair_style command"); + + if (strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"Spin simulations require metal unit style"); + + cut_spin_long_global = force->numeric(FLERR,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_spin_long[i][j] = cut_spin_long_global; + } + } + } + } + +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::coeff(int narg, char **arg) +{ + if (!allocated) allocate(); + + // check if args correct + + if (strcmp(arg[2],"long") != 0) + error->all(FLERR,"Incorrect args in pair_style command"); + if (narg < 1 || narg > 4) + error->all(FLERR,"Incorrect args in pair_style command"); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double spin_long_cut_one = force->numeric(FLERR,arg[3]); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + setflag[i][j] = 1; + cut_spin_long[i][j] = spin_long_cut_one; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::init_style() +{ + if (!atom->sp_flag) + error->all(FLERR,"Pair spin requires atom/spin style"); + + // need a full neighbor list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->half = 0; + neighbor->requests[irequest]->full = 1; + + // checking if nve/spin is a listed fix + + int ifix = 0; + while (ifix < modify->nfix) { + if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + ifix++; + } + if (ifix == modify->nfix) + error->all(FLERR,"pair/spin style requires nve/spin"); + + // get the lattice_flag from nve/spin + + for (int i = 0; i < modify->nfix; i++) { + if (strcmp(modify->fix[i]->style,"nve/spin") == 0) { + lockfixnvespin = (FixNVESpin *) modify->fix[i]; + lattice_flag = lockfixnvespin->lattice_flag; + } + } + +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairSpinDipolarCut::init_one(int i, int j) +{ + if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + + cut_spin_long[j][i] = cut_spin_long[i][j]; + + return cut_spin_long_global; +} + +/* ---------------------------------------------------------------------- + extract the larger cutoff if "cut" or "cut_coul" +------------------------------------------------------------------------- */ + +void *PairSpinDipolarCut::extract(const char *str, int &dim) +{ + if (strcmp(str,"cut") == 0) { + dim = 0; + return (void *) &cut_spin_long_global; + } else if (strcmp(str,"cut_coul") == 0) { + dim = 0; + return (void *) &cut_spin_long_global; + } else if (strcmp(str,"ewald_order") == 0) { + ewald_order = 0; + ewald_order |= 1<<1; + ewald_order |= 1<<3; + dim = 0; + return (void *) &ewald_order; + } else if (strcmp(str,"ewald_mix") == 0) { + dim = 0; + return (void *) &mix_flag; + } + return NULL; +} + +/* ---------------------------------------------------------------------- */ + +void PairSpinDipolarCut::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double rinv,r2inv,r3inv,rsq; + double evdwl,ecoul; + double xi[3],rij[3]; + double spi[4],spj[4],fi[3],fmi[3]; + double local_cut2; + int *ilist,*jlist,*numneigh,**firstneigh; + + evdwl = ecoul = 0.0; + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + double **x = atom->x; + double **f = atom->f; + double **fm = atom->fm; + double **sp = atom->sp; + 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; + + // computation of the exchange interaction + // loop over atoms and their neighbors + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spi[3] = sp[i][3]; + itype = type[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + spj[3] = sp[j][3]; + + fi[0] = fi[1] = fi[2] = 0.0; + fmi[0] = fmi[1] = fmi[2] = 0.0; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + + local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + + if (rsq < local_cut2) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + r3inv = r2inv*rinv; + + compute_dipolar(i,j,rij,fmi,spi,spj,r3inv); + if (lattice_flag) compute_dipolar_mech(i,j,rij,fmi,spi,spj,r2inv); + } + + // force accumulation + + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + fm[i][0] += fmi[0]; + fm[i][1] += fmi[1]; + fm[i][2] += fmi[2]; + + if (newton_pair || j < nlocal) { + f[j][0] -= fi[0]; + f[j][1] -= fi[1]; + f[j][2] -= fi[2]; + } + + if (eflag) { + if (rsq <= local_cut2) { + evdwl -= spi[0]*fmi[0] + spi[1]*fmi[1] + + spi[2]*fmi[2]; + evdwl *= hbar; + } + } else evdwl = 0.0; + + + if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, + evdwl,ecoul,fi[0],fi[1],fi[2],rij[0],rij[1],rij[2]); + + } + } +} + +/* ---------------------------------------------------------------------- + update the pair interaction fmi acting on the spin ii + adding 1/r (for r in [0,rc]) contribution to the pair + removing erf(r)/r (for r in [0,rc]) from the kspace force +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::compute_single_pair(int ii, double fmi[3]) +{ + int i,j,jj,jnum,itype,jtype; + double rsq,rinv,r2inv,r3inv; + double xi[3],rij[3]; + double spi[4],spj[4]; + double local_cut2; + int *ilist,*jlist,*numneigh,**firstneigh; + + double **x = atom->x; + double **sp = atom->sp; + int *type = atom->type; + + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + + // computation of the exchange interaction + // loop over neighbors of atom i + + i = ilist[ii]; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spi[3] = sp[i][3]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + itype = type[i]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + spj[3] = sp[j][3]; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + + local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + + if (rsq < local_cut2) { + r2inv = 1.0/rsq; + rinv = sqrt(r2inv); + r3inv = r2inv*rinv; + + // compute dipolar interaction + + compute_dipolar(i,j,rij,fmi,spi,spj,r3inv); + } + } + + //fmi[0] *= mub2mu0hbinv; + //fmi[1] *= mub2mu0hbinv; + //fmi[2] *= mub2mu0hbinv; +} + +/* ---------------------------------------------------------------------- + compute dipolar interaction between spins i and j +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::compute_dipolar(int i, int j, double rij[3], + double fmi[3], double spi[4], double spj[4], double r3inv) +{ + double sjdotr; + double gigjri2,pre; + + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + gigjri2 = (spi[3] * spj[3])*r3inv; + pre = mub2mu0hbinv * gigjri2 / 4.0 / MY_PI; + + fmi[0] += pre * gigjri2 * (3.0 * sjdotr *rij[0] - spj[0]); + fmi[1] += pre * gigjri2 * (3.0 * sjdotr *rij[1] - spj[1]); + fmi[2] += pre * gigjri2 * (3.0 * sjdotr *rij[2] - spj[2]); +} + +/* ---------------------------------------------------------------------- + compute the mechanical force due to the dipolar interaction between + atom i and atom j +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::compute_dipolar_mech(int i, int j, double rij[3], + double fi[3], double spi[3], double spj[3], double r2inv) +{ + double sdots,sidotr,sjdotr,b2,b3; + double gigjri4,bij,pre; + + gigjri4 = (spi[3] * spj[3])/r2inv/r2inv; + sdots = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; + sidotr = spi[0]*rij[0] + spi[1]*rij[1] + spi[2]*rij[2]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + + bij = sdots - 5.0 * sidotr*sjdotr; + pre = mub2mu0 * bij / 4.0 / MY_PI; + fi[0] += pre * (rij[0] * bij + (sjdotr*spi[0] + sidotr*spj[0])); + fi[1] += pre * (rij[1] * bij + (sjdotr*spi[1] + sidotr*spj[1])); + fi[2] += pre * (rij[2] * bij + (sjdotr*spi[2] + sidotr*spj[2])); +} + + +/* ---------------------------------------------------------------------- + allocate all arrays +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::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(cut_spin_long,n+1,n+1,"pair/spin/long:cut_spin_long"); + memory->create(cutsq,n+1,n+1,"pair/spin/long:cutsq"); +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::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_spin_long[i][j],sizeof(int),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::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_spin_long[i][j],sizeof(int),1,fp); + } + MPI_Bcast(&cut_spin_long[i][j],1,MPI_INT,0,world); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::write_restart_settings(FILE *fp) +{ + fwrite(&cut_spin_long_global,sizeof(double),1,fp); + fwrite(&mix_flag,sizeof(int),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairSpinDipolarCut::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_spin_long_global,sizeof(double),1,fp); + fread(&mix_flag,sizeof(int),1,fp); + } + MPI_Bcast(&cut_spin_long_global,1,MPI_DOUBLE,0,world); + MPI_Bcast(&mix_flag,1,MPI_INT,0,world); +} diff --git a/src/SPIN/pair_spin_dipolar_cut.h b/src/SPIN/pair_spin_dipolar_cut.h new file mode 100644 index 0000000000..ac17ac2120 --- /dev/null +++ b/src/SPIN/pair_spin_dipolar_cut.h @@ -0,0 +1,100 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + www.cs.sandia.gov/~sjplimp/lammps.html + Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories + + 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(spin/dipolar/cut,PairSpinDipolarCut) + +#else + +#ifndef LMP_PAIR_SPIN_DIPOLAR_CUT_H +#define LMP_PAIR_SPIN_DIPOLAR_CUT_H + +#include "pair_spin.h" + +namespace LAMMPS_NS { + +class PairSpinDipolarCut : public PairSpin { + public: + double cut_coul; + double **sigma; + + PairSpinDipolarCut(class LAMMPS *); + ~PairSpinDipolarCut(); + void settings(int, char **); + void coeff(int, char **); + double init_one(int, int); + void init_style(); + void *extract(const char *, int &); + + void compute(int, int); + void compute_single_pair(int, double *); + + void compute_dipolar(int, int, double *, double *, double *, + double *, double); + void compute_dipolar_mech(int, int, double *, double *, double *, + double *, double); + + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + + double cut_spin_long_global; // global long cutoff distance + + protected: + double hbar; // reduced Planck's constant + double mub; // Bohr's magneton + double mu_0; // vacuum permeability + double mub2mu0; // prefactor for mech force + double mub2mu0hbinv; // prefactor for mag force + + double **cut_spin_long; // cutoff distance long + + double g_ewald; + int ewald_order; + + int lattice_flag; // flag for mech force computation + class FixNVESpin *lockfixnvespin; // ptr for setups + + void allocate(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Incorrect args in pair_style command + +Self-explanatory. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair dipole/long requires atom attributes q, mu, torque + +The atom style defined does not have these attributes. + +E: Cannot (yet) use 'electron' units with dipoles + +This feature is not yet supported. + +E: Pair style requires a KSpace style + +No kspace style is defined. + +*/ -- GitLab From 53a779067ee59366eb96fddfd2c37e0471c0c4bf Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 24 Sep 2018 10:59:17 -0600 Subject: [PATCH 0047/1243] Commit JT 092418 - ewald_dipole_spin added - accuracy problem (with eval of gewald and Newton solver) --- examples/SPIN/pppm_spin/in.spin.ewald_spin | 67 ++ src/KSPACE/ewald_dipole.cpp | 6 +- src/KSPACE/ewald_dipole.h | 3 - src/KSPACE/ewald_dipole_spin.cpp | 895 +++++++++++++++++++++ src/KSPACE/ewald_dipole_spin.h | 102 +++ 5 files changed, 1067 insertions(+), 6 deletions(-) create mode 100644 examples/SPIN/pppm_spin/in.spin.ewald_spin create mode 100644 src/KSPACE/ewald_dipole_spin.cpp create mode 100644 src/KSPACE/ewald_dipole_spin.h diff --git a/examples/SPIN/pppm_spin/in.spin.ewald_spin b/examples/SPIN/pppm_spin/in.spin.ewald_spin new file mode 100644 index 0000000000..d9ca46b27a --- /dev/null +++ b/examples/SPIN/pppm_spin/in.spin.ewald_spin @@ -0,0 +1,67 @@ +# hcp cobalt in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary p p p + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice hcp 2.5071 +region box block 0.0 8.0 0.0 8.0 0.0 8.0 +create_box 1 box +create_atoms 1 box + +# setting mass, mag. moments, and interactions for hcp cobalt + +mass 1 58.93 + +#set group all spin/random 31 1.72 +set group all spin 1.72 0.0 0.0 1.0 +velocity all create 100 4928459 rot yes dist gaussian + +pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long/qsymp 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 +pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +#pair_coeff * * spin/long/qsymp long 8.0 +pair_coeff * * spin/long long 8.0 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +#kspace_style pppm/dipole/spin 1.0e-4 +#kspace_style ewald/dipole/spin 1.0e-4 +kspace_style ewald/dipole/spin 1.0e-2 +kspace_modify mesh 32 32 32 + +#fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.0 21 +fix 3 all nve/spin lattice yes + +timestep 0.0001 + + +compute out_mag all compute/spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo_style custom step time v_magnorm v_emag temp etotal +thermo 10 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +#run 20000 +run 1 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index 372825d587..42d850dcc2 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -161,6 +161,8 @@ void EwaldDipole::init() // zprd used rather than zprd_slab if (!gewaldflag) { + if (accuracy <= 0.0) + error->all(FLERR,"KSpace accuracy must be > 0"); double g_ewald_new = NewtonSolve(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); if (g_ewald_new > 0.0) g_ewald = g_ewald_new; @@ -778,14 +780,12 @@ void EwaldDipole::slabcorr() { // compute local contribution to global dipole moment - //double *q = atom->q; double **x = atom->x; double zprd = domain->zprd; int nlocal = atom->nlocal; double dipole = 0.0; double **mu = atom->mu; - //for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2]; for (int i = 0; i < nlocal; i++) dipole += mu[i][2]; // sum local contributions to get global dipole moment @@ -856,7 +856,7 @@ void EwaldDipole::musum_musq() } if (mu2 == 0 && comm->me == 0) - error->all(FLERR,"Using kspace solver PPPMDipole on system with no dipoles"); + error->all(FLERR,"Using kspace solver EwaldDipole on system with no dipoles"); } /* ---------------------------------------------------------------------- diff --git a/src/KSPACE/ewald_dipole.h b/src/KSPACE/ewald_dipole.h index f937b2a2c2..0a57f86d00 100644 --- a/src/KSPACE/ewald_dipole.h +++ b/src/KSPACE/ewald_dipole.h @@ -38,9 +38,6 @@ class EwaldDipole : public Ewald { double **tk; // field for torque double **vc; // virial per k - //virtual void allocate(); - //void deallocate(); - void musum_musq(); double rms_dipole(int, double, bigint); virtual void eik_dot_r(); diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp new file mode 100644 index 0000000000..5522b18e03 --- /dev/null +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -0,0 +1,895 @@ +/* ---------------------------------------------------------------------- + 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: Julien Tranchida (SNL) + Stan Moore (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include "ewald_dipole_spin.h" +#include "atom.h" +#include "comm.h" +#include "force.h" +#include "pair.h" +#include "domain.h" +#include "math_const.h" +#include "math_special.h" +#include "memory.h" +#include "error.h" +#include "update.h" + +#include "math_const.h" +#include "math_special.h" + +using namespace LAMMPS_NS; +using namespace MathConst; +using namespace MathSpecial; + +#define SMALL 0.00001 + +/* ---------------------------------------------------------------------- */ + +EwaldDipoleSpin::EwaldDipoleSpin(LAMMPS *lmp, int narg, char **arg) : + EwaldDipole(lmp, narg, arg) +{ + dipoleflag = 0; + spinflag = 1; + + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0; // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz +} + +/* ---------------------------------------------------------------------- + free all memory +------------------------------------------------------------------------- */ + +EwaldDipoleSpin::~EwaldDipoleSpin() +{ + //memory->destroy(muk); + //memory->destroy(tk); + //memory->destroy(vc); +} + +/* ---------------------------------------------------------------------- + called once before run +------------------------------------------------------------------------- */ + +void EwaldDipoleSpin::init() +{ + if (comm->me == 0) { + if (screen) fprintf(screen,"EwaldDipoleSpin initialization ...\n"); + if (logfile) fprintf(logfile,"EwaldDipoleSpin initialization ...\n"); + } + + // error check + + //dipoleflag = atom->mu?1:0; + spinflag = atom->sp?1:0; + //qsum_qsq(0); // q[i] might not be declared ? + + //if (dipoleflag && q2) + // error->all(FLERR,"Cannot (yet) use charges with Kspace style EwaldDipoleSpin"); + + triclinic_check(); + + // no triclinic ewald spin (yet) + + triclinic = domain->triclinic; + if (triclinic) + error->all(FLERR,"Cannot (yet) use EwaldDipoleSpin with triclinic box"); + + if (domain->dimension == 2) + error->all(FLERR,"Cannot use EwaldDipoleSpin with 2d simulation"); + + if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); +//if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); + + if ((spinflag && strcmp(update->unit_style,"metal")) != 0) + error->all(FLERR,"'metal' units have to be used with spins"); + + if (slabflag == 0 && domain->nonperiodic > 0) + error->all(FLERR,"Cannot use nonperiodic boundaries with EwaldDipoleSpin"); + if (slabflag) { + if (domain->xperiodic != 1 || domain->yperiodic != 1 || + domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1) + error->all(FLERR,"Incorrect boundaries with slab EwaldDipoleSpin"); + } + + // extract short-range Coulombic cutoff from pair style + + pair_check(); + + int itmp; + double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp); + if (p_cutoff == NULL) + error->all(FLERR,"KSpace style is incompatible with Pair style"); + double cutoff = *p_cutoff; + + // kspace TIP4P not yet supported + // qdist = offset only for TIP4P fictitious charge + + //qdist = 0.0; + if (tip4pflag) + error->all(FLERR,"Cannot yet use TIP4P with EwaldDipoleSpin"); + + // compute musum & musqsum and warn if no spin + + scale = 1.0; + qqrd2e = force->qqrd2e; + //musum_musq(); + spsum_musq(); + natoms_original = atom->natoms; + + // set accuracy (force units) from accuracy_relative or accuracy_absolute + + if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute; + else accuracy = accuracy_relative * two_charge_force; + + // setup K-space resolution + + bigint natoms = atom->natoms; + + // use xprd,yprd,zprd even if triclinic so grid size is the same + // adjust z dimension for 2d slab EwaldDipoleSpin + // 3d EwaldDipoleSpin just uses zprd since slab_volfactor = 1.0 + + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + double zprd_slab = zprd*slab_volfactor; + + // make initial g_ewald estimate + // based on desired accuracy and real space cutoff + // fluid-occupied volume used to estimate real-space error + // zprd used rather than zprd_slab + + if (!gewaldflag) { + if (accuracy <= 0.0) + error->all(FLERR,"KSpace accuracy must be > 0"); + double g_ewald_new = + NewtonSolve(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); + if (g_ewald_new > 0.0) g_ewald = g_ewald_new; + else error->warning(FLERR,"Ewald/disp Newton solver failed, " + "using old method to estimate g_ewald"); + } + + // setup EwaldDipoleSpin coefficients so can print stats + + setup(); + + // final RMS accuracy + + double lprx = rms(kxmax_orig,xprd,natoms,q2); + double lpry = rms(kymax_orig,yprd,natoms,q2); + double lprz = rms(kzmax_orig,zprd_slab,natoms,q2); + double lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0); + double q2_over_sqrt = q2 / sqrt(natoms*cutoff*xprd*yprd*zprd_slab); + double spr = 2.0 *q2_over_sqrt * exp(-g_ewald*g_ewald*cutoff*cutoff); + double tpr = estimate_table_accuracy(q2_over_sqrt,spr); + double estimated_accuracy = sqrt(lpr*lpr + spr*spr + tpr*tpr); + + // stats + + if (comm->me == 0) { + if (screen) { + fprintf(screen," G vector (1/distance) = %g\n",g_ewald); + fprintf(screen," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(screen," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(screen," KSpace vectors: actual max1d max3d = %d %d %d\n", + kcount,kmax,kmax3d); + fprintf(screen," kxmax kymax kzmax = %d %d %d\n", + kxmax,kymax,kzmax); + } + if (logfile) { + fprintf(logfile," G vector (1/distance) = %g\n",g_ewald); + fprintf(logfile," estimated absolute RMS force accuracy = %g\n", + estimated_accuracy); + fprintf(logfile," estimated relative force accuracy = %g\n", + estimated_accuracy/two_charge_force); + fprintf(logfile," KSpace vectors: actual max1d max3d = %d %d %d\n", + kcount,kmax,kmax3d); + fprintf(logfile," kxmax kymax kzmax = %d %d %d\n", + kxmax,kymax,kzmax); + } + } +} + +/* ---------------------------------------------------------------------- + adjust EwaldDipoleSpin coeffs, called initially and whenever volume has changed +------------------------------------------------------------------------- */ + +void EwaldDipoleSpin::setup() +{ + // volume-dependent factors + + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + + // adjustment of z dimension for 2d slab EwaldDipoleSpin + // 3d EwaldDipoleSpin just uses zprd since slab_volfactor = 1.0 + + double zprd_slab = zprd*slab_volfactor; + volume = xprd * yprd * zprd_slab; + + unitk[0] = 2.0*MY_PI/xprd; + unitk[1] = 2.0*MY_PI/yprd; + unitk[2] = 2.0*MY_PI/zprd_slab; + + int kmax_old = kmax; + + if (kewaldflag == 0) { + + // determine kmax + // function of current box size, accuracy, G_ewald (short-range cutoff) + + bigint natoms = atom->natoms; + double err; + kxmax = 1; + kymax = 1; + kzmax = 1; + + // set kmax in 3 directions to respect accuracy + + err = rms_dipole(kxmax,xprd,natoms); + while (err > accuracy) { + kxmax++; + err = rms_dipole(kxmax,xprd,natoms); + } + + err = rms_dipole(kymax,yprd,natoms); + while (err > accuracy) { + kymax++; + err = rms_dipole(kymax,yprd,natoms); + } + + err = rms_dipole(kzmax,zprd,natoms); + while (err > accuracy) { + kzmax++; + err = rms_dipole(kzmax,zprd,natoms); + } + + kmax = MAX(kxmax,kymax); + kmax = MAX(kmax,kzmax); + kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; + + double gsqxmx = unitk[0]*unitk[0]*kxmax*kxmax; + double gsqymx = unitk[1]*unitk[1]*kymax*kymax; + double gsqzmx = unitk[2]*unitk[2]*kzmax*kzmax; + gsqmx = MAX(gsqxmx,gsqymx); + gsqmx = MAX(gsqmx,gsqzmx); + + kxmax_orig = kxmax; + kymax_orig = kymax; + kzmax_orig = kzmax; + + } else { + + kxmax = kx_ewald; + kymax = ky_ewald; + kzmax = kz_ewald; + + kxmax_orig = kxmax; + kymax_orig = kymax; + kzmax_orig = kzmax; + + kmax = MAX(kxmax,kymax); + kmax = MAX(kmax,kzmax); + kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax; + + double gsqxmx = unitk[0]*unitk[0]*kxmax*kxmax; + double gsqymx = unitk[1]*unitk[1]*kymax*kymax; + double gsqzmx = unitk[2]*unitk[2]*kzmax*kzmax; + gsqmx = MAX(gsqxmx,gsqymx); + gsqmx = MAX(gsqmx,gsqzmx); + } + + gsqmx *= 1.00001; + + // if size has grown, reallocate k-dependent and nlocal-dependent arrays + + if (kmax > kmax_old) { + deallocate(); + allocate(); + group_allocate_flag = 0; + + memory->destroy(ek); + memory->destroy(tk); + memory->destroy(vc); + memory->destroy3d_offset(cs,-kmax_created); + memory->destroy3d_offset(sn,-kmax_created); + memory->destroy(muk); + nmax = atom->nmax; + memory->create(ek,nmax,3,"ewald_dipole_spin:ek"); + memory->create(tk,nmax,3,"ewald_dipole_spin:tk"); + memory->create(vc,kmax3d,6,"ewald_dipole_spin:tk"); + memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald_dipole_spin:cs"); + memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald_dipole_spin:sn"); + memory->create(muk,kmax3d,nmax,"ewald_dipole_spin:muk"); + kmax_created = kmax; + } + + // pre-compute EwaldDipoleSpin coefficients + + coeffs(); +} + +/* ---------------------------------------------------------------------- + compute dipole RMS accuracy for a dimension +------------------------------------------------------------------------- */ + +//double EwaldDipoleSpin::rms_dipole(int km, double prd, bigint natoms) +//{ +// if (natoms == 0) natoms = 1; // avoid division by zero +// +// // error from eq.(46), Wang et al., JCP 115, 6351 (2001) +// +// double value = 8*MY_PI*mu2*g_ewald/volume * +// sqrt(2*MY_PI*km*km*km/(15.0*natoms)) * +// exp(-MY_PI*MY_PI*km*km/(g_ewald*g_ewald*prd*prd)); +// +// return value; +//} + +/* ---------------------------------------------------------------------- + compute the EwaldDipoleSpin long-range force, energy, virial +------------------------------------------------------------------------- */ + +void EwaldDipoleSpin::compute(int eflag, int vflag) +{ + int i,j,k; + const double g3 = g_ewald*g_ewald*g_ewald; + double spx, spy, spz; + + // set energy/virial flags + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = evflag_atom = eflag_global = vflag_global = + eflag_atom = vflag_atom = 0; + + // if atom count has changed, update qsum and qsqsum + + if (atom->natoms != natoms_original) { + //musum_musq(); + spsum_musq(); + natoms_original = atom->natoms; + } + + // return if there are no charges + + if (musqsum == 0.0) return; + + // extend size of per-atom arrays if necessary + + if (atom->nmax > nmax) { + memory->destroy(ek); + memory->destroy(tk); + memory->destroy(vc); + memory->destroy3d_offset(cs,-kmax_created); + memory->destroy3d_offset(sn,-kmax_created); + memory->destroy(muk); + nmax = atom->nmax; + memory->create(ek,nmax,3,"ewald_dipole_spin:ek"); + memory->create(tk,nmax,3,"ewald_dipole_spin:tk"); + memory->create(vc,kmax3d,6,"ewald_dipole_spin:tk"); + memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald_dipole_spin:cs"); + memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald_dipole_spin:sn"); + memory->create(muk,kmax3d,nmax,"ewald_dipole_spin:muk"); + kmax_created = kmax; + } + + // partial structure factors on each processor + // total structure factor by summing over procs + + eik_dot_r(); + + MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(sfacim,sfacim_all,kcount,MPI_DOUBLE,MPI_SUM,world); + + // K-space portion of electric field + // double loop over K-vectors and local atoms + // perform per-atom calculations if needed + + double **f = atom->f; + double **fm_long = atom->fm_long; + double **t = atom->torque; + //double **mu = atom->mu; + double **sp = atom->sp; + int nlocal = atom->nlocal; + + int kx,ky,kz; + double cypz,sypz,exprl,expim; + double partial,partial2,partial_peratom; + double vcik[6]; + + for (i = 0; i < nlocal; i++) { + ek[i][0] = ek[i][1] = ek[i][2] = 0.0; + tk[i][0] = tk[i][1] = tk[i][2] = 0.0; + } + + for (k = 0; k < kcount; k++) { + kx = kxvecs[k]; + ky = kyvecs[k]; + kz = kzvecs[k]; + for (j = 0; j<6; j++) vc[k][j] = 0.0; + + for (i = 0; i < nlocal; i++) { + + vcik[0] = vcik[1] = vcik[2] = 0.0; + vcik[3] = vcik[4] = vcik[5] = 0.0; + + // calculating re and im of exp(i*k*ri) + + cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i]; + sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i]; + exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; + expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; + + // taking im of struct_fact x exp(i*k*ri) (for force calc.) + + partial = (muk[k][i])*(expim*sfacrl_all[k] + exprl*sfacim_all[k]); + ek[i][0] += partial*eg[k][0]; + ek[i][1] += partial*eg[k][1]; + ek[i][2] += partial*eg[k][2]; + + // compute field for torque calculation + + partial2 = exprl*sfacrl_all[k] - expim*sfacim_all[k]; + tk[i][0] += partial2*eg[k][0]; + tk[i][1] += partial2*eg[k][1]; + tk[i][2] += partial2*eg[k][2]; + + // total and per-atom virial correction + + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + + vc[k][0] += vcik[0] = partial2 * spx * kx; + vc[k][1] += vcik[1] = partial2 * spy * ky; + vc[k][2] += vcik[2] = partial2 * spz * kz; + vc[k][3] += vcik[3] = partial2 * spx * ky; + vc[k][4] += vcik[4] = partial2 * spx * kz; + vc[k][5] += vcik[5] = partial2 * spy * kz; + + // taking re-part of struct_fact x exp(i*k*ri) + // (for per-atom energy and virial calc.) + + if (evflag_atom) { + partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; + if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; + if (vflag_atom) + for (j = 0; j < 6; j++) + vatom[i][j] += ug[k] * (vg[k][j]*partial_peratom - vcik[j]); + } + } + } + + // force and mag. precession vectors calculation + + const double spscale = mub2mu0 * scale; + const double spscale2 = mub2mu0hbinv * scale; + //const double muscale = qqrd2e * scale; + + for (i = 0; i < nlocal; i++) { + f[i][0] += spscale * ek[i][0]; + f[i][1] += spscale * ek[i][1]; + if (slabflag != 2) f[i][2] += spscale * ek[i][2]; + fm_long[i][0] += spscale2 * tk[i][0]; + fm_long[i][1] += spscale2 * tk[i][1]; + if (slabflag != 2) fm_long[i][2] += spscale2 * tk[i][3]; + } + + // sum global energy across Kspace vevs and add in volume-dependent term + // taking the re-part of struct_fact_i x struct_fact_j + // substracting self energy and scaling + + if (eflag_global) { + for (k = 0; k < kcount; k++) { + energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] + + sfacim_all[k]*sfacim_all[k]); + } + energy -= musqsum*2.0*g3/3.0/MY_PIS; + energy *= spscale; + } + + // global virial + + if (vflag_global) { + double uk, vk; + for (k = 0; k < kcount; k++) { + uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); + for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j] + ug[k]*vc[k][j]; + } + for (j = 0; j < 6; j++) virial[j] *= spscale; + } + + // per-atom energy/virial + // energy includes self-energy correction + + if (evflag_atom) { + if (eflag_atom) { + for (i = 0; i < nlocal; i++) { + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + eatom[i] -= (spx*spx + spy*spy + spz*spz) + *2.0*g3/3.0/MY_PIS; + eatom[i] *= spscale; + } + } + + if (vflag_atom) + for (i = 0; i < nlocal; i++) + for (j = 0; j < 6; j++) vatom[i][j] *= spscale; + } + + // 2d slab correction + + if (slabflag == 1) slabcorr(); +} + +/* ---------------------------------------------------------------------- + compute the +------------------------------------------------------------------------- */ + +void EwaldDipoleSpin::eik_dot_r() +{ + int i,k,l,m,n,ic; + double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4; + double sqk,clpm,slpm; + //double mux, muy, muz; + double spx, spy, spz, spi; + + double **x = atom->x; + //double **mu = atom->mu; + double **sp = atom->sp; + int nlocal = atom->nlocal; + + n = 0; + spi = spx = spy = spz = 0.0; + + // loop on different k-directions + // loop on n kpoints and nlocal atoms + // store (n x nlocal) tab. of values of (mu_i dot k) + // store n values of sum_j[ (mu_j dot k) exp(-k dot r_j) ] + + // (k,0,0), (0,l,0), (0,0,m) + + // loop 1: k=1, l=1, m=1 + // define first val. of cos and sin + + for (ic = 0; ic < 3; ic++) { + sqk = unitk[ic]*unitk[ic]; + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + for (i = 0; i < nlocal; i++) { + cs[0][ic][i] = 1.0; + sn[0][ic][i] = 0.0; + cs[1][ic][i] = cos(unitk[ic]*x[i][ic]); + sn[1][ic][i] = sin(unitk[ic]*x[i][ic]); + cs[-1][ic][i] = cs[1][ic][i]; + sn[-1][ic][i] = -sn[1][ic][i]; + spi = sp[i][ic]*sp[i][3]; + //muk[n][i] = (mu[i][ic]*unitk[ic]); + muk[n][i] = (spi*unitk[ic]); + cstr1 += muk[n][i]*cs[1][ic][i]; + sstr1 += muk[n][i]*sn[1][ic][i]; + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + } + } + + // loop 2: k>1, l>1, m>1 + + for (m = 2; m <= kmax; m++) { + for (ic = 0; ic < 3; ic++) { + sqk = m*unitk[ic] * m*unitk[ic]; + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + for (i = 0; i < nlocal; i++) { + cs[m][ic][i] = cs[m-1][ic][i]*cs[1][ic][i] - + sn[m-1][ic][i]*sn[1][ic][i]; + sn[m][ic][i] = sn[m-1][ic][i]*cs[1][ic][i] + + cs[m-1][ic][i]*sn[1][ic][i]; + cs[-m][ic][i] = cs[m][ic][i]; + sn[-m][ic][i] = -sn[m][ic][i]; + spi = sp[i][ic]*sp[i][3]; + muk[n][i] = (spi*m*unitk[ic]); + //muk[n][i] = (mu[i][ic]*m*unitk[ic]); + cstr1 += muk[n][i]*cs[m][ic][i]; + sstr1 += muk[n][i]*sn[m][ic][i]; + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + } + } + } + + // 1 = (k,l,0), 2 = (k,-l,0) + + for (k = 1; k <= kxmax; k++) { + for (l = 1; l <= kymax; l++) { + sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + for (i = 0; i < nlocal; i++) { + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + //mux = mu[i][0]; + //muy = mu[i][1]; + + // dir 1: (k,l,0) + muk[n][i] = (spx*k*unitk[0] + spy*l*unitk[1]); + cstr1 += muk[n][i]*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); + sstr1 += muk[n][i]*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); + + // dir 2: (k,-l,0) + muk[n+1][i] = (spx*k*unitk[0] - spy*l*unitk[1]); + cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); + sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + } + } + } + + // 1 = (0,l,m), 2 = (0,l,-m) + + for (l = 1; l <= kymax; l++) { + for (m = 1; m <= kzmax; m++) { + sqk = (l*unitk[1] * l*unitk[1]) + (m*unitk[2] * m*unitk[2]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + for (i = 0; i < nlocal; i++) { + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + //muy = mu[i][1]; + //muz = mu[i][2]; + + // dir 1: (0,l,m) + muk[n][i] = (spy*l*unitk[1] + spz*m*unitk[2]); + cstr1 += muk[n][i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); + sstr1 += muk[n][i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); + + // dir 2: (0,l,-m) + muk[n+1][i] = (spy*l*unitk[1] - spz*m*unitk[2]); + cstr2 += muk[n+1][i]*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); + sstr2 += muk[n+1][i]*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + } + } + } + + // 1 = (k,0,m), 2 = (k,0,-m) + + for (k = 1; k <= kxmax; k++) { + for (m = 1; m <= kzmax; m++) { + sqk = (k*unitk[0] * k*unitk[0]) + (m*unitk[2] * m*unitk[2]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + for (i = 0; i < nlocal; i++) { + //mux = mu[i][0]; + //muz = mu[i][2]; + spx = sp[i][0]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + + // dir 1: (k,0,m) + muk[n][i] = (spx*k*unitk[0] + spz*m*unitk[2]); + cstr1 += muk[n][i]*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); + sstr1 += muk[n][i]*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); + + // dir 2: (k,0,-m) + muk[n+1][i] = (spx*k*unitk[0] - spz*m*unitk[2]); + cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); + sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + } + } + } + + // 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m) + + for (k = 1; k <= kxmax; k++) { + for (l = 1; l <= kymax; l++) { + for (m = 1; m <= kzmax; m++) { + sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]) + + (m*unitk[2] * m*unitk[2]); + if (sqk <= gsqmx) { + cstr1 = 0.0; + sstr1 = 0.0; + cstr2 = 0.0; + sstr2 = 0.0; + cstr3 = 0.0; + sstr3 = 0.0; + cstr4 = 0.0; + sstr4 = 0.0; + for (i = 0; i < nlocal; i++) { + //mux = mu[i][0]; + //muy = mu[i][1]; + //muz = mu[i][2]; + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + + // dir 1: (k,l,m) + muk[n][i] = (spx*k*unitk[0] + spy*l*unitk[1] + spz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; + slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; + cstr1 += muk[n][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr1 += muk[n][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + + // dir 2: (k,-l,m) + muk[n+1][i] = (spx*k*unitk[0] - spy*l*unitk[1] + spz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; + slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; + cstr2 += muk[n+1][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr2 += muk[n+1][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + + // dir 3: (k,l,-m) + muk[n+2][i] = (spx*k*unitk[0] + spy*l*unitk[1] - spz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; + slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; + cstr3 += muk[n+2][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr3 += muk[n+2][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + + // dir 4: (k,-l,-m) + muk[n+3][i] = (spx*k*unitk[0] - spy*l*unitk[1] - spz*m*unitk[2]); + clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; + slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; + cstr4 += muk[n+3][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr4 += muk[n+3][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + } + sfacrl[n] = cstr1; + sfacim[n++] = sstr1; + sfacrl[n] = cstr2; + sfacim[n++] = sstr2; + sfacrl[n] = cstr3; + sfacim[n++] = sstr3; + sfacrl[n] = cstr4; + sfacim[n++] = sstr4; + } + } + } + } +} + +/* ---------------------------------------------------------------------- + Slab-geometry correction term to dampen inter-slab interactions between + periodically repeating slabs. Yields good approximation to 2D EwaldDipoleSpin if + adequate empty space is left between repeating slabs (J. Chem. Phys. + 111, 3155). Slabs defined here to be parallel to the xy plane. Also + extended to non-neutral systems (J. Chem. Phys. 131, 094107). +------------------------------------------------------------------------- */ + +void EwaldDipoleSpin::slabcorr() +{ + // compute local contribution to global dipole/spin moment + + double **x = atom->x; + double zprd = domain->zprd; + int nlocal = atom->nlocal; + + double spin = 0.0; + double **sp = atom->sp; + double spx,spy,spz; + for (int i = 0; i < nlocal; i++) { + spz = sp[i][2]*sp[i][3]; + spin += spz; + } + + // sum local contributions to get global spin moment + + double spin_all; + MPI_Allreduce(&spin,&spin_all,1,MPI_DOUBLE,MPI_SUM,world); + + // need to make non-neutral systems and/or + // per-atom energy translationally invariant + + if (eflag_atom || fabs(qsum) > SMALL) { + + error->all(FLERR,"Cannot (yet) use kspace slab correction with " + "long-range spins and non-neutral systems or per-atom energy"); + } + + // compute corrections + + const double e_slabcorr = MY_2PI*(spin_all*spin_all/12.0)/volume; + const double spscale = mub2mu0 * scale; + + if (eflag_global) energy += spscale * e_slabcorr; + + // per-atom energy + + if (eflag_atom) { + double efact = spscale * MY_2PI/volume/12.0; + for (int i = 0; i < nlocal; i++) { + spz = sp[i][2]*sp[i][3]; + eatom[i] += efact * spz * spin_all; + } + } + + // add on mag. force corrections + + double ffact = spscale * (-4.0*MY_PI/volume); + double **fm_long = atom->fm_long; + for (int i = 0; i < nlocal; i++) { + fm_long[i][2] += ffact * spin_all; + } +} + +/* ---------------------------------------------------------------------- + compute musum,musqsum,mu2 for magnetic spins + called initially, when particle count changes, when spins are changed +------------------------------------------------------------------------- */ + +void EwaldDipoleSpin::spsum_musq() +{ + const int nlocal = atom->nlocal; + + musum = musqsum = mu2 = 0.0; + if (atom->sp_flag) { + double** sp = atom->sp; + double spx,spy,spz; + double musum_local(0.0), musqsum_local(0.0); + + for (int i = 0; i < nlocal; i++) { + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + musum_local += spx + spy + spz; + musqsum_local += spx*spx + spy*spy + spz*spz; + } + + MPI_Allreduce(&musum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&musqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); + + mu2 = musqsum * mub2mu0; + } + + if (mu2 == 0 && comm->me == 0) + error->all(FLERR,"Using kspace solver EwaldDipoleSpin on system with no spins"); +} diff --git a/src/KSPACE/ewald_dipole_spin.h b/src/KSPACE/ewald_dipole_spin.h new file mode 100644 index 0000000000..92122525a8 --- /dev/null +++ b/src/KSPACE/ewald_dipole_spin.h @@ -0,0 +1,102 @@ +/* -*- 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 KSPACE_CLASS + +KSpaceStyle(ewald/dipole/spin,EwaldDipoleSpin) + +#else + +#ifndef LMP_EWALD_DIPOLE_SPIN_H +#define LMP_EWALD_DIPOLE_SPIN_H + +#include "ewald_dipole.h" + +namespace LAMMPS_NS { + +class EwaldDipoleSpin : public EwaldDipole { + public: + EwaldDipoleSpin(class LAMMPS *, int, char **); + virtual ~EwaldDipoleSpin(); + void init(); + void setup(); + void compute(int, int); + + protected: + double hbar; // reduced Planck's constant + double mub; // Bohr's magneton + double mu_0; // vacuum permeability + double mub2mu0; // prefactor for mech force + double mub2mu0hbinv; // prefactor for mag force + + void spsum_musq(); + virtual void eik_dot_r(); + void slabcorr(); + +}; + +} + +#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. + +E: Cannot use EwaldDipoleSpin with 2d simulation + +The kspace style ewald cannot be used in 2d simulations. You can use +2d EwaldDipoleSpin in a 3d simulation; see the kspace_modify command. + +E: Kspace style requires atom attribute q + +The atom style defined does not have these attributes. + +E: Cannot use nonperiodic boundaries with EwaldDipoleSpin + +For kspace style ewald, all 3 dimensions must have periodic boundaries +unless you use the kspace_modify command to define a 2d slab with a +non-periodic z dimension. + +E: Incorrect boundaries with slab EwaldDipoleSpin + +Must have periodic x,y dimensions and non-periodic z dimension to use +2d slab option with EwaldDipoleSpin. + +E: Cannot (yet) use EwaldDipoleSpin with triclinic box and slab correction + +This feature is not yet supported. + +E: KSpace style is incompatible with Pair style + +Setting a kspace style requires that a pair style with matching +long-range Coulombic or dispersion components be used. + +E: KSpace accuracy must be > 0 + +The kspace accuracy designated in the input must be greater than zero. + +E: Must use 'kspace_modify gewald' for uncharged system + +UNDOCUMENTED + +E: Cannot (yet) use K-space slab correction with compute group/group for triclinic systems + +This option is not yet supported. + +*/ -- GitLab From 6b4303c405b9fa0f39eb69fcd8a1b53e66936618 Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 24 Sep 2018 16:40:59 -0600 Subject: [PATCH 0048/1243] Commit2 JT 092418 - initialized g_ewald before Newton solver - mu2 is now adim in ewald_dipole_spin --- examples/SPIN/pppm_spin/in.dipole.pppm_dipole | 2 +- examples/SPIN/pppm_spin/in.spin.ewald_spin | 4 ++-- src/KSPACE/ewald_dipole.cpp | 9 +++++++++ src/KSPACE/ewald_dipole_spin.cpp | 12 +++++++++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole index c2c49e3caf..86ac5198b0 100644 --- a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole +++ b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole @@ -28,7 +28,7 @@ pair_coeff * * 0.0 0.0 #kspace_style pppm/disp 1.0e-4 #kspace_style pppm/dipole 1.0e-4 kspace_style ewald/dipole 1.0e-4 -kspace_modify gewald 0.1 +#kspace_modify gewald 0.1 neighbor 0.3 bin neigh_modify every 2 delay 4 check yes diff --git a/examples/SPIN/pppm_spin/in.spin.ewald_spin b/examples/SPIN/pppm_spin/in.spin.ewald_spin index d9ca46b27a..f2192676c7 100644 --- a/examples/SPIN/pppm_spin/in.spin.ewald_spin +++ b/examples/SPIN/pppm_spin/in.spin.ewald_spin @@ -36,8 +36,8 @@ neigh_modify every 10 check yes delay 20 #kspace_style pppm/dipole/spin 1.0e-4 #kspace_style ewald/dipole/spin 1.0e-4 -kspace_style ewald/dipole/spin 1.0e-2 -kspace_modify mesh 32 32 32 +kspace_style ewald/dipole/spin 1.0e-4 +#kspace_modify mesh 32 32 32 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index 42d850dcc2..c3a3818013 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -163,6 +163,15 @@ void EwaldDipole::init() if (!gewaldflag) { if (accuracy <= 0.0) error->all(FLERR,"KSpace accuracy must be > 0"); + + // initial guess with old method + + g_ewald = accuracy*sqrt(natoms*cutoff*xprd*yprd*zprd) / (2.0*mu2); + if (g_ewald >= 1.0) g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; + else g_ewald = sqrt(-log(g_ewald)) / cutoff; + + // try Newton solver + double g_ewald_new = NewtonSolve(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); if (g_ewald_new > 0.0) g_ewald = g_ewald_new; diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp index 5522b18e03..43b9b32c76 100644 --- a/src/KSPACE/ewald_dipole_spin.cpp +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -164,6 +164,15 @@ void EwaldDipoleSpin::init() if (!gewaldflag) { if (accuracy <= 0.0) error->all(FLERR,"KSpace accuracy must be > 0"); + + // initial guess with old method + + g_ewald = accuracy*sqrt(natoms*cutoff*xprd*yprd*zprd) / (2.0*mu2); + if (g_ewald >= 1.0) g_ewald = (1.35 - 0.15*log(accuracy))/cutoff; + else g_ewald = sqrt(-log(g_ewald)) / cutoff; + + // try Newton solver + double g_ewald_new = NewtonSolve(g_ewald,cutoff,natoms,xprd*yprd*zprd,mu2); if (g_ewald_new > 0.0) g_ewald = g_ewald_new; @@ -887,7 +896,8 @@ void EwaldDipoleSpin::spsum_musq() MPI_Allreduce(&musum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&musqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); - mu2 = musqsum * mub2mu0; + //mu2 = musqsum * mub2mu0; + mu2 = musqsum; } if (mu2 == 0 && comm->me == 0) -- GitLab From 19aaf294e560e1a0b70699428736e0ef3f003fab Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 27 Sep 2018 10:46:52 -0600 Subject: [PATCH 0049/1243] Commit JT 092718 - renamed pair/spin/long functions - started to work on debugging ewald_dipole (force errors) --- examples/SPIN/pppm_spin/in.spin.ewald_spin | 27 ++-- examples/SPIN/pppm_spin/in.spin.pppm_spin | 17 ++- .../SPIN/pppm_spin/in.spin.spin_dipolar_cut | 18 +-- src/KSPACE/ewald_dipole.cpp | 18 ++- src/KSPACE/ewald_dipole_spin.cpp | 16 ++- src/KSPACE/pppm_dipole_spin.cpp | 13 +- src/SPIN/pair_spin_dipolar_cut.cpp | 30 +++-- ...in_long.cpp => pair_spin_dipolar_long.cpp} | 57 ++++----- ...r_spin_long.h => pair_spin_dipolar_long.h} | 12 +- ...p.cpp => pair_spin_dipolar_long_qsymp.cpp} | 119 +++++------------- ...qsymp.h => pair_spin_dipolar_long_qsymp.h} | 12 +- 11 files changed, 153 insertions(+), 186 deletions(-) rename src/SPIN/{pair_spin_long.cpp => pair_spin_dipolar_long.cpp} (91%) rename src/SPIN/{pair_spin_long.h => pair_spin_dipolar_long.h} (90%) rename src/SPIN/{pair_spin_long_qsymp.cpp => pair_spin_dipolar_long_qsymp.cpp} (82%) rename src/SPIN/{pair_spin_long_qsymp.h => pair_spin_dipolar_long_qsymp.h} (89%) diff --git a/examples/SPIN/pppm_spin/in.spin.ewald_spin b/examples/SPIN/pppm_spin/in.spin.ewald_spin index f2192676c7..c0ce74dd77 100644 --- a/examples/SPIN/pppm_spin/in.spin.ewald_spin +++ b/examples/SPIN/pppm_spin/in.spin.ewald_spin @@ -19,30 +19,30 @@ create_atoms 1 box mass 1 58.93 -#set group all spin/random 31 1.72 -set group all spin 1.72 0.0 0.0 1.0 -velocity all create 100 4928459 rot yes dist gaussian +set group all spin/random 31 1.72 +#set group all spin 1.72 0.0 0.0 1.0 +#velocity all create 100 4928459 rot yes dist gaussian -pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long 8.0 #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long/qsymp 8.0 #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 -pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co -pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +#pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +#pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 #pair_coeff * * spin/long/qsymp long 8.0 -pair_coeff * * spin/long long 8.0 +pair_style spin/dipolar/long 8.0 +pair_coeff * * long 8.0 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 -#kspace_style pppm/dipole/spin 1.0e-4 -#kspace_style ewald/dipole/spin 1.0e-4 -kspace_style ewald/dipole/spin 1.0e-4 -#kspace_modify mesh 32 32 32 +kspace_style ewald/dipole/spin 1.0e-4 +#kspace_modify mesh 32 32 32 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 fix 2 all langevin/spin 0.0 0.0 21 -fix 3 all nve/spin lattice yes +#fix 3 all nve/spin lattice yes +fix 3 all nve/spin lattice no timestep 0.0001 @@ -57,7 +57,8 @@ variable magnorm equal c_out_mag[4] variable emag equal c_out_mag[5] variable tmag equal c_out_mag[6] -thermo_style custom step time v_magnorm v_emag temp etotal +thermo_style custom step time v_magnorm v_tmag temp v_emag ke pe etotal +#thermo_style custom step time v_magnorm v_emag temp etotal thermo 10 compute outsp all property/atom spx spy spz sp fmx fmy fmz diff --git a/examples/SPIN/pppm_spin/in.spin.pppm_spin b/examples/SPIN/pppm_spin/in.spin.pppm_spin index 9e57797f55..6762fe6fab 100644 --- a/examples/SPIN/pppm_spin/in.spin.pppm_spin +++ b/examples/SPIN/pppm_spin/in.spin.pppm_spin @@ -23,19 +23,18 @@ mass 1 58.93 set group all spin 1.72 0.0 0.0 1.0 velocity all create 100 4928459 rot yes dist gaussian -#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 -pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long/qsymp 8.0 -#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 +pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long/qsymp 8.0 pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 -pair_coeff * * spin/long/qsymp long 8.0 -#pair_coeff * * spin/long long 8.0 +#pair_coeff * * spin/dipolar/long/qsymp long 8.0 +pair_coeff * * spin/dipolar/long long 8.0 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 -kspace_style pppm/dipole/spin 1.0e-4 -kspace_modify mesh 32 32 32 +kspace_style pppm/dipole/spin 1.0e-4 +#kspace_modify mesh 32 32 32 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 @@ -61,5 +60,5 @@ thermo 10 compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] -#run 20000 -run 1 +run 20000 +#run 1 diff --git a/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut b/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut index 838181e6d8..b265c4413e 100644 --- a/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut +++ b/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut @@ -19,16 +19,17 @@ create_atoms 1 box mass 1 58.93 -#set group all spin/random 31 1.72 -set group all spin 1.72 0.0 0.0 1.0 -velocity all create 100 4928459 rot yes dist gaussian +set group all spin/random 31 1.72 +#set group all spin 1.72 0.0 0.0 1.0 +#velocity all create 100 4928459 rot yes dist gaussian #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 -pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/cut 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/cut 8.0 +pair_style spin/dipolar/cut 8.0 #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 -pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co -pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 -pair_coeff * * spin/dipolar/cut long 8.0 +#pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +#pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +pair_coeff * * long 8.0 #pair_coeff * * spin/long long 8.0 neighbor 0.1 bin @@ -37,7 +38,8 @@ neigh_modify every 10 check yes delay 20 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 fix 2 all langevin/spin 0.0 0.0 21 -fix 3 all nve/spin lattice yes +#fix 3 all nve/spin lattice yes +fix 3 all nve/spin lattice no timestep 0.0001 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index c3a3818013..ea05889f52 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -449,12 +449,19 @@ void EwaldDipole::compute(int eflag, int vflag) exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; + // mu dot k product + + //muik = mu[i][0]*kx + mu[i][1]*ky + mu[i][2]*kz; + + // taking im of struct_fact x exp(i*k*ri) (for force calc.) partial = (muk[k][i])*(expim*sfacrl_all[k] + exprl*sfacim_all[k]); - ek[i][0] += partial*eg[k][0]; - ek[i][1] += partial*eg[k][1]; - ek[i][2] += partial*eg[k][2]; + //partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); + //partial = muik * (expim*sfacrl_all[k] + exprl*sfacim_all[k]); + ek[i][0] += partial * eg[k][0]; + ek[i][1] += partial * eg[k][1]; + ek[i][2] += partial * eg[k][2]; // compute field for torque calculation @@ -493,6 +500,9 @@ void EwaldDipole::compute(int eflag, int vflag) f[i][0] += muscale * ek[i][0]; f[i][1] += muscale * ek[i][1]; if (slabflag != 2) f[i][2] += muscale * ek[i][2]; + //f[i][0] -= muscale * ek[i][0]; + //f[i][1] -= muscale * ek[i][1]; + //if (slabflag != 2) f[i][2] -= muscale * ek[i][2]; t[i][0] += -mu[i][1]*tk[i][2] + mu[i][2]*tk[i][1]; t[i][1] += -mu[i][2]*tk[i][0] + mu[i][0]*tk[i][2]; if (slabflag != 2) t[i][2] += -mu[i][0]*tk[i][1] + mu[i][1]*tk[i][0]; @@ -545,7 +555,7 @@ void EwaldDipole::compute(int eflag, int vflag) } /* ---------------------------------------------------------------------- - compute the + compute the struc. factors and mu dot k products ------------------------------------------------------------------------- */ void EwaldDipole::eik_dot_r() diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp index 43b9b32c76..9a61d9cbe1 100644 --- a/src/KSPACE/ewald_dipole_spin.cpp +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -50,11 +50,11 @@ EwaldDipoleSpin::EwaldDipoleSpin(LAMMPS *lmp, int narg, char **arg) : dipoleflag = 0; spinflag = 1; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } /* ---------------------------------------------------------------------- @@ -500,6 +500,9 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) const double spscale2 = mub2mu0hbinv * scale; //const double muscale = qqrd2e * scale; + printf("test ek: %g %g %g \n",ek[0][0],ek[0][1],ek[0][2]); + printf("test tk: %g %g %g \n",tk[0][0],tk[0][1],tk[0][2]); + for (i = 0; i < nlocal; i++) { f[i][0] += spscale * ek[i][0]; f[i][1] += spscale * ek[i][1]; @@ -509,6 +512,9 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) if (slabflag != 2) fm_long[i][2] += spscale2 * tk[i][3]; } + printf("test f_l: %g %g %g \n",f[0][0],f[0][1],f[0][2]); + printf("test fm_l: %g %g %g \n",fm_long[0][0],fm_long[0][1],fm_long[0][2]); + // sum global energy across Kspace vevs and add in volume-dependent term // taking the re-part of struct_fact_i x struct_fact_j // substracting self energy and scaling diff --git a/src/KSPACE/pppm_dipole_spin.cpp b/src/KSPACE/pppm_dipole_spin.cpp index aa85c5d289..e66ab4903e 100644 --- a/src/KSPACE/pppm_dipole_spin.cpp +++ b/src/KSPACE/pppm_dipole_spin.cpp @@ -69,11 +69,11 @@ PPPMDipoleSpin::PPPMDipoleSpin(LAMMPS *lmp, int narg, char **arg) : dipoleflag = 0; spinflag = 1; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } /* ---------------------------------------------------------------------- @@ -746,7 +746,8 @@ void PPPMDipoleSpin::spsum_spsq() MPI_Allreduce(&spsum_local,&musum,1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&spsqsum_local,&musqsum,1,MPI_DOUBLE,MPI_SUM,world); - mu2 = musqsum * mub2mu0; + //mu2 = musqsum * mub2mu0; + mu2 = musqsum; } if (mu2 == 0 && comm->me == 0) diff --git a/src/SPIN/pair_spin_dipolar_cut.cpp b/src/SPIN/pair_spin_dipolar_cut.cpp index f686d12926..b2c0a1ab11 100644 --- a/src/SPIN/pair_spin_dipolar_cut.cpp +++ b/src/SPIN/pair_spin_dipolar_cut.cpp @@ -13,7 +13,7 @@ /* ------------------------------------------------------------------------ Contributing authors: Julien Tranchida (SNL) - Aidan Thompson (SNL) + Stan Moore (SNL) Please cite the related publication: Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). @@ -64,11 +64,13 @@ lockfixnvespin(NULL) no_virial_fdotr_compute = 1; lattice_flag = 0; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + + //printf("hbar: %g, mub2mu0hbinv: %g \n",hbar,mub2mu0hbinv); } @@ -391,7 +393,9 @@ void PairSpinDipolarCut::compute_single_pair(int ii, double fmi[3]) compute_dipolar(i,j,rij,fmi,spi,spj,r3inv); } } - + + //printf("test fm: %g, %g, %g \n",fmi[0],fmi[1],fmi[2]); + //fmi[0] *= mub2mu0hbinv; //fmi[1] *= mub2mu0hbinv; //fmi[2] *= mub2mu0hbinv; @@ -405,15 +409,15 @@ void PairSpinDipolarCut::compute_dipolar(int i, int j, double rij[3], double fmi[3], double spi[4], double spj[4], double r3inv) { double sjdotr; - double gigjri2,pre; + double gigjri3,pre; sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; - gigjri2 = (spi[3] * spj[3])*r3inv; - pre = mub2mu0hbinv * gigjri2 / 4.0 / MY_PI; + gigjri3 = (spi[3] * spj[3])*r3inv; + pre = mub2mu0hbinv * gigjri3 / 4.0 / MY_PI; - fmi[0] += pre * gigjri2 * (3.0 * sjdotr *rij[0] - spj[0]); - fmi[1] += pre * gigjri2 * (3.0 * sjdotr *rij[1] - spj[1]); - fmi[2] += pre * gigjri2 * (3.0 * sjdotr *rij[2] - spj[2]); + fmi[0] += pre * gigjri3 * (3.0 * sjdotr *rij[0] - spj[0]); + fmi[1] += pre * gigjri3 * (3.0 * sjdotr *rij[1] - spj[1]); + fmi[2] += pre * gigjri3 * (3.0 * sjdotr *rij[2] - spj[2]); } /* ---------------------------------------------------------------------- diff --git a/src/SPIN/pair_spin_long.cpp b/src/SPIN/pair_spin_dipolar_long.cpp similarity index 91% rename from src/SPIN/pair_spin_long.cpp rename to src/SPIN/pair_spin_dipolar_long.cpp index d7ecdf5edd..c1030c92d7 100644 --- a/src/SPIN/pair_spin_long.cpp +++ b/src/SPIN/pair_spin_dipolar_long.cpp @@ -13,12 +13,7 @@ /* ------------------------------------------------------------------------ Contributing authors: Julien Tranchida (SNL) - Aidan Thompson (SNL) - - Please cite the related publication: - Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). - Massively parallel symplectic algorithm for coupled magnetic spin dynamics - and molecular dynamics. Journal of Computational Physics. + Stan Moore (SNL) ------------------------------------------------------------------------- */ #include @@ -26,7 +21,7 @@ #include #include -#include "pair_spin_long.h" +#include "pair_spin_dipolar_long.h" #include "atom.h" #include "comm.h" #include "neighbor.h" @@ -55,7 +50,7 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -PairSpinLong::PairSpinLong(LAMMPS *lmp) : PairSpin(lmp), +PairSpinDipolarLong::PairSpinDipolarLong(LAMMPS *lmp) : PairSpin(lmp), lockfixnvespin(NULL) { single_enable = 0; @@ -64,11 +59,11 @@ lockfixnvespin(NULL) no_virial_fdotr_compute = 1; lattice_flag = 0; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } @@ -76,7 +71,7 @@ lockfixnvespin(NULL) free all arrays ------------------------------------------------------------------------- */ -PairSpinLong::~PairSpinLong() +PairSpinDipolarLong::~PairSpinDipolarLong() { if (allocated) { memory->destroy(setflag); @@ -89,7 +84,7 @@ PairSpinLong::~PairSpinLong() global settings ------------------------------------------------------------------------- */ -void PairSpinLong::settings(int narg, char **arg) +void PairSpinDipolarLong::settings(int narg, char **arg) { if (narg < 1 || narg > 2) error->all(FLERR,"Incorrect args in pair_style command"); @@ -118,7 +113,7 @@ void PairSpinLong::settings(int narg, char **arg) set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSpinLong::coeff(int narg, char **arg) +void PairSpinDipolarLong::coeff(int narg, char **arg) { if (!allocated) allocate(); @@ -151,7 +146,7 @@ void PairSpinLong::coeff(int narg, char **arg) init specific to this pair style ------------------------------------------------------------------------- */ -void PairSpinLong::init_style() +void PairSpinDipolarLong::init_style() { if (!atom->sp_flag) error->all(FLERR,"Pair spin requires atom/spin style"); @@ -194,7 +189,7 @@ void PairSpinLong::init_style() init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSpinLong::init_one(int i, int j) +double PairSpinDipolarLong::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); @@ -207,7 +202,7 @@ double PairSpinLong::init_one(int i, int j) extract the larger cutoff if "cut" or "cut_coul" ------------------------------------------------------------------------- */ -void *PairSpinLong::extract(const char *str, int &dim) +void *PairSpinDipolarLong::extract(const char *str, int &dim) { if (strcmp(str,"cut") == 0) { dim = 0; @@ -230,7 +225,7 @@ void *PairSpinLong::extract(const char *str, int &dim) /* ---------------------------------------------------------------------- */ -void PairSpinLong::compute(int eflag, int vflag) +void PairSpinDipolarLong::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double r,rinv,r2inv,rsq; @@ -357,7 +352,7 @@ void PairSpinLong::compute(int eflag, int vflag) update the pair interaction fmi acting on the spin ii ------------------------------------------------------------------------- */ -void PairSpinLong::compute_single_pair(int ii, double fmi[3]) +void PairSpinDipolarLong::compute_single_pair(int ii, double fmi[3]) { int i,j,jj,jnum,itype,jtype; double r,rinv,r2inv,rsq; @@ -436,18 +431,20 @@ void PairSpinLong::compute_single_pair(int ii, double fmi[3]) } // adding the kspace components to fm - + + //printf("test fm before: %g, %g, %g \n",fmi[0],fmi[1],fmi[2]); + //printf("test fm_long: %g, %g, %g \n",fm_long[i][0],fm_long[i][1],fm_long[i][2]); fmi[0] += fm_long[i][0]; fmi[1] += fm_long[i][1]; fmi[2] += fm_long[i][2]; - + //printf("test fm after: %g, %g, %g \n",fmi[0],fmi[1],fmi[2]); } /* ---------------------------------------------------------------------- compute dipolar interaction between spins i and j ------------------------------------------------------------------------- */ -void PairSpinLong::compute_long(int i, int j, double rij[3], +void PairSpinDipolarLong::compute_long(int i, int j, double rij[3], double bij[4], double fmi[3], double spi[4], double spj[4]) { double sjdotr; @@ -469,7 +466,7 @@ void PairSpinLong::compute_long(int i, int j, double rij[3], atom i and atom j ------------------------------------------------------------------------- */ -void PairSpinLong::compute_long_mech(int i, int j, double rij[3], +void PairSpinDipolarLong::compute_long_mech(int i, int j, double rij[3], double bij[4], double fi[3], double spi[3], double spj[3]) { double sdots,sidotr,sjdotr,b2,b3; @@ -499,7 +496,7 @@ void PairSpinLong::compute_long_mech(int i, int j, double rij[3], allocate all arrays ------------------------------------------------------------------------- */ -void PairSpinLong::allocate() +void PairSpinDipolarLong::allocate() { allocated = 1; int n = atom->ntypes; @@ -517,7 +514,7 @@ void PairSpinLong::allocate() proc 0 writes to restart file ------------------------------------------------------------------------- */ -void PairSpinLong::write_restart(FILE *fp) +void PairSpinDipolarLong::write_restart(FILE *fp) { write_restart_settings(fp); @@ -536,7 +533,7 @@ void PairSpinLong::write_restart(FILE *fp) proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ -void PairSpinLong::read_restart(FILE *fp) +void PairSpinDipolarLong::read_restart(FILE *fp) { read_restart_settings(fp); @@ -562,7 +559,7 @@ void PairSpinLong::read_restart(FILE *fp) proc 0 writes to restart file ------------------------------------------------------------------------- */ -void PairSpinLong::write_restart_settings(FILE *fp) +void PairSpinDipolarLong::write_restart_settings(FILE *fp) { fwrite(&cut_spin_long_global,sizeof(double),1,fp); fwrite(&mix_flag,sizeof(int),1,fp); @@ -572,7 +569,7 @@ void PairSpinLong::write_restart_settings(FILE *fp) proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ -void PairSpinLong::read_restart_settings(FILE *fp) +void PairSpinDipolarLong::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&cut_spin_long_global,sizeof(double),1,fp); diff --git a/src/SPIN/pair_spin_long.h b/src/SPIN/pair_spin_dipolar_long.h similarity index 90% rename from src/SPIN/pair_spin_long.h rename to src/SPIN/pair_spin_dipolar_long.h index 0cdf6d2b80..191e983328 100644 --- a/src/SPIN/pair_spin_long.h +++ b/src/SPIN/pair_spin_dipolar_long.h @@ -13,24 +13,24 @@ #ifdef PAIR_CLASS -PairStyle(spin/long,PairSpinLong) +PairStyle(spin/dipolar/long,PairSpinDipolarLong) #else -#ifndef LMP_PAIR_SPIN_LONG_H -#define LMP_PAIR_SPIN_LONG_H +#ifndef LMP_PAIR_SPIN_DIPOLAR_LONG_H +#define LMP_PAIR_SPIN_DIPOLAR_LONG_H #include "pair_spin.h" namespace LAMMPS_NS { -class PairSpinLong : public PairSpin { +class PairSpinDipolarLong : public PairSpin { public: double cut_coul; double **sigma; - PairSpinLong(class LAMMPS *); - ~PairSpinLong(); + PairSpinDipolarLong(class LAMMPS *); + ~PairSpinDipolarLong(); void settings(int, char **); void coeff(int, char **); double init_one(int, int); diff --git a/src/SPIN/pair_spin_long_qsymp.cpp b/src/SPIN/pair_spin_dipolar_long_qsymp.cpp similarity index 82% rename from src/SPIN/pair_spin_long_qsymp.cpp rename to src/SPIN/pair_spin_dipolar_long_qsymp.cpp index 3b499d0ef7..63876ba97a 100644 --- a/src/SPIN/pair_spin_long_qsymp.cpp +++ b/src/SPIN/pair_spin_dipolar_long_qsymp.cpp @@ -13,12 +13,7 @@ /* ------------------------------------------------------------------------ Contributing authors: Julien Tranchida (SNL) - Aidan Thompson (SNL) - - Please cite the related publication: - Tranchida, J., Plimpton, S. J., Thibaudeau, P., & Thompson, A. P. (2018). - Massively parallel symplectic algorithm for coupled magnetic spin dynamics - and molecular dynamics. Journal of Computational Physics. + Stan Moore (SNL) ------------------------------------------------------------------------- */ #include @@ -26,7 +21,7 @@ #include #include -#include "pair_spin_long_qsymp.h" +#include "pair_spin_dipolar_long_qsymp.h" #include "atom.h" #include "comm.h" #include "neighbor.h" @@ -55,7 +50,7 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -PairSpinLongQsymp::PairSpinLongQsymp(LAMMPS *lmp) : PairSpin(lmp), +PairSpinDipolarLongQsymp::PairSpinDipolarLongQsymp(LAMMPS *lmp) : PairSpin(lmp), lockfixnvespin(NULL) { single_enable = 0; @@ -64,11 +59,11 @@ lockfixnvespin(NULL) no_virial_fdotr_compute = 1; lattice_flag = 0; - hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0; // in eV - mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz + hbar = force->hplanck/MY_2PI; // eV/(rad.THz) + mub = 5.78901e-5; // in eV/T + mu_0 = 1.2566370614e-6; // in T.m/A + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } @@ -76,7 +71,7 @@ lockfixnvespin(NULL) free all arrays ------------------------------------------------------------------------- */ -PairSpinLongQsymp::~PairSpinLongQsymp() +PairSpinDipolarLongQsymp::~PairSpinDipolarLongQsymp() { if (allocated) { memory->destroy(setflag); @@ -89,7 +84,7 @@ PairSpinLongQsymp::~PairSpinLongQsymp() global settings ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::settings(int narg, char **arg) +void PairSpinDipolarLongQsymp::settings(int narg, char **arg) { if (narg < 1 || narg > 2) error->all(FLERR,"Incorrect args in pair_style command"); @@ -118,7 +113,7 @@ void PairSpinLongQsymp::settings(int narg, char **arg) set coeffs for one or more type pairs ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::coeff(int narg, char **arg) +void PairSpinDipolarLongQsymp::coeff(int narg, char **arg) { if (!allocated) allocate(); @@ -151,7 +146,7 @@ void PairSpinLongQsymp::coeff(int narg, char **arg) init specific to this pair style ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::init_style() +void PairSpinDipolarLongQsymp::init_style() { if (!atom->sp_flag) error->all(FLERR,"Pair spin requires atom/spin style"); @@ -194,7 +189,7 @@ void PairSpinLongQsymp::init_style() init for one type pair i,j and corresponding j,i ------------------------------------------------------------------------- */ -double PairSpinLongQsymp::init_one(int i, int j) +double PairSpinDipolarLongQsymp::init_one(int i, int j) { if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); @@ -207,7 +202,7 @@ double PairSpinLongQsymp::init_one(int i, int j) extract the larger cutoff if "cut" or "cut_coul" ------------------------------------------------------------------------- */ -void *PairSpinLongQsymp::extract(const char *str, int &dim) +void *PairSpinDipolarLongQsymp::extract(const char *str, int &dim) { if (strcmp(str,"cut") == 0) { dim = 0; @@ -230,7 +225,7 @@ void *PairSpinLongQsymp::extract(const char *str, int &dim) /* ---------------------------------------------------------------------- */ -void PairSpinLongQsymp::compute(int eflag, int vflag) +void PairSpinDipolarLongQsymp::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double r,rinv,r2inv,rsq; @@ -359,9 +354,9 @@ void PairSpinLongQsymp::compute(int eflag, int vflag) // correction of the fm_kspace - fm_long[i][0] -= mub2mu0hbinv * fmx_erf_s; - fm_long[i][1] -= mub2mu0hbinv * fmy_erf_s; - fm_long[i][2] -= mub2mu0hbinv * fmz_erf_s; + fm_long[i][0] -= (mub2mu0hbinv * fmx_erf_s); + fm_long[i][1] -= (mub2mu0hbinv * fmy_erf_s); + fm_long[i][2] -= (mub2mu0hbinv * fmz_erf_s); if (newton_pair || j < nlocal) { f[j][0] -= fi[0]; @@ -391,21 +386,17 @@ void PairSpinLongQsymp::compute(int eflag, int vflag) removing erf(r)/r (for r in [0,rc]) from the kspace force ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) +void PairSpinDipolarLongQsymp::compute_single_pair(int ii, double fmi[3]) { int i,j,jj,jnum,itype,jtype; - double r,rinv,r2inv,r3inv,rsq; - double grij,expm2,t,erf; + double rinv,r2inv,r3inv,rsq; double sjdotr,sjdotrr3inv; double b1,b2,gigj; double bij[4],xi[3],rij[3]; double spi[4],spj[4]; double local_cut2; - double pre1,pre2,pre3; int *ilist,*jlist,*numneigh,**firstneigh; - //double fmx_erf_s,fmy_erf_s,fmz_erf_s; double fmx_s,fmy_s,fmz_s; - //double fmx_long,fmy_long,fmz_long; double **x = atom->x; double **sp = atom->sp; @@ -416,10 +407,6 @@ void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) numneigh = list->numneigh; firstneigh = list->firstneigh; - pre1 = 2.0 * g_ewald / MY_PIS; - pre2 = 4.0 * pow(g_ewald,3.0) / MY_PIS; - pre3 = 8.0 * pow(g_ewald,5.0) / MY_PIS; - // computation of the exchange interaction // loop over neighbors of atom i @@ -427,16 +414,11 @@ void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) xi[0] = x[i][0]; xi[1] = x[i][1]; xi[2] = x[i][2]; - spi[0] = sp[i][0]; - spi[1] = sp[i][1]; - spi[2] = sp[i][2]; spi[3] = sp[i][3]; jlist = firstneigh[i]; jnum = numneigh[i]; itype = type[i]; - //fmx_long = fmy_long = fmz_long = 0.0; - //fmx_erf_s = fmy_erf_s = fmz_erf_s = 0.0; fmx_s = fmy_s = fmz_s = 0.0; for (jj = 0; jj < jnum; jj++) { @@ -449,8 +431,6 @@ void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) spj[2] = sp[j][2]; spj[3] = sp[j][3]; - bij[0] = bij[1] = bij[2] = bij[3] = 0.0; - rij[0] = x[j][0] - xi[0]; rij[1] = x[j][1] - xi[1]; rij[2] = x[j][2] - xi[2]; @@ -458,58 +438,25 @@ void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; + // evaluating full dipolar interaction on [0,rc] + if (rsq < local_cut2) { r2inv = 1.0/rsq; rinv = sqrt(r2inv); r3inv = r2inv*rinv; - - r = sqrt(rsq); - //grij = g_ewald * r; - //expm2 = exp(-grij*grij); - //t = 1.0 / (1.0 + EWALD_P*grij); - - // evaluating erf instead of erfc - - //erf = 1.0 - t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2; - - //bij[0] = erf * rinv; - //bij[1] = (bij[0] + pre1*expm2) * r2inv; - //bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; - //bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; - - //gigj = spi[3] * spj[3]; - //sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; - - //b1 = bij[1]; - //b2 = bij[2]; - - // evaluating short-range correction to the kspace part on [0,rc] - - //fmx_erf_s += mub2mu0hbinv * gigj * (b2 * sjdotr * rij[0] - b1 * spj[0]); - //fmy_erf_s += mub2mu0hbinv * gigj * (b2 * sjdotr * rij[1] - b1 * spj[1]); - //fmz_erf_s += mub2mu0hbinv * gigj * (b2 * sjdotr * rij[2] - b1 * spj[2]); - - // evaluating real dipolar interaction on [0,rc] - + + gigj = spi[3] * spj[3]; + sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; sjdotrr3inv = 3.0 * sjdotr * r3inv; + fmx_s += mub2mu0hbinv * gigj * (sjdotrr3inv * rij[0] - sp[i][0]/r3inv); fmy_s += mub2mu0hbinv * gigj * (sjdotrr3inv * rij[1] - sp[i][1]/r3inv); fmz_s += mub2mu0hbinv * gigj * (sjdotrr3inv * rij[2] - sp[i][2]/r3inv); - } } - // removing short-range erf function from kspace force - - //fmx_long = fm_long[i][0] - fmx_erf_s; - //fmy_long = fm_long[i][1] - fmy_erf_s; - //fmz_long = fm_long[i][2] - fmz_erf_s; - // adding truncated kspace force and short-range full force - //fmi[0] += fmx_s + fmx_long; - //fmi[1] += fmy_s + fmy_long; - //fmi[2] += fmz_s + fmz_long; fmi[0] += (fmx_s + fm_long[i][0]); fmi[1] += (fmy_s + fm_long[i][1]); fmi[2] += (fmz_s + fm_long[i][2]); @@ -519,7 +466,7 @@ void PairSpinLongQsymp::compute_single_pair(int ii, double fmi[3]) compute dipolar interaction between spins i and j ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::compute_long(int i, int j, double rij[3], +void PairSpinDipolarLongQsymp::compute_long(int i, int j, double rij[3], double bij[4], double fmi[3], double spi[4], double spj[4]) { double sjdotr; @@ -541,7 +488,7 @@ void PairSpinLongQsymp::compute_long(int i, int j, double rij[3], atom i and atom j ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::compute_long_mech(int i, int j, double rij[3], +void PairSpinDipolarLongQsymp::compute_long_mech(int i, int j, double rij[3], double bij[4], double fi[3], double spi[3], double spj[3]) { double sdots,sidotr,sjdotr,b2,b3; @@ -571,7 +518,7 @@ void PairSpinLongQsymp::compute_long_mech(int i, int j, double rij[3], allocate all arrays ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::allocate() +void PairSpinDipolarLongQsymp::allocate() { allocated = 1; int n = atom->ntypes; @@ -589,7 +536,7 @@ void PairSpinLongQsymp::allocate() proc 0 writes to restart file ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::write_restart(FILE *fp) +void PairSpinDipolarLongQsymp::write_restart(FILE *fp) { write_restart_settings(fp); @@ -608,7 +555,7 @@ void PairSpinLongQsymp::write_restart(FILE *fp) proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::read_restart(FILE *fp) +void PairSpinDipolarLongQsymp::read_restart(FILE *fp) { read_restart_settings(fp); @@ -634,7 +581,7 @@ void PairSpinLongQsymp::read_restart(FILE *fp) proc 0 writes to restart file ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::write_restart_settings(FILE *fp) +void PairSpinDipolarLongQsymp::write_restart_settings(FILE *fp) { fwrite(&cut_spin_long_global,sizeof(double),1,fp); fwrite(&mix_flag,sizeof(int),1,fp); @@ -644,7 +591,7 @@ void PairSpinLongQsymp::write_restart_settings(FILE *fp) proc 0 reads from restart file, bcasts ------------------------------------------------------------------------- */ -void PairSpinLongQsymp::read_restart_settings(FILE *fp) +void PairSpinDipolarLongQsymp::read_restart_settings(FILE *fp) { if (comm->me == 0) { fread(&cut_spin_long_global,sizeof(double),1,fp); diff --git a/src/SPIN/pair_spin_long_qsymp.h b/src/SPIN/pair_spin_dipolar_long_qsymp.h similarity index 89% rename from src/SPIN/pair_spin_long_qsymp.h rename to src/SPIN/pair_spin_dipolar_long_qsymp.h index ae8c5a3864..28867b5229 100644 --- a/src/SPIN/pair_spin_long_qsymp.h +++ b/src/SPIN/pair_spin_dipolar_long_qsymp.h @@ -13,24 +13,24 @@ #ifdef PAIR_CLASS -PairStyle(spin/long/qsymp,PairSpinLongQsymp) +PairStyle(spin/dipolar/long/qsymp,PairSpinDipolarLongQsymp) #else -#ifndef LMP_PAIR_SPIN_LONG_QSYMP_H -#define LMP_PAIR_SPIN_LONG_QSYMP_H +#ifndef LMP_PAIR_SPIN_DIPOLAR_LONG_QSYMP_H +#define LMP_PAIR_SPIN_DIPOLAR_LONG_QSYMP_H #include "pair_spin.h" namespace LAMMPS_NS { -class PairSpinLongQsymp : public PairSpin { +class PairSpinDipolarLongQsymp : public PairSpin { public: double cut_coul; double **sigma; - PairSpinLongQsymp(class LAMMPS *); - ~PairSpinLongQsymp(); + PairSpinDipolarLongQsymp(class LAMMPS *); + ~PairSpinDipolarLongQsymp(); void settings(int, char **); void coeff(int, char **); double init_one(int, int); -- GitLab From b9d12f0aa0148fa1777527e307facac7893b2de9 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 1 Oct 2018 22:01:12 -0500 Subject: [PATCH 0050/1243] Update function pointer name --- src/KIM/pair_kim.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index e209cb1202..eca3f6f1d7 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -735,7 +735,7 @@ void PairKIM::kim_init() kimerror = pargs->SetCallbackPointer( KIM::COMPUTE_CALLBACK_NAME::GetNeighborList, KIM::LANGUAGE_NAME::cpp, - reinterpret_cast(get_neigh), + reinterpret_cast(get_neigh), reinterpret_cast(this)); if (kimerror) -- GitLab From a745a0aed0846b8deccad6bdeadb263594f06555 Mon Sep 17 00:00:00 2001 From: julient31 Date: Wed, 3 Oct 2018 10:23:58 -0600 Subject: [PATCH 0051/1243] Commit JT 100318 - correction forces ewald_dipole - correction mag. dipolar energy --- examples/SPIN/pppm_spin/in.spin.ewald_spin | 4 +- src/KSPACE/ewald_dipole.cpp | 12 +--- src/KSPACE/ewald_dipole_spin.cpp | 66 ++++------------------ src/KSPACE/pppm_dipole_spin.cpp | 8 ++- src/SPIN/pair_spin_dipolar_cut.cpp | 8 ++- src/SPIN/pair_spin_dipolar_long.cpp | 9 ++- src/SPIN/pair_spin_dipolar_long_qsymp.cpp | 8 ++- 7 files changed, 37 insertions(+), 78 deletions(-) diff --git a/examples/SPIN/pppm_spin/in.spin.ewald_spin b/examples/SPIN/pppm_spin/in.spin.ewald_spin index c0ce74dd77..889ed086f8 100644 --- a/examples/SPIN/pppm_spin/in.spin.ewald_spin +++ b/examples/SPIN/pppm_spin/in.spin.ewald_spin @@ -44,7 +44,7 @@ fix 2 all langevin/spin 0.0 0.0 21 #fix 3 all nve/spin lattice yes fix 3 all nve/spin lattice no -timestep 0.0001 +timestep 0.001 compute out_mag all compute/spin @@ -65,4 +65,4 @@ compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] #run 20000 -run 1 +run 1000 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index ea05889f52..5579ba3840 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -449,16 +449,9 @@ void EwaldDipole::compute(int eflag, int vflag) exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz; expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz; - // mu dot k product - - //muik = mu[i][0]*kx + mu[i][1]*ky + mu[i][2]*kz; - - // taking im of struct_fact x exp(i*k*ri) (for force calc.) - partial = (muk[k][i])*(expim*sfacrl_all[k] + exprl*sfacim_all[k]); - //partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); - //partial = muik * (expim*sfacrl_all[k] + exprl*sfacim_all[k]); + partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); ek[i][0] += partial * eg[k][0]; ek[i][1] += partial * eg[k][1]; ek[i][2] += partial * eg[k][2]; @@ -500,9 +493,6 @@ void EwaldDipole::compute(int eflag, int vflag) f[i][0] += muscale * ek[i][0]; f[i][1] += muscale * ek[i][1]; if (slabflag != 2) f[i][2] += muscale * ek[i][2]; - //f[i][0] -= muscale * ek[i][0]; - //f[i][1] -= muscale * ek[i][1]; - //if (slabflag != 2) f[i][2] -= muscale * ek[i][2]; t[i][0] += -mu[i][1]*tk[i][2] + mu[i][2]*tk[i][1]; t[i][1] += -mu[i][2]*tk[i][0] + mu[i][0]*tk[i][2]; if (slabflag != 2) t[i][2] += -mu[i][0]*tk[i][1] + mu[i][1]*tk[i][0]; diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp index 9a61d9cbe1..df1acb337d 100644 --- a/src/KSPACE/ewald_dipole_spin.cpp +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -51,9 +51,12 @@ EwaldDipoleSpin::EwaldDipoleSpin(LAMMPS *lmp, int narg, char **arg) : spinflag = 1; hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + //mub = 5.78901e-5; // in eV/T + //mu_0 = 1.2566370614e-6; // in T.m/A + mub = 9.274e-4; // in A.Ang^2 + mu_0 = 785.15; // in eV/Ang/A^2 + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV.Ang^3 + //mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } @@ -61,12 +64,7 @@ EwaldDipoleSpin::EwaldDipoleSpin(LAMMPS *lmp, int narg, char **arg) : free all memory ------------------------------------------------------------------------- */ -EwaldDipoleSpin::~EwaldDipoleSpin() -{ - //memory->destroy(muk); - //memory->destroy(tk); - //memory->destroy(vc); -} +EwaldDipoleSpin::~EwaldDipoleSpin() {} /* ---------------------------------------------------------------------- called once before run @@ -81,12 +79,7 @@ void EwaldDipoleSpin::init() // error check - //dipoleflag = atom->mu?1:0; spinflag = atom->sp?1:0; - //qsum_qsq(0); // q[i] might not be declared ? - - //if (dipoleflag && q2) - // error->all(FLERR,"Cannot (yet) use charges with Kspace style EwaldDipoleSpin"); triclinic_check(); @@ -100,7 +93,6 @@ void EwaldDipoleSpin::init() error->all(FLERR,"Cannot use EwaldDipoleSpin with 2d simulation"); if (!atom->sp) error->all(FLERR,"Kspace style requires atom attribute sp"); -//if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q"); if ((spinflag && strcmp(update->unit_style,"metal")) != 0) error->all(FLERR,"'metal' units have to be used with spins"); @@ -134,7 +126,6 @@ void EwaldDipoleSpin::init() scale = 1.0; qqrd2e = force->qqrd2e; - //musum_musq(); spsum_musq(); natoms_original = atom->natoms; @@ -343,23 +334,6 @@ void EwaldDipoleSpin::setup() coeffs(); } -/* ---------------------------------------------------------------------- - compute dipole RMS accuracy for a dimension -------------------------------------------------------------------------- */ - -//double EwaldDipoleSpin::rms_dipole(int km, double prd, bigint natoms) -//{ -// if (natoms == 0) natoms = 1; // avoid division by zero -// -// // error from eq.(46), Wang et al., JCP 115, 6351 (2001) -// -// double value = 8*MY_PI*mu2*g_ewald/volume * -// sqrt(2*MY_PI*km*km*km/(15.0*natoms)) * -// exp(-MY_PI*MY_PI*km*km/(g_ewald*g_ewald*prd*prd)); -// -// return value; -//} - /* ---------------------------------------------------------------------- compute the EwaldDipoleSpin long-range force, energy, virial ------------------------------------------------------------------------- */ @@ -379,7 +353,6 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) // if atom count has changed, update qsum and qsqsum if (atom->natoms != natoms_original) { - //musum_musq(); spsum_musq(); natoms_original = atom->natoms; } @@ -421,8 +394,6 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) double **f = atom->f; double **fm_long = atom->fm_long; - double **t = atom->torque; - //double **mu = atom->mu; double **sp = atom->sp; int nlocal = atom->nlocal; @@ -456,7 +427,7 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) // taking im of struct_fact x exp(i*k*ri) (for force calc.) - partial = (muk[k][i])*(expim*sfacrl_all[k] + exprl*sfacim_all[k]); + partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); ek[i][0] += partial*eg[k][0]; ek[i][1] += partial*eg[k][1]; ek[i][2] += partial*eg[k][2]; @@ -498,10 +469,6 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) const double spscale = mub2mu0 * scale; const double spscale2 = mub2mu0hbinv * scale; - //const double muscale = qqrd2e * scale; - - printf("test ek: %g %g %g \n",ek[0][0],ek[0][1],ek[0][2]); - printf("test tk: %g %g %g \n",tk[0][0],tk[0][1],tk[0][2]); for (i = 0; i < nlocal; i++) { f[i][0] += spscale * ek[i][0]; @@ -512,8 +479,8 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) if (slabflag != 2) fm_long[i][2] += spscale2 * tk[i][3]; } - printf("test f_l: %g %g %g \n",f[0][0],f[0][1],f[0][2]); - printf("test fm_l: %g %g %g \n",fm_long[0][0],fm_long[0][1],fm_long[0][2]); + //printf("test f_l: %g %g %g \n",f[0][0],f[0][1],f[0][2]); + //printf("test fm_l: %g %g %g \n",fm_long[0][0],fm_long[0][1],fm_long[0][2]); // sum global energy across Kspace vevs and add in volume-dependent term // taking the re-part of struct_fact_i x struct_fact_j @@ -573,11 +540,9 @@ void EwaldDipoleSpin::eik_dot_r() int i,k,l,m,n,ic; double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4; double sqk,clpm,slpm; - //double mux, muy, muz; double spx, spy, spz, spi; double **x = atom->x; - //double **mu = atom->mu; double **sp = atom->sp; int nlocal = atom->nlocal; @@ -607,7 +572,6 @@ void EwaldDipoleSpin::eik_dot_r() cs[-1][ic][i] = cs[1][ic][i]; sn[-1][ic][i] = -sn[1][ic][i]; spi = sp[i][ic]*sp[i][3]; - //muk[n][i] = (mu[i][ic]*unitk[ic]); muk[n][i] = (spi*unitk[ic]); cstr1 += muk[n][i]*cs[1][ic][i]; sstr1 += muk[n][i]*sn[1][ic][i]; @@ -634,7 +598,6 @@ void EwaldDipoleSpin::eik_dot_r() sn[-m][ic][i] = -sn[m][ic][i]; spi = sp[i][ic]*sp[i][3]; muk[n][i] = (spi*m*unitk[ic]); - //muk[n][i] = (mu[i][ic]*m*unitk[ic]); cstr1 += muk[n][i]*cs[m][ic][i]; sstr1 += muk[n][i]*sn[m][ic][i]; } @@ -657,8 +620,6 @@ void EwaldDipoleSpin::eik_dot_r() for (i = 0; i < nlocal; i++) { spx = sp[i][0]*sp[i][3]; spy = sp[i][1]*sp[i][3]; - //mux = mu[i][0]; - //muy = mu[i][1]; // dir 1: (k,l,0) muk[n][i] = (spx*k*unitk[0] + spy*l*unitk[1]); @@ -691,8 +652,6 @@ void EwaldDipoleSpin::eik_dot_r() for (i = 0; i < nlocal; i++) { spy = sp[i][1]*sp[i][3]; spz = sp[i][2]*sp[i][3]; - //muy = mu[i][1]; - //muz = mu[i][2]; // dir 1: (0,l,m) muk[n][i] = (spy*l*unitk[1] + spz*m*unitk[2]); @@ -723,8 +682,6 @@ void EwaldDipoleSpin::eik_dot_r() cstr2 = 0.0; sstr2 = 0.0; for (i = 0; i < nlocal; i++) { - //mux = mu[i][0]; - //muz = mu[i][2]; spx = sp[i][0]*sp[i][3]; spz = sp[i][2]*sp[i][3]; @@ -763,9 +720,6 @@ void EwaldDipoleSpin::eik_dot_r() cstr4 = 0.0; sstr4 = 0.0; for (i = 0; i < nlocal; i++) { - //mux = mu[i][0]; - //muy = mu[i][1]; - //muz = mu[i][2]; spx = sp[i][0]*sp[i][3]; spy = sp[i][1]*sp[i][3]; spz = sp[i][2]*sp[i][3]; diff --git a/src/KSPACE/pppm_dipole_spin.cpp b/src/KSPACE/pppm_dipole_spin.cpp index e66ab4903e..be38a460b2 100644 --- a/src/KSPACE/pppm_dipole_spin.cpp +++ b/src/KSPACE/pppm_dipole_spin.cpp @@ -70,8 +70,12 @@ PPPMDipoleSpin::PPPMDipoleSpin(LAMMPS *lmp, int narg, char **arg) : spinflag = 1; hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A + //mub = 5.78901e-5; // in eV/T + //mu_0 = 1.2566370614e-6; // in T.m/A + mub = 9.274e-4; // in A.Ang^2 + mu_0 = 785.15; // in eV/Ang/A^2 + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV.Ang^3 + //mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } diff --git a/src/SPIN/pair_spin_dipolar_cut.cpp b/src/SPIN/pair_spin_dipolar_cut.cpp index b2c0a1ab11..2c44b25fbf 100644 --- a/src/SPIN/pair_spin_dipolar_cut.cpp +++ b/src/SPIN/pair_spin_dipolar_cut.cpp @@ -65,8 +65,12 @@ lockfixnvespin(NULL) lattice_flag = 0; hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A + //mub = 5.78901e-5; // in eV/T + //mu_0 = 1.2566370614e-6; // in T.m/A + mub = 9.274e-4; // in A.Ang^2 + mu_0 = 785.15; // in eV/Ang/A^2 + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV.Ang^3 + //mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz diff --git a/src/SPIN/pair_spin_dipolar_long.cpp b/src/SPIN/pair_spin_dipolar_long.cpp index c1030c92d7..140b92700c 100644 --- a/src/SPIN/pair_spin_dipolar_long.cpp +++ b/src/SPIN/pair_spin_dipolar_long.cpp @@ -60,9 +60,12 @@ lockfixnvespin(NULL) lattice_flag = 0; hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A - mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV + //mub = 5.78901e-5; // in eV/T + //mu_0 = 1.2566370614e-6; // in T.m/A + mub = 9.274e-4; // in A.Ang^2 + mu_0 = 785.15; // in eV/Ang/A^2 + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV.Ang^3 + //mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz } diff --git a/src/SPIN/pair_spin_dipolar_long_qsymp.cpp b/src/SPIN/pair_spin_dipolar_long_qsymp.cpp index 63876ba97a..4b07b540bc 100644 --- a/src/SPIN/pair_spin_dipolar_long_qsymp.cpp +++ b/src/SPIN/pair_spin_dipolar_long_qsymp.cpp @@ -60,8 +60,12 @@ lockfixnvespin(NULL) lattice_flag = 0; hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - mub = 5.78901e-5; // in eV/T - mu_0 = 1.2566370614e-6; // in T.m/A + //mub = 5.78901e-5; // in eV/T + //mu_0 = 1.2566370614e-6; // in T.m/A + mub = 9.274e-4; // in A.Ang^2 + mu_0 = 785.15; // in eV/Ang/A^2 + mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV.Ang^3 + //mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz -- GitLab From d5fe8857cc75dd1c140883f7005c9f669c084a82 Mon Sep 17 00:00:00 2001 From: julient31 Date: Fri, 5 Oct 2018 14:01:29 -0600 Subject: [PATCH 0052/1243] Commit JT 100518 - correction torque ewald_dipole - idem ewald_dipole_spin to check --- src/KSPACE/ewald_dipole.cpp | 8 ++++---- src/KSPACE/ewald_dipole_spin.cpp | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index 5579ba3840..f2124deb4f 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -458,7 +458,7 @@ void EwaldDipole::compute(int eflag, int vflag) // compute field for torque calculation - partial2 = exprl*sfacrl_all[k] - expim*sfacim_all[k]; + partial2 = exprl*sfacrl_all[k] + expim*sfacim_all[k]; tk[i][0] += partial2*eg[k][0]; tk[i][1] += partial2*eg[k][1]; tk[i][2] += partial2*eg[k][2]; @@ -493,9 +493,9 @@ void EwaldDipole::compute(int eflag, int vflag) f[i][0] += muscale * ek[i][0]; f[i][1] += muscale * ek[i][1]; if (slabflag != 2) f[i][2] += muscale * ek[i][2]; - t[i][0] += -mu[i][1]*tk[i][2] + mu[i][2]*tk[i][1]; - t[i][1] += -mu[i][2]*tk[i][0] + mu[i][0]*tk[i][2]; - if (slabflag != 2) t[i][2] += -mu[i][0]*tk[i][1] + mu[i][1]*tk[i][0]; + t[i][0] -= muscale * (mu[i][1]*tk[i][2] - mu[i][2]*tk[i][1]); + t[i][1] -= muscale * (mu[i][2]*tk[i][0] - mu[i][0]*tk[i][2]); + if (slabflag != 2) t[i][2] -= muscale * (mu[i][0]*tk[i][1] - mu[i][1]*tk[i][0]); } // sum global energy across Kspace vevs and add in volume-dependent term diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp index df1acb337d..3554f66f36 100644 --- a/src/KSPACE/ewald_dipole_spin.cpp +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -434,7 +434,7 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) // compute field for torque calculation - partial2 = exprl*sfacrl_all[k] - expim*sfacim_all[k]; + partial2 = exprl*sfacrl_all[k] + expim*sfacim_all[k]; tk[i][0] += partial2*eg[k][0]; tk[i][1] += partial2*eg[k][1]; tk[i][2] += partial2*eg[k][2]; @@ -478,9 +478,6 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) fm_long[i][1] += spscale2 * tk[i][1]; if (slabflag != 2) fm_long[i][2] += spscale2 * tk[i][3]; } - - //printf("test f_l: %g %g %g \n",f[0][0],f[0][1],f[0][2]); - //printf("test fm_l: %g %g %g \n",fm_long[0][0],fm_long[0][1],fm_long[0][2]); // sum global energy across Kspace vevs and add in volume-dependent term // taking the re-part of struct_fact_i x struct_fact_j -- GitLab From 762a4b97acce6917fd8335b2593ed66396c7a68f Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Tue, 30 Oct 2018 21:54:59 -0500 Subject: [PATCH 0053/1243] Revert "pair_kim - no need to comm vatom() values" This reverts commit 9962f941e674e3dd18e76dec4ba5017e98832513. --- src/KIM/pair_kim.cpp | 86 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index eca3f6f1d7..1bd21884eb 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -486,8 +486,8 @@ void PairKIM::init_style() } - // make sure comm_reverse expects (at most) 3 values when newton is off - if (!lmps_using_newton) comm_reverse_off = 3; + // make sure comm_reverse expects (at most) 9 values when newton is off + if (!lmps_using_newton) comm_reverse_off = 9; // request full neighbor for (int i = 0; i < kim_number_of_neighbor_lists; ++i) @@ -553,7 +553,9 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) m = 0; last = first + n; - if (kim_model_support_for_forces != notSupported) + if ((kim_model_support_for_forces != notSupported) && + ((vflag_atom == 0) || + (kim_model_support_for_particleVirial == notSupported))) { for (i = first; i < last; i++) { @@ -563,6 +565,42 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) } return m; } + else if ((kim_model_support_for_forces != notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) + { + double *va=&(vatom[0][0]); + for (i = first; i < last; i++) + { + buf[m++] = fp[3*i+0]; + buf[m++] = fp[3*i+1]; + buf[m++] = fp[3*i+2]; + + buf[m++] = va[6*i+0]; + buf[m++] = va[6*i+1]; + buf[m++] = va[6*i+2]; + buf[m++] = va[6*i+3]; + buf[m++] = va[6*i+4]; + buf[m++] = va[6*i+5]; + } + return m; + } + else if ((kim_model_support_for_forces == notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) + { + double *va=&(vatom[0][0]); + for (i = first; i < last; i++) + { + buf[m++] = va[6*i+0]; + buf[m++] = va[6*i+1]; + buf[m++] = va[6*i+2]; + buf[m++] = va[6*i+3]; + buf[m++] = va[6*i+4]; + buf[m++] = va[6*i+5]; + } + return m; + } else return 0; } @@ -578,7 +616,9 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) fp = &(atom->f[0][0]); m = 0; - if (kim_model_support_for_forces != notSupported) + if ((kim_model_support_for_forces != notSupported) && + ((vflag_atom == 0) || + (kim_model_support_for_particleVirial == notSupported))) { for (i = 0; i < n; i++) { @@ -588,6 +628,42 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) fp[3*j+2]+= buf[m++]; } } + else if ((kim_model_support_for_forces != notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) + { + double *va=&(vatom[0][0]); + for (i = 0; i < n; i++) + { + j = list[i]; + fp[3*j+0]+= buf[m++]; + fp[3*j+1]+= buf[m++]; + fp[3*j+2]+= buf[m++]; + + va[j*6+0]+=buf[m++]; + va[j*6+1]+=buf[m++]; + va[j*6+2]+=buf[m++]; + va[j*6+3]+=buf[m++]; + va[j*6+4]+=buf[m++]; + va[j*6+5]+=buf[m++]; + } + } + else if ((kim_model_support_for_forces == notSupported) && + (vflag_atom == 1) && + (kim_model_support_for_particleVirial != notSupported)) + { + double *va=&(vatom[0][0]); + for (i = 0; i < n; i++) + { + j = list[i]; + va[j*6+0]+=buf[m++]; + va[j*6+1]+=buf[m++]; + va[j*6+2]+=buf[m++]; + va[j*6+3]+=buf[m++]; + va[j*6+4]+=buf[m++]; + va[j*6+5]+=buf[m++]; + } + } else ;// do nothing @@ -809,7 +885,7 @@ void PairKIM::set_argument_pointers() } else if (kim_model_support_for_particleVirial != notSupported) { - kimerror = kimerror || pargs->SetArgumentPointer(partialParticleVirial, + kimerror = kimerror || pargs->SetArgumentPointer(partialParticleEnergy, &(vatom[0][0])); } -- GitLab From 8dd3bce7c5ae65d56a9c1281d55fa94a683a2e47 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Thu, 1 Nov 2018 19:33:52 -0500 Subject: [PATCH 0054/1243] Update to C KIM_API bindings --- src/KIM/pair_kim.cpp | 324 ++++++++++++++++++++++++------------------- src/KIM/pair_kim.h | 28 ++-- 2 files changed, 197 insertions(+), 155 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 1bd21884eb..072c3a6296 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -50,7 +50,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package + Designed for use with the kim-api-v2.0.0-beta.2 (and newer) package ------------------------------------------------------------------------- */ #include @@ -82,17 +82,17 @@ PairKIM::PairKIM(LAMMPS *lmp) : lmps_unique_elements(NULL), lmps_num_unique_elements(0), lmps_units(METAL), - lengthUnit(KIM::LENGTH_UNIT::unused), - energyUnit(KIM::ENERGY_UNIT::unused), - chargeUnit(KIM::CHARGE_UNIT::unused), - temperatureUnit(KIM::TEMPERATURE_UNIT::unused), - timeUnit(KIM::TIME_UNIT::unused), + lengthUnit(KIM_LENGTH_UNIT_unused), + energyUnit(KIM_ENERGY_UNIT_unused), + chargeUnit(KIM_CHARGE_UNIT_unused), + temperatureUnit(KIM_TEMPERATURE_UNIT_unused), + timeUnit(KIM_TIME_UNIT_unused), pkim(NULL), pargs(NULL), - kim_model_support_for_energy(KIM::SUPPORT_STATUS::notSupported), - kim_model_support_for_forces(KIM::SUPPORT_STATUS::notSupported), - kim_model_support_for_particleEnergy(KIM::SUPPORT_STATUS::notSupported), - kim_model_support_for_particleVirial(KIM::SUPPORT_STATUS::notSupported), + kim_model_support_for_energy(KIM_SUPPORT_STATUS_notSupported), + kim_model_support_for_forces(KIM_SUPPORT_STATUS_notSupported), + kim_model_support_for_particleEnergy(KIM_SUPPORT_STATUS_notSupported), + kim_model_support_for_particleVirial(KIM_SUPPORT_STATUS_notSupported), lmps_local_tot_num_atoms(0), kim_global_influence_distance(0.0), kim_number_of_neighbor_lists(0), @@ -205,13 +205,14 @@ void PairKIM::compute(int eflag , int vflag) lmps_maxalloc = atom->nmax; memory->create(kim_particleSpecies,lmps_maxalloc, "pair:kim_particleSpecies"); - int kimerror = pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::particleSpeciesCodes, + int kimerror = KIM_ComputeArguments_SetArgumentPointerInteger(pargs, + KIM_COMPUTE_ARGUMENT_NAME_particleSpeciesCodes, kim_particleSpecies); memory->create(kim_particleContributing,lmps_maxalloc, "pair:kim_particleContributing"); - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::particleContributing, + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerInteger( + pargs, + KIM_COMPUTE_ARGUMENT_NAME_particleContributing, kim_particleContributing); if (kimerror) error->all( @@ -240,7 +241,7 @@ void PairKIM::compute(int eflag , int vflag) lmps_local_tot_num_atoms = (int) nall; // compute via KIM model - kimerror = pkim->Compute(pargs); + kimerror = KIM_Model_Compute(pkim, pargs); if (kimerror) error->all(FLERR,"KIM Compute returned error"); // compute virial before reverse comm! @@ -256,8 +257,9 @@ void PairKIM::compute(int eflag , int vflag) } if ((vflag_atom) && - (kim_model_support_for_particleVirial != - KIM::SUPPORT_STATUS::notSupported)) + KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported) + ) { // flip sign and order of virial if KIM is computing it double tmp; for (int i = 0; i < nall; ++i) @@ -438,8 +440,9 @@ void PairKIM::coeff(int narg, char **arg) int kimerror; int supported; int code; - kimerror = pkim->GetSpeciesSupportAndCode( - KIM::SpeciesName(lmps_unique_elements[i]), + kimerror = KIM_Model_GetSpeciesSupportAndCode( + pkim, + KIM_SpeciesName_FromString(lmps_unique_elements[i]), &supported, &code); if (supported) @@ -545,17 +548,18 @@ double PairKIM::init_one(int i, int j) int PairKIM::pack_reverse_comm(int n, int first, double *buf) { - using namespace KIM::SUPPORT_STATUS; - int i,m,last; double *fp; fp = &(atom->f[0][0]); m = 0; last = first + n; - if ((kim_model_support_for_forces != notSupported) && + if (KIM_SupportStatus_NotEqual(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported) + && ((vflag_atom == 0) || - (kim_model_support_for_particleVirial == notSupported))) + KIM_SupportStatus_Equal(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported))) { for (i = first; i < last; i++) { @@ -565,9 +569,11 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) } return m; } - else if ((kim_model_support_for_forces != notSupported) && + else if (KIM_SupportStatus_NotEqual(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported) && (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) + KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported)) { double *va=&(vatom[0][0]); for (i = first; i < last; i++) @@ -585,9 +591,12 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) } return m; } - else if ((kim_model_support_for_forces == notSupported) && + else if (KIM_SupportStatus_Equal(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported) + && (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) + KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported)) { double *va=&(vatom[0][0]); for (i = first; i < last; i++) @@ -609,16 +618,17 @@ int PairKIM::pack_reverse_comm(int n, int first, double *buf) void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) { - using namespace KIM::SUPPORT_STATUS; - int i,j,m; double *fp; fp = &(atom->f[0][0]); m = 0; - if ((kim_model_support_for_forces != notSupported) && + if (KIM_SupportStatus_NotEqual(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported) + && ((vflag_atom == 0) || - (kim_model_support_for_particleVirial == notSupported))) + KIM_SupportStatus_Equal(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported))) { for (i = 0; i < n; i++) { @@ -628,9 +638,12 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) fp[3*j+2]+= buf[m++]; } } - else if ((kim_model_support_for_forces != notSupported) && + else if (KIM_SupportStatus_NotEqual(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported) + && (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) + KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported)) { double *va=&(vatom[0][0]); for (i = 0; i < n; i++) @@ -648,9 +661,12 @@ void PairKIM::unpack_reverse_comm(int n, int *list, double *buf) va[j*6+5]+=buf[m++]; } } - else if ((kim_model_support_for_forces == notSupported) && + else if (KIM_SupportStatus_Equal(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported) + && (vflag_atom == 1) && - (kim_model_support_for_particleVirial != notSupported)) + KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported)) { double *va=&(vatom[0][0]); for (i = 0; i < n; i++) @@ -741,11 +757,11 @@ void PairKIM::kim_free() if (kim_init_ok) { - int kimerror = pkim->ComputeArgumentsDestroy(&pargs); + int kimerror = KIM_Model_ComputeArgumentsDestroy(pkim, &pargs); if (kimerror) error->all(FLERR,"Unable to destroy Compute Arguments Object"); - KIM::Model::Destroy(&pkim); + KIM_Model_Destroy(&pkim); } kim_init_ok = false; @@ -760,8 +776,8 @@ void PairKIM::kim_init() // initialize KIM model int requestedUnitsAccepted; - kimerror = KIM::Model::Create( - KIM::NUMBERING::zeroBased, + kimerror = KIM_Model_Create( + KIM_NUMBERING_zeroBased, lengthUnit, energyUnit, chargeUnit, temperatureUnit, timeUnit, kim_modelname, &requestedUnitsAccepted, @@ -773,10 +789,10 @@ void PairKIM::kim_init() error->all(FLERR,"KIM Model did not accept the requested unit system"); } - kimerror = pkim->ComputeArgumentsCreate(&pargs); + kimerror = KIM_Model_ComputeArgumentsCreate(pkim, &pargs); if (kimerror) { - KIM::Model::Destroy(&pkim); + KIM_Model_Destroy(&pkim); error->all(FLERR,"KIM ComputeArgumentsCreate failed"); } else @@ -788,8 +804,9 @@ void PairKIM::kim_init() // determine KIM Model capabilities (used in this function below) set_kim_model_has_flags(); - pkim->GetInfluenceDistance(&kim_global_influence_distance); - pkim->GetNeighborListPointers( + KIM_Model_GetInfluenceDistance(pkim, &kim_global_influence_distance); + KIM_Model_GetNeighborListPointers( + pkim, &kim_number_of_neighbor_lists, &kim_cutoff_values, &modelWillNotRequestNeighborsOfNoncontributingParticles); @@ -800,18 +817,19 @@ void PairKIM::kim_init() } neighborLists = new NeighList*[kim_number_of_neighbor_lists]; - kimerror = pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::numberOfParticles, + kimerror = KIM_ComputeArguments_SetArgumentPointerInteger(pargs, + KIM_COMPUTE_ARGUMENT_NAME_numberOfParticles, &lmps_local_tot_num_atoms); - if (kim_model_support_for_energy != KIM::SUPPORT_STATUS::notSupported) - kimerror = kimerror || pargs->SetArgumentPointer( - KIM::COMPUTE_ARGUMENT_NAME::partialEnergy, + if (KIM_SupportStatus_NotEqual(kim_model_support_for_energy, + KIM_SUPPORT_STATUS_notSupported)) + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble(pargs, + KIM_COMPUTE_ARGUMENT_NAME_partialEnergy, &(eng_vdwl)); - kimerror = pargs->SetCallbackPointer( - KIM::COMPUTE_CALLBACK_NAME::GetNeighborList, - KIM::LANGUAGE_NAME::cpp, - reinterpret_cast(get_neigh), + kimerror = KIM_ComputeArguments_SetCallbackPointer(pargs, + KIM_COMPUTE_CALLBACK_NAME_GetNeighborList, + KIM_LANGUAGE_NAME_cpp, + reinterpret_cast(get_neigh), reinterpret_cast(this)); if (kimerror) @@ -824,14 +842,14 @@ void PairKIM::kim_init() void PairKIM::set_argument_pointers() { - using namespace KIM::COMPUTE_ARGUMENT_NAME; - using namespace KIM::SUPPORT_STATUS; - int kimerror; - kimerror = pargs->SetArgumentPointer(coordinates, &(atom->x[0][0])); + kimerror = KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, KIM_COMPUTE_ARGUMENT_NAME_coordinates, &(atom->x[0][0])); // Set KIM pointer appropriately for particalEnergy - if ((kim_model_support_for_particleEnergy == required) && (eflag_atom != 1)) + if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy, + KIM_SUPPORT_STATUS_required) + && (eflag_atom != 1)) { // reallocate per-atom energy array if necessary if (atom->nmax > maxeatom) @@ -841,33 +859,41 @@ void PairKIM::set_argument_pointers() memory->create(eatom,comm->nthreads*maxeatom,"pair:eatom"); } } - if ((kim_model_support_for_particleEnergy == optional) && (eflag_atom != 1)) + if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy, + KIM_SUPPORT_STATUS_optional) + && (eflag_atom != 1)) { - kimerror = kimerror || pargs->SetArgumentPointer( - partialParticleEnergy, + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, + KIM_COMPUTE_ARGUMENT_NAME_partialParticleEnergy, reinterpret_cast(NULL)); } - else if (kim_model_support_for_particleEnergy != notSupported) + else if (KIM_SupportStatus_NotEqual(kim_model_support_for_particleEnergy, + KIM_SUPPORT_STATUS_notSupported)) { - kimerror = kimerror || pargs->SetArgumentPointer(partialParticleEnergy, - eatom); + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, KIM_COMPUTE_ARGUMENT_NAME_partialParticleEnergy, eatom); } // Set KIM pointer appropriately for forces - if (kim_model_support_for_forces == notSupported) + if (KIM_SupportStatus_Equal(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported)) { - kimerror = kimerror || pargs->SetArgumentPointer( - partialForces, + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, + KIM_COMPUTE_ARGUMENT_NAME_partialForces, reinterpret_cast(NULL)); } else { - kimerror = kimerror || pargs->SetArgumentPointer(partialForces, - &(atom->f[0][0])); + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, KIM_COMPUTE_ARGUMENT_NAME_partialForces, &(atom->f[0][0])); } // Set KIM pointer appropriately for particleVirial - if ((kim_model_support_for_particleVirial == required) && (vflag_atom != 1)) + if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_required) + && (vflag_atom != 1)) { // reallocate per-atom virial array if necessary if (atom->nmax > maxeatom) @@ -877,16 +903,20 @@ void PairKIM::set_argument_pointers() memory->create(vatom,comm->nthreads*maxvatom,6,"pair:vatom"); } } - if ((kim_model_support_for_particleVirial == optional) && (vflag_atom != 1)) + if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_optional) + && (vflag_atom != 1)) { - kimerror = kimerror || pargs->SetArgumentPointer( - partialParticleVirial, + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, + KIM_COMPUTE_ARGUMENT_NAME_partialParticleVirial, reinterpret_cast(NULL)); } - else if (kim_model_support_for_particleVirial != notSupported) + else if (KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported)) { - kimerror = kimerror || pargs->SetArgumentPointer(partialParticleEnergy, - &(vatom[0][0])); + kimerror = kimerror || KIM_ComputeArguments_SetArgumentPointerDouble( + pargs, KIM_COMPUTE_ARGUMENT_NAME_partialParticleEnergy, &(vatom[0][0])); } if (kimerror) @@ -913,39 +943,39 @@ void PairKIM::set_lmps_flags() // determine unit system and set lmps_units flag if ((strcmp(update->unit_style,"real")==0)) { lmps_units = REAL; - lengthUnit = KIM::LENGTH_UNIT::A; - energyUnit = KIM::ENERGY_UNIT::kcal_mol; - chargeUnit = KIM::CHARGE_UNIT::e; - temperatureUnit = KIM::TEMPERATURE_UNIT::K; - timeUnit = KIM::TIME_UNIT::fs; + lengthUnit = KIM_LENGTH_UNIT_A; + energyUnit = KIM_ENERGY_UNIT_kcal_mol; + chargeUnit = KIM_CHARGE_UNIT_e; + temperatureUnit = KIM_TEMPERATURE_UNIT_K; + timeUnit = KIM_TIME_UNIT_fs; } else if ((strcmp(update->unit_style,"metal")==0)) { lmps_units = METAL; - lengthUnit = KIM::LENGTH_UNIT::A; - energyUnit = KIM::ENERGY_UNIT::eV; - chargeUnit = KIM::CHARGE_UNIT::e; - temperatureUnit = KIM::TEMPERATURE_UNIT::K; - timeUnit = KIM::TIME_UNIT::ps; + lengthUnit = KIM_LENGTH_UNIT_A; + energyUnit = KIM_ENERGY_UNIT_eV; + chargeUnit = KIM_CHARGE_UNIT_e; + temperatureUnit = KIM_TEMPERATURE_UNIT_K; + timeUnit = KIM_TIME_UNIT_ps; } else if ((strcmp(update->unit_style,"si")==0)) { lmps_units = SI; - lengthUnit = KIM::LENGTH_UNIT::m; - energyUnit = KIM::ENERGY_UNIT::J; - chargeUnit = KIM::CHARGE_UNIT::C; - temperatureUnit = KIM::TEMPERATURE_UNIT::K; - timeUnit = KIM::TIME_UNIT::s; + lengthUnit = KIM_LENGTH_UNIT_m; + energyUnit = KIM_ENERGY_UNIT_J; + chargeUnit = KIM_CHARGE_UNIT_C; + temperatureUnit = KIM_TEMPERATURE_UNIT_K; + timeUnit = KIM_TIME_UNIT_s; } else if ((strcmp(update->unit_style,"cgs")==0)) { lmps_units = CGS; - lengthUnit = KIM::LENGTH_UNIT::cm; - energyUnit = KIM::ENERGY_UNIT::erg; - chargeUnit = KIM::CHARGE_UNIT::statC; - temperatureUnit = KIM::TEMPERATURE_UNIT::K; - timeUnit = KIM::TIME_UNIT::s; + lengthUnit = KIM_LENGTH_UNIT_cm; + energyUnit = KIM_ENERGY_UNIT_erg; + chargeUnit = KIM_CHARGE_UNIT_statC; + temperatureUnit = KIM_TEMPERATURE_UNIT_K; + timeUnit = KIM_TIME_UNIT_s; } else if ((strcmp(update->unit_style,"electron")==0)) { lmps_units = ELECTRON; - lengthUnit = KIM::LENGTH_UNIT::Bohr; - energyUnit = KIM::ENERGY_UNIT::Hartree; - chargeUnit = KIM::CHARGE_UNIT::e; - temperatureUnit = KIM::TEMPERATURE_UNIT::K; - timeUnit = KIM::TIME_UNIT::fs; + lengthUnit = KIM_LENGTH_UNIT_Bohr; + energyUnit = KIM_ENERGY_UNIT_Hartree; + chargeUnit = KIM_CHARGE_UNIT_e; + temperatureUnit = KIM_TEMPERATURE_UNIT_K; + timeUnit = KIM_TIME_UNIT_fs; } else if ((strcmp(update->unit_style,"lj")==0)) { error->all(FLERR,"LAMMPS unit_style lj not supported by KIM models"); } else { @@ -959,75 +989,85 @@ void PairKIM::set_lmps_flags() void PairKIM::set_kim_model_has_flags() { - { // BEGIN enclosing scope for using directives - using namespace KIM::COMPUTE_ARGUMENT_NAME; - using namespace KIM::SUPPORT_STATUS; - int numberOfComputeArgumentNames; - GetNumberOfComputeArgumentNames(&numberOfComputeArgumentNames); + KIM_COMPUTE_ARGUMENT_NAME_GetNumberOfComputeArgumentNames( + &numberOfComputeArgumentNames); for (int i = 0; i < numberOfComputeArgumentNames; ++i) { - KIM::ComputeArgumentName computeArgumentName; - int kimerror = GetComputeArgumentName(i, &computeArgumentName); - KIM::SupportStatus supportStatus; - kimerror = pargs->GetArgumentSupportStatus(computeArgumentName, - &supportStatus); - - if (computeArgumentName == partialEnergy) + KIM_ComputeArgumentName computeArgumentName; + int kimerror = KIM_COMPUTE_ARGUMENT_NAME_GetComputeArgumentName( + i, &computeArgumentName); + KIM_SupportStatus supportStatus; + kimerror = KIM_ComputeArguments_GetArgumentSupportStatus( + pargs, computeArgumentName, &supportStatus); + + if (KIM_ComputeArgumentName_Equal(computeArgumentName, + KIM_COMPUTE_ARGUMENT_NAME_partialEnergy) + ) kim_model_support_for_energy = supportStatus; - else if (computeArgumentName == partialForces) + else if (KIM_ComputeArgumentName_Equal( + computeArgumentName, KIM_COMPUTE_ARGUMENT_NAME_partialForces) + ) kim_model_support_for_forces = supportStatus; - else if (computeArgumentName == partialParticleEnergy) + else if + (KIM_ComputeArgumentName_Equal( + computeArgumentName, + KIM_COMPUTE_ARGUMENT_NAME_partialParticleEnergy)\ + ) kim_model_support_for_particleEnergy = supportStatus; - else if (computeArgumentName == partialParticleVirial) + else if + (KIM_ComputeArgumentName_Equal( + computeArgumentName, + KIM_COMPUTE_ARGUMENT_NAME_partialParticleVirial) + ) kim_model_support_for_particleVirial = supportStatus; - else if (supportStatus == required) + else if (KIM_SupportStatus_Equal(supportStatus, KIM_SUPPORT_STATUS_required) + ) { std::stringstream msg; msg << "KIM Model requires unsupported compute argument: " - << computeArgumentName.String(); + << KIM_ComputeArgumentName_ToString(computeArgumentName); error->all(FLERR, msg.str().c_str()); } } - if (kim_model_support_for_energy == notSupported) + if (KIM_SupportStatus_Equal(kim_model_support_for_energy, + KIM_SUPPORT_STATUS_notSupported)) error->warning(FLERR,"KIM Model does not provide `partialEnergy'; " "Potential energy will be zero"); - if (kim_model_support_for_forces == notSupported) + if (KIM_SupportStatus_Equal(kim_model_support_for_forces, + KIM_SUPPORT_STATUS_notSupported)) error->warning(FLERR,"KIM Model does not provide `partialForce'; " "Forces will be zero"); - if (kim_model_support_for_particleEnergy == notSupported) + if (KIM_SupportStatus_Equal(kim_model_support_for_particleEnergy, + KIM_SUPPORT_STATUS_notSupported)) error->warning(FLERR,"KIM Model does not provide `partialParticleEnergy'; " "energy per atom will be zero"); - if (kim_model_support_for_particleVirial == notSupported) + if (KIM_SupportStatus_Equal(kim_model_support_for_particleVirial, + KIM_SUPPORT_STATUS_notSupported)) error->warning(FLERR,"KIM Model does not provide `partialParticleVirial'; " "virial per atom will be zero"); - } // END enclosing scope for using directives - - - { // BEGIN enclosing scope for using directives - using namespace KIM::COMPUTE_CALLBACK_NAME; - using namespace KIM::SUPPORT_STATUS; - int numberOfComputeCallbackNames; - GetNumberOfComputeCallbackNames(&numberOfComputeCallbackNames); - for (int i = 0; i < numberOfComputeCallbackNames; ++i) + int numberOfComputeCallbackNames; + KIM_COMPUTE_CALLBACK_NAME_GetNumberOfComputeCallbackNames( + &numberOfComputeCallbackNames); + for (int i = 0; i < numberOfComputeCallbackNames; ++i) + { + KIM_ComputeCallbackName computeCallbackName; + int kimerror = KIM_COMPUTE_CALLBACK_NAME_GetComputeCallbackName( + i, &computeCallbackName); + KIM_SupportStatus supportStatus; + kimerror = KIM_ComputeArguments_GetCallbackSupportStatus( + pargs, computeCallbackName, &supportStatus); + + if (KIM_SupportStatus_Equal(supportStatus, KIM_SUPPORT_STATUS_required)) { - KIM::ComputeCallbackName computeCallbackName; - int kimerror = GetComputeCallbackName(i, &computeCallbackName); - KIM::SupportStatus supportStatus; - kimerror = pargs->GetCallbackSupportStatus(computeCallbackName, - &supportStatus); - - if (supportStatus == required) - { - error->all(FLERR,"KIM Model requires unsupported compute callback"); - } + error->all(FLERR,"KIM Model requires unsupported compute callback"); } - } // END enclosing scope for using directives + } - return; + return; } diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index eef6e0345b..1b8051ea1e 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -50,7 +50,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package + Designed for use with the kim-api-v2.0.0-beta.2 (and newer) package ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS @@ -65,7 +65,9 @@ PairStyle(kim,PairKIM) // includes from KIM & LAMMPS class KIM_API_model; #include "pair.h" -#include "KIM_SimulatorHeaders.hpp" +extern "C" { +#include "KIM_SimulatorHeaders.h" +} #include @@ -113,20 +115,20 @@ namespace LAMMPS_NS { bool lmps_using_molecular; enum unit_sys {REAL, METAL, SI, CGS, ELECTRON}; unit_sys lmps_units; - KIM::LengthUnit lengthUnit; - KIM::EnergyUnit energyUnit; - KIM::ChargeUnit chargeUnit; - KIM::TemperatureUnit temperatureUnit; - KIM::TimeUnit timeUnit; + KIM_LengthUnit lengthUnit; + KIM_EnergyUnit energyUnit; + KIM_ChargeUnit chargeUnit; + KIM_TemperatureUnit temperatureUnit; + KIM_TimeUnit timeUnit; - KIM::Model * pkim; - KIM::ComputeArguments * pargs; + KIM_Model * pkim; + KIM_ComputeArguments * pargs; // values set in set_kim_model_has_flags(), called by kim_init() - KIM::SupportStatus kim_model_support_for_energy; - KIM::SupportStatus kim_model_support_for_forces; - KIM::SupportStatus kim_model_support_for_particleEnergy; - KIM::SupportStatus kim_model_support_for_particleVirial; + KIM_SupportStatus kim_model_support_for_energy; + KIM_SupportStatus kim_model_support_for_forces; + KIM_SupportStatus kim_model_support_for_particleEnergy; + KIM_SupportStatus kim_model_support_for_particleVirial; // values set in kim_init() bool kim_init_ok; -- GitLab From 9ed6f2fc4395ec962e6c9c849f71f3f329664e56 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sun, 4 Nov 2018 20:10:04 -0600 Subject: [PATCH 0055/1243] Adjust lib/kim install script and settings --- lib/kim/Install.py | 55 ++++++++++++++++------------------------- lib/kim/Makefile.lammps | 17 +++++++++++-- lib/kim/README | 30 +++++++++------------- 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/lib/kim/Install.py b/lib/kim/Install.py index da0dcd2789..815827b645 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -9,24 +9,24 @@ import sys,os,re,subprocess # help message help = """ -Syntax from src dir: make lib-kim args="-b -v version -a kim-name" +Syntax from src dir: make lib-kim args="-b -v version -a kim-name" or: make lib-kim args="-b -a everything" or: make lib-kim args="-n -a kim-name" - or: make lib-kim args="-p /usr/local/lib/kim-api-v2 -a kim-name" -Syntax from lib dir: python Install.py -b -v version -a kim-name + or: make lib-kim args="-p /home/bob/kim -a kim-name" +Syntax from lib dir: python Install.py -b -v version -a kim-name or: python Install.py -b -a everything or: python Install.py -n -a kim-name - or: python Install.py -p /usr/local/lib/kim-api-v2 -a kim-name + or: python Install.py -p /home/bob/kim -a kim-name specify one or more options, order does not matter -v = version of KIM API library to use - default = kim-api-v2.0.0-beta.1 (current as of July 2018) + default = kim-api-v2.0.0-beta.2 (current as of November 2018) -b = download and build base KIM API library with example Models this will delete any previous installation in the current folder -n = do NOT download and build base KIM API library. Use an existing installation - -p = specify location of KIM API installation (implies -n) + -p = specify install prefix of KIM API installation (implies -n) -a = add single KIM model or model driver with kim-name to existing KIM API lib (see example below). If kim-name = everything, then rebuild KIM API library with @@ -109,7 +109,7 @@ nargs = len(args) if nargs == 0: error() thisdir = os.environ['PWD'] -version = "kim-api-v2.0.0-beta.1" +version = "kim-api-v2.0.0-beta.2" buildflag = False everythingflag = False @@ -160,13 +160,10 @@ if pathflag: error() # configure LAMMPS to use existing kim-api installation - with open("%s/Makefile.KIM_DIR" % thisdir, 'w') as mkfile: - mkfile.write("KIM_INSTALL_DIR=%s\n\n" % kimdir) - mkfile.write(".DUMMY: print_dir\n\n") - mkfile.write("print_dir:\n") - mkfile.write(" @printf $(KIM_INSTALL_DIR)\n") + with open("%s/kim-prefix.txt" % thisdir, 'w') as pffile: + pffile.write("%s" % kimdir) - print("Created %s/Makefile.KIM_DIR\n using %s" % (thisdir,kimdir)) + print("Created %s/kim-prefix.txt\n using %s" % (thisdir,kimdir)) else: kimdir = os.path.join(os.path.abspath(thisdir), "installed-" + version) @@ -182,13 +179,10 @@ if buildflag: # configure LAMMPS to use kim-api to be installed - with open("%s/Makefile.KIM_DIR" % thisdir, 'w') as mkfile: - mkfile.write("KIM_INSTALL_DIR=%s\n\n" % kimdir) - mkfile.write(".DUMMY: print_dir\n\n") - mkfile.write("print_dir:\n") - mkfile.write(" @printf $(KIM_INSTALL_DIR)\n") + with open("%s/kim-prefix.txt" % thisdir, 'w') as pffile: + pffile.write("%s" % kimdir) - print("Created %s/Makefile.KIM_DIR\n using %s" % (thisdir,kimdir)) + print("Created %s/kim-prefix.txt\n using %s" % (thisdir,kimdir)) # download entire kim-api tarball @@ -201,32 +195,25 @@ if buildflag: # configure kim-api print("Configuring kim-api ...") - cmd = 'cd "%s/%s"; ./configure --prefix="%s"' % (thisdir,version,kimdir) - subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) + cmd = 'cd "%s/%s" && mkdir build && cd build && cmake .. -DCMAKE_INSTALL_PREFIX="%s" -DCMAKE_BUILD_TYPE=Release' % (thisdir,version,kimdir) + txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) + if verboseflag: print(txt.decode("UTF-8")) # build kim-api print("Building kim-api ...") - cmd = 'cd "%s/%s"; make' % (thisdir,version) + cmd = 'cd "%s/%s/build" && make' % (thisdir,version) txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) if verboseflag: print(txt.decode("UTF-8")) # install kim-api print("Installing kim-api ...") - cmd = 'cd "%s/%s"; make install' % (thisdir,version) + cmd = 'cd "%s/%s/build" && make install' % (thisdir,version) txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) if verboseflag: print(txt.decode("UTF-8")) # remove source files - print("Building and installing example Models") - cmd = 'cd "%s/%s/examples"; make model-drivers-all-system' % (thisdir,version) - txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) - if verboseflag: print (txt.decode("UTF-8")) - cmd = 'cd "%s/%s/examples"; make models-all-system' % (thisdir,version) - txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) - if verboseflag: print (txt.decode("UTF-8")) - print("Removing kim-api source and build files ...") cmd = 'cd "%s"; rm -rf %s; rm -rf %s.txz' % (thisdir,version,version) subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) @@ -241,9 +228,9 @@ if buildflag: # add single OpenKIM model if addflag: - makefile_path = os.path.join(thisdir, "Makefile.KIM_DIR") - if os.path.isfile(makefile_path): - cmd = 'make --no-print-directory -f %s print_dir' % makefile_path + pf_path = os.path.join(thisdir, "kim-prefix.txt") + if os.path.isfile(pf_path): + cmd = 'cat %s' % pf_path kimdir = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) if not os.path.isdir(kimdir): diff --git a/lib/kim/Makefile.lammps b/lib/kim/Makefile.lammps index 1c2ab417d5..7c9fc7c5f7 100644 --- a/lib/kim/Makefile.lammps +++ b/lib/kim/Makefile.lammps @@ -13,5 +13,18 @@ # Settings that the LAMMPS build will import when this package is installed -kim_SYSINC = $(shell pkg-config --cflags libkim-api-v2) -kim_SYSLIB = $(shell pkg-config --libs libkim-api-v2) + +ifeq ($(strip $(shell pkg-config --version)),) + $(error 'pkg-config' not found, but is required to configure the KIM API) +endif + +kim_PREFIX := $(shell cat ../../lib/kim/kim-prefix.txt 2> /dev/null) +kim_PREFIX := $(if $(kim_PREFIX),$(kim_PREFIX)/lib/pkgconfig,) +kim_PREFIX := $(if $(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX):$(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX)) + +kim_SYSINC := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --cflags libkim-api-v2 2> /dev/null) +kim_SYSLIB := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --libs libkim-api-v2 2> /dev/null) + +ifeq ($(strip $(kim_SYSINC)),) + $(error 'pkg-config' could not find an installed KIM API library.) +endif diff --git a/lib/kim/README b/lib/kim/README index 6bcad18ce0..7cf8f9bb7d 100644 --- a/lib/kim/README +++ b/lib/kim/README @@ -3,10 +3,9 @@ is required to use the KIM package and its pair_style kim command in a LAMMPS input script. Information about the KIM project can be found at https://openkim.org. -The KIM project is lead by Ellad Tadmor and Ryan Elliott (U Minn) and -James Sethna (Cornell U). Ryan Elliott is the main developer for the -KIM API and he also maintains the code that implements the pair_style -kim command. +The KIM project is lead by Ellad Tadmor and Ryan Elliott (U Minn). +Ryan Elliott is the main developer for the KIM API and he also +maintains the code that implements the pair_style kim command. You can type "make lib-kim" from the src directory to see help on how to download and build this library via make commands, or you can @@ -21,7 +20,7 @@ Instructions: 1. Configure lammps for use with the kim-api library installed in this directory # replace X.Y.Z as appropriate here and below -$ printf "KIM_INSTALL_DIR=${PWD}/installed-kim-api-vX.Y.Z\n" > ./Makefile.KIM_DIR +$ printf "${PWD}/installed-kim-api-vX.Y.Z" > ./kim-prefix.txt 2. Download and unpack the kim-api @@ -30,26 +29,21 @@ $ tar zxvf kim-api-vX.Y.Z.txz # configure the kim-api $ cd kim-api-vX.Y.Z -$ ./configure --prefix=${PWD}/../installed-kim-api-vX.Y.Z +$ mkdir build && cd build +$ cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../../installed-kim-api-vX.Y.Z 3. Build and install the kim-api and model $ make $ make install -4. To install the example models shipped with the kim-api - -$ cd examples -$ make model-drivers-all-system -$ make models-all-system -$ cd ../.. - -5. Remove source and build files +4. Remove source and build files +$ cd ../../ $ rm -rf kim-api-vX.Y.Z $ rm -rf kim-api-vX.Y.Z.txz -6. To add items do the following (replace the kim item name with your +5. To add items do the following (replace the kim item name with your desired value) $ source ${PWD}/kim-api-vX.Y.Z/bin/kim-api-vX-activate @@ -65,6 +59,6 @@ $ cd lammpos/src $ make yes-kim $ make g++ (or whatever target you wish) -Note that the Makefile.lammps and Makefile.KIM_DIR files in this directory -are required to allow the LAMMPS build to find the necessary KIM files. -You should not normally need to edit these files. +Note that the Makefile.lammps file in this directory is required to +allow the LAMMPS build to find the necessary KIM files. You should +not normally need to edit these files. -- GitLab From dd61ded311abda89440ee62de0b740684c5acc12 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 5 Nov 2018 09:24:02 -0600 Subject: [PATCH 0056/1243] Update cmake build to work with cmake-based KIM --- cmake/CMakeLists.txt | 46 ++++++++++++------------- cmake/Modules/FindKIM-API-V2.cmake | 55 ++++++++++++++++++++++++++++++ cmake/Modules/FindKIM.cmake | 22 ------------ 3 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 cmake/Modules/FindKIM-API-V2.cmake delete mode 100644 cmake/Modules/FindKIM.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 418bdd0dba..5402ac1987 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -454,7 +454,7 @@ endif() if(PKG_LATTE) option(DOWNLOAD_LATTE "Download latte (instead of using the system's one)" OFF) if(DOWNLOAD_LATTE) - if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR + if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR message(FATAL_ERROR "For downlading LATTE you need at least cmake-3.7") endif() message(STATUS "LATTE not found - we will build our own") @@ -485,15 +485,15 @@ if(PKG_USER-SCAFACOS) ExternalProject_Add(scafacos_build URL https://github.com/scafacos/scafacos/releases/download/v1.0.1/scafacos-1.0.1.tar.gz URL_MD5 bd46d74e3296bd8a444d731bb10c1738 - CONFIGURE_COMMAND /configure --prefix= - --disable-doc + CONFIGURE_COMMAND /configure --prefix= + --disable-doc --enable-fcs-solvers=fmm,p2nfft,direct,ewald,p3m --with-internal-fftw --with-internal-pfft --with-internal-pnfft - $<$:--with-pic> - FC=${CMAKE_MPI_Fortran_COMPILER} - CXX=${CMAKE_MPI_CXX_COMPILER} + $<$:--with-pic> + FC=${CMAKE_MPI_Fortran_COMPILER} + CXX=${CMAKE_MPI_CXX_COMPILER} CC=${CMAKE_MPI_C_COMPILER} F77= ) @@ -547,7 +547,7 @@ if(PKG_USER-SMD) if(DOWNLOAD_EIGEN3) include(ExternalProject) ExternalProject_Add(Eigen3_build - URL http://bitbucket.org/eigen/eigen/get/3.3.4.tar.gz + URL http://bitbucket.org/eigen/eigen/get/3.3.4.tar.gz URL_MD5 1a47e78efe365a97de0c022d127607c3 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) @@ -588,23 +588,23 @@ if(PKG_KIM) if(DOWNLOAD_KIM) include(ExternalProject) ExternalProject_Add(kim_build - URL https://github.com/openkim/kim-api/archive/v1.9.5.tar.gz - URL_MD5 9f66efc128da33039e30659f36fc6d00 - BUILD_IN_SOURCE 1 - CONFIGURE_COMMAND /configure --prefix= + URL https://s3.openkim.org/kim-api/kim-api-v2.0.0-beta.2.txz + URL_MD5 1fbdbb734059cf0dc9d807e6dd6cc8ea + BINARY_DIR build + CMAKE_ARGS -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_Fortran_COMPILER=gfortran-8 -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=Release ) ExternalProject_get_property(kim_build INSTALL_DIR) - set(KIM_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v1) - set(KIM_LIBRARIES ${INSTALL_DIR}/lib/libkim-api-v1.so) + set(KIM-API-V2_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) + set(KIM-API-V2_LIBRARIES ${INSTALL_DIR}/lib/libkim-api-v2.2${CMAKE_SHARED_LIBRARY_SUFFIX}) list(APPEND LAMMPS_DEPS kim_build) else() - find_package(KIM) - if(NOT KIM_FOUND) - message(FATAL_ERROR "KIM not found, help CMake to find it by setting KIM_LIBRARY and KIM_INCLUDE_DIR, or set DOWNLOAD_KIM=ON to download it") + find_package(KIM-API-V2) + if(NOT KIM-API-V2_FOUND) + message(FATAL_ERROR "KIM not found, help CMake to find it by setting PKG_CONFIG_PATH, or set DOWNLOAD_KIM=ON to download it") endif() endif() - list(APPEND LAMMPS_LINK_LIBS ${KIM_LIBRARIES}) - include_directories(${KIM_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${KIM-API-V3_LIBRARIES}) + include_directories(${KIM-API-V2_INCLUDE_DIRS}) endif() if(PKG_MESSAGE) @@ -645,7 +645,7 @@ if(PKG_MSCG) find_package(GSL REQUIRED) option(DOWNLOAD_MSCG "Download latte (instead of using the system's one)" OFF) if(DOWNLOAD_MSCG) - if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR + if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR message(FATAL_ERROR "For downlading LATTE you need at least cmake-3.7") endif() include(ExternalProject) @@ -1020,7 +1020,7 @@ if(PKG_USER-INTEL) endif() if(PKG_GPU) - if (CMAKE_VERSION VERSION_LESS "3.1") + if (CMAKE_VERSION VERSION_LESS "3.1") message(FATAL_ERROR "For the GPU package you need at least cmake-3.1") endif() set(GPU_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/GPU) @@ -1224,7 +1224,7 @@ if(BUILD_EXE) add_dependencies(lmp ${LAMMPS_DEPS}) endif() endif() - + set_target_properties(lmp PROPERTIES OUTPUT_NAME ${LAMMPS_BINARY}) install(TARGETS lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${LAMMPS_DOC_DIR}/lammps.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 RENAME ${LAMMPS_BINARY}.1) @@ -1361,14 +1361,14 @@ message(STATUS "<<< Build configuration >>> get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) list (FIND LANGUAGES "Fortran" _index) if (${_index} GREATER -1) - message(STATUS "Fortran Compiler ${CMAKE_Fortran_COMPILER} + message(STATUS "Fortran Compiler ${CMAKE_Fortran_COMPILER} Type ${CMAKE_Fortran_COMPILER_ID} Version ${CMAKE_Fortran_COMPILER_VERSION} Fortran Flags ${CMAKE_Fortran_FLAGS} ${CMAKE_Fortran_FLAGS_${BTYPE}}") endif() list (FIND LANGUAGES "C" _index) if (${_index} GREATER -1) - message(STATUS "C Compiler ${CMAKE_C_COMPILER} + message(STATUS "C Compiler ${CMAKE_C_COMPILER} Type ${CMAKE_C_COMPILER_ID} Version ${CMAKE_C_COMPILER_VERSION} C Flags ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BTYPE}}") diff --git a/cmake/Modules/FindKIM-API-V2.cmake b/cmake/Modules/FindKIM-API-V2.cmake new file mode 100644 index 0000000000..0cc947e139 --- /dev/null +++ b/cmake/Modules/FindKIM-API-V2.cmake @@ -0,0 +1,55 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the Common Development +# and Distribution License Version 1.0 (the "License"). +# +# You can obtain a copy of the license at +# http://www.opensource.org/licenses/CDDL-1.0. See the License for the +# specific language governing permissions and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each file and +# include the License file in a prominent location with the name LICENSE.CDDL. +# If applicable, add the following below this CDDL HEADER, with the fields +# enclosed by brackets "[]" replaced with your own identifying information: +# +# Portions Copyright (c) [yyyy] [name of copyright owner]. All rights reserved. +# +# CDDL HEADER END +# + +# +# Copyright (c) 2013--2018, Regents of the University of Minnesota. +# All rights reserved. +# +# Contributors: +# Richard Berger +# Christoph Junghans +# Ryan S. Elliott +# + +# +# Release: This file is part of the kim-api.git repository. +# + + +# - Find KIM-API-V2 +# +# sets standard pkg_check_modules variables plus: +# +# KIM-API-V2-CMAKE_C_COMPILER +# KIM-API-V2-CMAKE_CXX_COMPILER +# KIM-API-V2-CMAKE_Fortran_COMPILER +# +find_package(PkgConfig REQUIRED) +include(FindPackageHandleStandardArgs) + +pkg_check_modules(KIM-API-V2 REQUIRED libkim-api-v2>=2.0) + +pkg_get_variable(KIM-API-V2-CMAKE_C_COMPILER libkim-api-v2 CMAKE_C_COMPILER) +pkg_get_variable(KIM-API-V2-CMAKE_CXX_COMPILER libkim-api-v2 CMAKE_CXX_COMPILER) +pkg_get_variable(KIM-API-V2_CMAKE_Fortran_COMPILER libkim-api-v2 CMAKE_Fortran_COMPILER) + +# handle the QUIETLY and REQUIRED arguments and set KIM-API-V2_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(KIM-API-V2 REQUIRED_VARS KIM-API-V2_LIBRARIES) diff --git a/cmake/Modules/FindKIM.cmake b/cmake/Modules/FindKIM.cmake deleted file mode 100644 index e29f26e01d..0000000000 --- a/cmake/Modules/FindKIM.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# - Find kim -# Find the native KIM headers and libraries. -# -# KIM_INCLUDE_DIRS - where to find kim.h, etc. -# KIM_LIBRARIES - List of libraries when using kim. -# KIM_FOUND - True if kim found. -# - -find_path(KIM_INCLUDE_DIR KIM_SimulatorHeaders.hpp PATH_SUFFIXES kim-api-v2) - -find_library(KIM_LIBRARY NAMES kim-api-v2) - -set(KIM_LIBRARIES ${KIM_LIBRARY}) -set(KIM_INCLUDE_DIRS ${KIM_INCLUDE_DIR}) - -include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set KIM_FOUND to TRUE -# if all listed variables are TRUE - -find_package_handle_standard_args(KIM DEFAULT_MSG KIM_LIBRARY KIM_INCLUDE_DIR) - -mark_as_advanced(KIM_INCLUDE_DIR KIM_LIBRARY ) -- GitLab From 29ae88e309fd02a3b4fbb3f882f498258096a794 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 5 Nov 2018 09:37:35 -0600 Subject: [PATCH 0057/1243] Update docs for KIM --- doc/src/Build_extras.txt | 44 ++++++++++++------------- doc/src/Errors_messages.txt | 8 ----- doc/src/Packages_details.txt | 63 +++++++++++++++++------------------- doc/src/pair_kim.txt | 2 +- 4 files changed, 51 insertions(+), 66 deletions(-) diff --git a/doc/src/Build_extras.txt b/doc/src/Build_extras.txt index d256a1afc8..5f4ad6ee69 100644 --- a/doc/src/Build_extras.txt +++ b/doc/src/Build_extras.txt @@ -63,7 +63,7 @@ available on your system. If CMake cannot find the library, you can set these variables: --D ZLIB_INCLUDE_DIR=path # path to zlib.h header file +-D ZLIB_INCLUDE_DIR=path # path to zlib.h header file -D ZLIB_LIBRARIES=path # path to libz.a (.so) file :pre [Traditional make]: @@ -150,7 +150,7 @@ package uses the library settings from the lib/gpu/Makefile.machine used to build the GPU library. :line - + KIM package :h4,link(kim) To build with this package, the KIM library must be downloaded and @@ -176,16 +176,12 @@ package?" page. [CMake build]: --D DOWNLOAD_KIM=value # download OpenKIM API v1 for build, value = no (default) or yes --D KIM_LIBRARY=path # KIM library file (only needed if a custom location) --D KIM_INCLUDE_DIR=path # KIM include directory (only needed if a custom location) :pre +-D DOWNLOAD_KIM=value # download OpenKIM API v1 for build, value = no (default) or yes :pre If DOWNLOAD_KIM is set, the KIM library will be downloaded and built inside the CMake build directory. If the KIM library is already on -your system (in a location CMake cannot find it), KIM_LIBRARY is the -filename (plus path) of the KIM library file, not the directory the -library file is in. KIM_INCLUDE_DIR is the directory the KIM include -file is in. +your system (in a location CMake cannot find it), set the PKG_CONFIG_PATH +environment variable so that libkim-api-v2 can be found. [Traditional make]: @@ -199,8 +195,8 @@ make lib-kim args="-b " # (re-)install KIM API lib with only example models make lib-kim args="-b -a Glue_Ercolessi_Adams_Al__MO_324507536345_001" # ditto plus one model make lib-kim args="-b -a everything" # install KIM API lib with all models make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # add one model or model driver -make lib-kim args="-p /usr/local/kim-api" # use an existing KIM API installation at the provided location -make lib-kim args="-p /usr/local/kim-api -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # ditto but add one model or driver :pre +make lib-kim args="-p /usr/local" # use an existing KIM API installation at the provided location +make lib-kim args="-p /usr/local -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # ditto but add one model or driver :pre :line @@ -254,7 +250,7 @@ For NVIDIA GPUs using CUDA, set these 4 variables: -D KOKKOS_ARCH="archCPU;archGPU" # archCPU = CPU from list above that is hosting the GPU # archGPU = GPU from list above -D KOKKOS_ENABLE_CUDA=yes --D KOKKOS_ENABLE_OPENMP=yes +-D KOKKOS_ENABLE_OPENMP=yes -D CMAKE_CXX_COMPILER=wrapper # wrapper = full path to Cuda nvcc wrapper :pre The wrapper value is the Cuda nvcc compiler wrapper provided in the @@ -296,7 +292,7 @@ export OMPI_CXX = $(KOKKOS_ABSOLUTE_PATH)/config/nvcc_wrapper CC = mpicxx :pre :line - + LATTE package :h4,link(latte) To build with this package, you must download and build the LATTE @@ -324,7 +320,7 @@ args: make lib-latte # print help message make lib-latte args="-b" # download and build in lib/latte/LATTE-master make lib-latte args="-p $HOME/latte" # use existing LATTE installation in $HOME/latte -make lib-latte args="-b -m gfortran" # download and build in lib/latte and +make lib-latte args="-b -m gfortran" # download and build in lib/latte and # copy Makefile.lammps.gfortran to Makefile.lammps :pre @@ -335,7 +331,7 @@ also check that the Makefile.lammps file you create is appropriate for the compiler you use on your system to build LATTE. :line - + MEAM package :h4,link(meam) NOTE: the use of the MEAM package is discouraged, as it has been @@ -378,7 +374,7 @@ EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. :line - + MESSAGE package :h4,link(message) This package can optionally include support for messaging via sockets, @@ -407,7 +403,7 @@ existing Makefile.lammps.* and has settings to link with the ZeroMQ library if requested in the build. :line - + MSCG package :h4,link(mscg) To build with this package, you must download and build the MS-CG @@ -419,7 +415,7 @@ lib/mscg/README and MSCG/Install files for more details. [CMake build]: -D DOWNLOAD_MSCG=value # download MSCG for build, value = no (default) or yes --D MSCG_LIBRARY=path # MSCG library file (only needed if a custom location) +-D MSCG_LIBRARY=path # MSCG library file (only needed if a custom location) -D MSCG_INCLUDE_DIR=path # MSCG include directory (only needed if a custom location) :pre If DOWNLOAD_MSCG is set, the MSCG library will be downloaded and built @@ -464,7 +460,7 @@ line of your Makefile.machine. See src/MAKE/OPTIONS/Makefile.opt for an example. :line - + POEMS package :h4,link(poems) [CMake build]: @@ -493,7 +489,7 @@ for your system, which should define an EXTRAMAKE variable to specify a corresponding Makefile.lammps.machine file. :line - + PYTHON package :h4,link(python) Building with the PYTHON package requires you have a Python shared @@ -520,7 +516,7 @@ Makefile.lammps.* file (and copy it to Makefile.lammps) if the LAMMPS build fails. :line - + REAX package :h4,link(reax) NOTE: the use of the REAX package and its "pair_style @@ -570,7 +566,7 @@ library"_voro-home. [CMake build]: -D DOWNLOAD_VORO=value # download Voro++ for build, value = no (default) or yes --D VORO_LIBRARY=path # Voro++ library file (only needed if at custom location) +-D VORO_LIBRARY=path # Voro++ library file (only needed if at custom location) -D VORO_INCLUDE_DIR=path # Voro++ include directory (only needed if at custom location) :pre If DOWNLOAD_VORO is set, the Voro++ library will be downloaded and @@ -869,7 +865,7 @@ Quantum ESPRESSO known to work with this QM/MM interface was version [CMake build]: The CMake build system currently does not support building the full -QM/MM-capable hybrid executable of LAMMPS and QE called pwqmmm.x. +QM/MM-capable hybrid executable of LAMMPS and QE called pwqmmm.x. You must use the traditional make build for this package. [Traditional make]: @@ -939,7 +935,7 @@ Coulomb solver library"_scafacos-home [CMake build]: -D DOWNLOAD_SCAFACOS=value # download ScaFaCoS for build, value = no (default) or yes --D SCAFACOS_LIBRARY=path # ScaFaCos library file (only needed if at custom location) +-D SCAFACOS_LIBRARY=path # ScaFaCos library file (only needed if at custom location) -D SCAFACOS_INCLUDE_DIR=path # ScaFaCoS include directory (only needed if at custom location) :pre If DOWNLOAD_SCAFACOS is set, the ScaFaCoS library will be downloaded diff --git a/doc/src/Errors_messages.txt b/doc/src/Errors_messages.txt index 695b949f7e..3dc93044c8 100644 --- a/doc/src/Errors_messages.txt +++ b/doc/src/Errors_messages.txt @@ -6994,12 +6994,6 @@ The atom style defined does not have this attribute. :dd The atom style defined does not have these attributes. :dd -{KIM neighbor iterator exceeded range} :dt - -This should not happen. It likely indicates a bug -in the KIM implementation of the interatomic potential -where it is requesting neighbors incorrectly. :dd - {KOKKOS package does not yet support comm_style tiled} :dt Self-explanatory. :dd @@ -10193,8 +10187,6 @@ Self-explanatory. :dd {Unrecognized virial argument in pair_style command} :dt -Only two options are supported: LAMMPSvirial and KIMvirial :dd - {Unsupported mixing rule in kspace_style ewald/disp} :dt Only geometric mixing is supported. :dd diff --git a/doc/src/Packages_details.txt b/doc/src/Packages_details.txt index 031858e846..7365e986e5 100644 --- a/doc/src/Packages_details.txt +++ b/doc/src/Packages_details.txt @@ -203,7 +203,7 @@ available on your system. [Author:] Axel Kohlmeyer (Temple U). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -284,7 +284,7 @@ also the "KOKKOS"_#PKG-KOKKOS package, which has GPU-enabled styles. [Authors:] Mike Brown (Intel) while at Sandia and ORNL and Trung Nguyen (Northwestern U) while at ORNL. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -345,14 +345,13 @@ system. Information about the KIM project can be found at its website: https://openkim.org. The KIM project is led by Ellad Tadmor and Ryan -Elliott (U Minnesota) and James Sethna (Cornell U). +Elliott (U Minnesota). [Authors:] Ryan Elliott (U Minnesota) is the main developer for the KIM API which the "pair_style kim"_pair_kim.html command uses. He -developed the pair style in collaboration with Valeriu Smirichinski (U -Minnesota). +developed the pair style. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -398,7 +397,7 @@ which was developed by Carter Edwards, Christian Trott, and others at Sandia, and which is included in the LAMMPS distribution in lib/kokkos. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -546,7 +545,7 @@ and user interface. [Author:] Greg Wagner (Northwestern U) while at Sandia. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -679,7 +678,7 @@ system. library was developed by Jacob Wagner in Greg Voth's group at the University of Chicago. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -711,7 +710,7 @@ have styles optimized for CPU performance. [Authors:] James Fischer (High Performance Technologies), David Richie, and Vincent Natoli (Stone Ridge Technolgy). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -768,7 +767,7 @@ connections at hinge points. [Author:] Rudra Mukherjee (JPL) while at RPI. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -800,7 +799,7 @@ shared library available on your system, which needs to be a Python 2 version, 2.6 or later. Python 3 is not yet supported. See the lib/python/README for more details. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -848,7 +847,7 @@ as bonds are created and destroyed. [Author:] Aidan Thompson (Sandia). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1021,7 +1020,7 @@ system. library was written by Chris Rycroft (Harvard U) while at UC Berkeley and LBNL. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1048,7 +1047,7 @@ atomic information to continuum fields. [Authors:] Reese Jones, Jeremy Templeton, Jon Zimmerman (Sandia). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1075,7 +1074,7 @@ model. [Author:] Ilya Valuev (JIHT, Russia). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1098,7 +1097,7 @@ This package provides "fix bocs"_fix_bocs.html, a modified version of "fix npt"_fix_nh.html which includes the pressure correction to the barostat as outlined in: -N. J. H. Dunn and W. G. Noid, "Bottom-up coarse-grained models that +N. J. H. Dunn and W. G. Noid, "Bottom-up coarse-grained models that accurately describe the structure, pressure, and compressibility of molecular liquids," J. Chem. Phys. 143, 243148 (2015). @@ -1183,7 +1182,7 @@ and Jerome Henin (LISM, CNRS, Marseille, France), originally for the NAMD MD code, but with portability in mind. Axel Kohlmeyer (Temple U) provided the interface to LAMMPS. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1363,7 +1362,7 @@ system. [Author:] Pierre de Buyl (KU Leuven) created both the package and the H5MD format. -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1401,7 +1400,7 @@ NOTE: the USER-INTEL package contains styles that require using the [Author:] Mike Brown (Intel). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1571,17 +1570,17 @@ USER-MOFFF package :link(PKG-USER-MOFFF),h4 [Contents:] Pair, angle and improper styles needed to employ the MOF-FF -force field by Schmid and coworkers with LAMMPS. +force field by Schmid and coworkers with LAMMPS. MOF-FF is a first principles derived force field with the primary aim -to simulate MOFs and related porous framework materials, using spherical +to simulate MOFs and related porous framework materials, using spherical Gaussian charges. It is described in S. Bureekaew et al., Phys. Stat. Sol. B 2013, 250, 1128-1141. -For the usage of MOF-FF see the example in the example directory as +For the usage of MOF-FF see the example in the example directory as well as the "MOF+"_MOFplus website. :link(MOFplus,https://www.mofplus.org/content/show/MOF-FF) -[Author:] Hendrik Heenen (Technical U of Munich), +[Author:] Hendrik Heenen (Technical U of Munich), Rochus Schmid (Ruhr-University Bochum). [Supporting info:] @@ -1622,7 +1621,7 @@ at [Author:] Axel Kohlmeyer (Temple U). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1662,7 +1661,7 @@ tools: [Author:] Lars Pastewka (Karlsruhe Institute of Technology). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1706,7 +1705,7 @@ See src/MAKE/OPTIONS/Makefile.omp for an example. Once you have an appropriate Makefile.machine, you can install/un-install the package and build LAMMPS in the usual manner: -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1785,7 +1784,7 @@ without changes to LAMMPS itself. [Author:] Axel Kohlmeyer (Temple U). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1843,7 +1842,7 @@ on your system. [Author:] Albert Bartok (Cambridge University) -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -1937,7 +1936,7 @@ specified as surface geometries from *.STL files. [Author:] Georg Ganzenmuller (Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute, Germany). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -2063,7 +2062,7 @@ system. [Authors:] Richard Berger (JKU) and Daniel Queteschiner (DCS Computing). -[Install:] +[Install:] This package has "specific installation instructions"_Build_extras.html#gpu on the "Build @@ -2075,5 +2074,3 @@ src/USER-VTK: filenames -> commands src/USER-VTK/README lib/vtk/README "dump vtk"_dump_vtk.html :ul - - diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index 8bd6aa9937..0c05913117 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -115,7 +115,7 @@ LAMMPS was built with that package. See the "Build package"_Build_package.html doc page for more info. This current version of pair_style kim is compatible with the -kim-api package version 2.0.0-beta.1 and higher. +kim-api package version 2.0.0-beta.2 and higher. [Related commands:] -- GitLab From 4a4147e0e4983a871bc17c510abd39f0b77e80e3 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 5 Nov 2018 11:15:07 -0600 Subject: [PATCH 0058/1243] Remove hard-coded compiler versions for KIM in CMake --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5402ac1987..670313dadd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -591,7 +591,7 @@ if(PKG_KIM) URL https://s3.openkim.org/kim-api/kim-api-v2.0.0-beta.2.txz URL_MD5 1fbdbb734059cf0dc9d807e6dd6cc8ea BINARY_DIR build - CMAKE_ARGS -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_C_COMPILER=gcc-8 -DCMAKE_Fortran_COMPILER=gfortran-8 -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=Release + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=Release ) ExternalProject_get_property(kim_build INSTALL_DIR) set(KIM-API-V2_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) -- GitLab From 81e79ec884ae2d88d0e5ee8357d6743b526b3abb Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Mon, 5 Nov 2018 15:39:10 -0600 Subject: [PATCH 0059/1243] Have KIM use LAMMPS specified compilers --- cmake/CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 670313dadd..3e6c57c667 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -586,12 +586,18 @@ endif() if(PKG_KIM) option(DOWNLOAD_KIM "Download kim-api (instead of using the system's one)" OFF) if(DOWNLOAD_KIM) + enable_language(C) + enable_language(Fortran) include(ExternalProject) ExternalProject_Add(kim_build URL https://s3.openkim.org/kim-api/kim-api-v2.0.0-beta.2.txz URL_MD5 1fbdbb734059cf0dc9d807e6dd6cc8ea BINARY_DIR build - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=Release + CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER} + -DCMAKE_INSTALL_PREFIX= + -DCMAKE_BUILD_TYPE=Release ) ExternalProject_get_property(kim_build INSTALL_DIR) set(KIM-API-V2_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) @@ -603,7 +609,7 @@ if(PKG_KIM) message(FATAL_ERROR "KIM not found, help CMake to find it by setting PKG_CONFIG_PATH, or set DOWNLOAD_KIM=ON to download it") endif() endif() - list(APPEND LAMMPS_LINK_LIBS ${KIM-API-V3_LIBRARIES}) + list(APPEND LAMMPS_LINK_LIBS ${KIM-API-V2_LIBRARIES}) include_directories(${KIM-API-V2_INCLUDE_DIRS}) endif() -- GitLab From 9727fdc47305b9ce29ec099a6a1d138892e38898 Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 8 Nov 2018 16:17:43 -0700 Subject: [PATCH 0060/1243] Commit JT 110818 - correct bug (match ewald/disp results for vir) - started correct mag. part --- examples/SPIN/pppm_spin/data.2 | 13 ++++ examples/SPIN/pppm_spin/in.spin.2 | 75 +++++++++++++++++++++ examples/SPIN/pppm_spin/in.spin.cut_comp | 72 +++++++++++++++++++++ examples/SPIN/pppm_spin/in.spin.pppm_spin | 10 +-- src/KSPACE/ewald_dipole.cpp | 28 ++++---- src/KSPACE/ewald_dipole_spin.cpp | 30 +++++---- src/SPIN/pair_spin_dipolar_cut.cpp | 79 +++++++++++------------ 7 files changed, 233 insertions(+), 74 deletions(-) create mode 100644 examples/SPIN/pppm_spin/data.2 create mode 100644 examples/SPIN/pppm_spin/in.spin.2 create mode 100644 examples/SPIN/pppm_spin/in.spin.cut_comp diff --git a/examples/SPIN/pppm_spin/data.2 b/examples/SPIN/pppm_spin/data.2 new file mode 100644 index 0000000000..426e3a9cb4 --- /dev/null +++ b/examples/SPIN/pppm_spin/data.2 @@ -0,0 +1,13 @@ +RANDOM INITIALIZATION FOR STOCKMAYER FLUID +2 atoms +1 atom types + + -3.0 3.0 xlo xhi + -3.0 3.0 ylo yhi + -3.0 3.0 zlo zhi + #30.0 30.0 0.0 xy xz yz + +Atoms + +1 1 1.73 0.0 0.0 0.0 0.0 0.0 1.0 +2 1 1.73 0.0 2.5 0.0 0.0 0.0 1.0 diff --git a/examples/SPIN/pppm_spin/in.spin.2 b/examples/SPIN/pppm_spin/in.spin.2 new file mode 100644 index 0000000000..29f3203694 --- /dev/null +++ b/examples/SPIN/pppm_spin/in.spin.2 @@ -0,0 +1,75 @@ +# two magnetic atoms in a 3d box + +clear +units metal +atom_style spin + +dimension 3 +#boundary p p p +atom_modify map array + +read_data ../examples/SPIN/pppm_spin/data.2 + + +mass 1 58.93 +#set group all spin/random 31 1.72 + +#velocity all create 100 4928459 rot yes dist gaussian + +pair_style spin/dipolar/cut 4.0 +pair_coeff * * long 2.6 +#pair_style hybrid/overlay spin/exchange 4.0 spin/dipolar/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long 8.0 +#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long/qsymp 8.0 +#pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +#pair_coeff * * spin/exchange exchange 4.0 0.1 1.135028015e-05 1.064568567 +#pair_coeff * * spin/dipolar/long long 8.0 + +#neighbor 0.1 bin +#neigh_modify every 10 check yes delay 20 +neighbor 0.3 bin +neigh_modify delay 0 +#neigh_modify every 1 delay 10 check yes page 100000000 one 10000000 + +#kspace_style pppm/dipole/spin 1.0e-4 +#kspace_style ewald/dipole/spin 1.0e-4 +#kspace_modify compute yes +#kspace_modify compute yes gewald 0.1 + +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.0 21 +#fix 3 all nve/spin lattice yes +fix 3 all nve/spin lattice no + +timestep 0.0001 + +thermo_style custom step temp pe ke etotal press +thermo_modify format float %20.16g +thermo 1 + +#compute peratom all pe/atom +#compute pe all reduce sum c_peratom +#thermo_style custom step temp pe c_pe + +#compute peratom2 all stress/atom +#compute peratom2 all stress/atom NULL +#compute p all reduce sum c_peratom2[1] c_peratom2[2] c_peratom2[3] c_peratom2[4] c_peratom2[5] c_peratom2[6] +#variable press equal -(c_p[1]+c_p[2]+c_p[3])/(3*vol) +#variable pxx equal -c_p[1]/vol +#variable pyy equal -c_p[2]/vol +#variable pzz equal -c_p[3]/vol +#variable pxy equal -c_p[4]/vol +#variable pxz equal -c_p[5]/vol +#variable pyz equal -c_p[6]/vol +#thermo_style custom step temp etotal pe c_pe press v_press pxx v_pxx pyy v_pyy pzz v_pzz pxy v_pxy pxz v_pxz pyz v_pyz +#thermo_style custom step etotal pe press v_press v_pxx v_pyy v_pzz v_pxy v_pxz v_pyz +#thermo_style custom step temp etotal press v_press + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 1 all custom 1 dump.equil id type x y z c_outsp[1] c_outsp[2] c_outsp[3] +#c_outsp[5] c_outsp[6] c_outsp[7] +#dump_modify 1 format line "%d %d %20.15g %20.15g %20.15g %20.15g %20.15g %20.15g" scale yes + +#pair_modify compute no + +run 1 diff --git a/examples/SPIN/pppm_spin/in.spin.cut_comp b/examples/SPIN/pppm_spin/in.spin.cut_comp new file mode 100644 index 0000000000..3d01c56878 --- /dev/null +++ b/examples/SPIN/pppm_spin/in.spin.cut_comp @@ -0,0 +1,72 @@ +# bcc iron in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary p p p +atom_modify map array + +lattice bcc 2.8665 +region box block 0.0 5.0 0.0 5.0 0.0 5.0 +create_box 1 box +create_atoms 1 box + +mass 1 58.93 +#set group all spin 2.2 0.0 0.0 1.0 +set group all spin/random 31 2.2 + +#pair_style spin/dipolar/cut 5.0 +#pair_coeff * * long 5.0 +pair_style spin/dipolar/long 4.0 +pair_coeff * * long 4.0 + +#neighbor 0.1 bin +#neigh_modify every 10 check yes delay 20 +neighbor 0.3 bin +neigh_modify delay 0 +#neigh_modify every 1 delay 10 check yes page 100000000 one 10000000 + +#kspace_style pppm/dipole/spin 1.0e-4 +kspace_style ewald/dipole/spin 1.0e-4 +kspace_modify compute yes +#kspace_modify compute yes gewald 0.1 + +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.1 21 +#fix 3 all nve/spin lattice yes +fix 3 all nve/spin lattice no + +timestep 0.0001 + +thermo_style custom step temp pe ke etotal press +thermo_modify format float %20.16g +thermo 50 + +#compute peratom all pe/atom +#compute pe all reduce sum c_peratom +#thermo_style custom step temp pe c_pe + +#compute peratom2 all stress/atom +#compute peratom2 all stress/atom NULL +#compute p all reduce sum c_peratom2[1] c_peratom2[2] c_peratom2[3] c_peratom2[4] c_peratom2[5] c_peratom2[6] +#variable press equal -(c_p[1]+c_p[2]+c_p[3])/(3*vol) +#variable pxx equal -c_p[1]/vol +#variable pyy equal -c_p[2]/vol +#variable pzz equal -c_p[3]/vol +#variable pxy equal -c_p[4]/vol +#variable pxz equal -c_p[5]/vol +#variable pyz equal -c_p[6]/vol +#thermo_style custom step temp etotal pe c_pe press v_press pxx v_pxx pyy v_pyy pzz v_pzz pxy v_pxy pxz v_pxz pyz v_pyz +#thermo_style custom step etotal pe press v_press v_pxx v_pyy v_pzz v_pxy v_pxz v_pyz +#thermo_style custom step temp etotal press v_press + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 50 all custom 1 dump.equil id type x y z c_outsp[1] c_outsp[2] c_outsp[3] +#c_outsp[5] c_outsp[6] c_outsp[7] +#dump_modify 1 format line "%d %d %20.15g %20.15g %20.15g %20.15g %20.15g %20.15g" scale yes + +#pair_modify compute no + +run 10000 diff --git a/examples/SPIN/pppm_spin/in.spin.pppm_spin b/examples/SPIN/pppm_spin/in.spin.pppm_spin index 6762fe6fab..78dfbb56a0 100644 --- a/examples/SPIN/pppm_spin/in.spin.pppm_spin +++ b/examples/SPIN/pppm_spin/in.spin.pppm_spin @@ -19,14 +19,15 @@ create_atoms 1 box mass 1 58.93 -#set group all spin/random 31 1.72 -set group all spin 1.72 0.0 0.0 1.0 +set group all spin/random 31 1.72 +#set group all spin 1.72 0.0 0.0 1.0 velocity all create 100 4928459 rot yes dist gaussian pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long 8.0 #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/long/qsymp 8.0 pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co -pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +#pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +pair_coeff * * spin/exchange exchange 4.0 0.0 1.135028015e-05 1.064568567 #pair_coeff * * spin/dipolar/long/qsymp long 8.0 pair_coeff * * spin/dipolar/long long 8.0 @@ -34,7 +35,7 @@ neighbor 0.1 bin neigh_modify every 10 check yes delay 20 kspace_style pppm/dipole/spin 1.0e-4 -#kspace_modify mesh 32 32 32 +kspace_modify compute yes #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 @@ -55,6 +56,7 @@ variable emag equal c_out_mag[5] variable tmag equal c_out_mag[6] thermo_style custom step time v_magnorm v_emag temp etotal +thermo_modify format float %20.16g thermo 10 compute outsp all property/atom spx spy spz sp fmx fmy fmz diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index f2124deb4f..92470eb4a8 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -439,8 +439,7 @@ void EwaldDipole::compute(int eflag, int vflag) for (i = 0; i < nlocal; i++) { - vcik[0] = vcik[1] = vcik[2] = 0.0; - vcik[3] = vcik[4] = vcik[5] = 0.0; + for (j = 0; j<6; j++) vcik[j] = 0.0; // calculating re and im of exp(i*k*ri) @@ -458,29 +457,28 @@ void EwaldDipole::compute(int eflag, int vflag) // compute field for torque calculation - partial2 = exprl*sfacrl_all[k] + expim*sfacim_all[k]; - tk[i][0] += partial2*eg[k][0]; - tk[i][1] += partial2*eg[k][1]; - tk[i][2] += partial2*eg[k][2]; + partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; + tk[i][0] += partial_peratom * eg[k][0]; + tk[i][1] += partial_peratom * eg[k][1]; + tk[i][2] += partial_peratom * eg[k][2]; // total and per-atom virial correction (dipole only) - vc[k][0] += vcik[0] = partial2 * mu[i][0] * kx; - vc[k][1] += vcik[1] = partial2 * mu[i][1] * ky; - vc[k][2] += vcik[2] = partial2 * mu[i][2] * kz; - vc[k][3] += vcik[3] = partial2 * mu[i][0] * ky; - vc[k][4] += vcik[4] = partial2 * mu[i][0] * kz; - vc[k][5] += vcik[5] = partial2 * mu[i][1] * kz; + vc[k][0] += vcik[0] = -(partial_peratom * mu[i][0] * eg[k][0]); + vc[k][1] += vcik[1] = -(partial_peratom * mu[i][1] * eg[k][1]); + vc[k][2] += vcik[2] = -(partial_peratom * mu[i][2] * eg[k][2]); + vc[k][3] += vcik[3] = -(partial_peratom * mu[i][0] * eg[k][1]); + vc[k][4] += vcik[4] = -(partial_peratom * mu[i][0] * eg[k][2]); + vc[k][5] += vcik[5] = -(partial_peratom * mu[i][1] * eg[k][2]); // taking re-part of struct_fact x exp(i*k*ri) // (for per-atom energy and virial calc.) if (evflag_atom) { - partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; if (vflag_atom) for (j = 0; j < 6; j++) - vatom[i][j] += ug[k] * (vg[k][j]*partial_peratom - vcik[j]); + vatom[i][j] += (ug[k]*muk[k][i]*vg[k][j]*partial_peratom - vcik[j]); } } } @@ -517,7 +515,7 @@ void EwaldDipole::compute(int eflag, int vflag) double uk, vk; for (k = 0; k < kcount; k++) { uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j] + ug[k]*vc[k][j]; + for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j] - vc[k][j]; } for (j = 0; j < 6; j++) virial[j] *= muscale; } diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp index 3554f66f36..4313f7b57b 100644 --- a/src/KSPACE/ewald_dipole_spin.cpp +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -428,13 +428,14 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) // taking im of struct_fact x exp(i*k*ri) (for force calc.) partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); - ek[i][0] += partial*eg[k][0]; - ek[i][1] += partial*eg[k][1]; - ek[i][2] += partial*eg[k][2]; + ek[i][0] += partial * eg[k][0]; + ek[i][1] += partial * eg[k][1]; + ek[i][2] += partial * eg[k][2]; // compute field for torque calculation - partial2 = exprl*sfacrl_all[k] + expim*sfacim_all[k]; + //partial2 = exprl*sfacrl_all[k] + expim*sfacim_all[k]; + partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; tk[i][0] += partial2*eg[k][0]; tk[i][1] += partial2*eg[k][1]; tk[i][2] += partial2*eg[k][2]; @@ -445,22 +446,23 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) spy = sp[i][1]*sp[i][3]; spz = sp[i][2]*sp[i][3]; - vc[k][0] += vcik[0] = partial2 * spx * kx; - vc[k][1] += vcik[1] = partial2 * spy * ky; - vc[k][2] += vcik[2] = partial2 * spz * kz; - vc[k][3] += vcik[3] = partial2 * spx * ky; - vc[k][4] += vcik[4] = partial2 * spx * kz; - vc[k][5] += vcik[5] = partial2 * spy * kz; + vc[k][0] += vcik[0] = -(partial_peratom * spx * eg[k][0]); + vc[k][1] += vcik[1] = -(partial_peratom * spy * eg[k][1]); + vc[k][2] += vcik[2] = -(partial_peratom * spz * eg[k][2]); + vc[k][3] += vcik[3] = -(partial_peratom * spx * eg[k][1]); + vc[k][4] += vcik[4] = -(partial_peratom * spx * eg[k][2]); + vc[k][5] += vcik[5] = -(partial_peratom * spy * eg[k][2]); // taking re-part of struct_fact x exp(i*k*ri) // (for per-atom energy and virial calc.) if (evflag_atom) { - partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; + //partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; if (vflag_atom) for (j = 0; j < 6; j++) - vatom[i][j] += ug[k] * (vg[k][j]*partial_peratom - vcik[j]); + vatom[i][j] += (ug[k]*muk[k][i]*vg[k][j]*partial_peratom - vcik[j]); + //vatom[i][j] += ug[k] * (vg[k][j]*partial_peratom - vcik[j]); } } } @@ -498,7 +500,7 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) double uk, vk; for (k = 0; k < kcount; k++) { uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]); - for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j] + ug[k]*vc[k][j]; + for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j] - vc[k][j]; } for (j = 0; j < 6; j++) virial[j] *= spscale; } @@ -529,7 +531,7 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) } /* ---------------------------------------------------------------------- - compute the + compute the struc. factors and mu dot k products ------------------------------------------------------------------------- */ void EwaldDipoleSpin::eik_dot_r() diff --git a/src/SPIN/pair_spin_dipolar_cut.cpp b/src/SPIN/pair_spin_dipolar_cut.cpp index 2c44b25fbf..b8927d62e9 100644 --- a/src/SPIN/pair_spin_dipolar_cut.cpp +++ b/src/SPIN/pair_spin_dipolar_cut.cpp @@ -65,17 +65,12 @@ lockfixnvespin(NULL) lattice_flag = 0; hbar = force->hplanck/MY_2PI; // eV/(rad.THz) - //mub = 5.78901e-5; // in eV/T - //mu_0 = 1.2566370614e-6; // in T.m/A mub = 9.274e-4; // in A.Ang^2 mu_0 = 785.15; // in eV/Ang/A^2 mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV.Ang^3 - //mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0 = mub * mub * mu_0 / (4.0*MY_PI); // in eV mub2mu0hbinv = mub2mu0 / hbar; // in rad.THz - //printf("hbar: %g, mub2mu0hbinv: %g \n",hbar,mub2mu0hbinv); - } /* ---------------------------------------------------------------------- @@ -103,6 +98,9 @@ void PairSpinDipolarCut::settings(int narg, char **arg) if (strcmp(update->unit_style,"metal") != 0) error->all(FLERR,"Spin simulations require metal unit style"); + if (!atom->sp) + error->all(FLERR,"Pair/spin style requires atom attribute sp"); + cut_spin_long_global = force->numeric(FLERR,arg[0]); // reset cutoffs that have been explicitly set @@ -234,7 +232,7 @@ void PairSpinDipolarCut::compute(int eflag, int vflag) int i,j,ii,jj,inum,jnum,itype,jtype; double rinv,r2inv,r3inv,rsq; double evdwl,ecoul; - double xi[3],rij[3]; + double xi[3],rij[3],eij[3]; double spi[4],spj[4],fi[3],fmi[3]; double local_cut2; int *ilist,*jlist,*numneigh,**firstneigh; @@ -282,6 +280,7 @@ void PairSpinDipolarCut::compute(int eflag, int vflag) spj[2] = sp[j][2]; spj[3] = sp[j][3]; + evdwl = 0.0; fi[0] = fi[1] = fi[2] = 0.0; fmi[0] = fmi[1] = fmi[2] = 0.0; @@ -289,16 +288,19 @@ void PairSpinDipolarCut::compute(int eflag, int vflag) rij[1] = x[j][1] - xi[1]; rij[2] = x[j][2] - xi[2]; rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + rinv = 1.0/sqrt(rsq); + eij[0] = rij[0]*rinv; + eij[1] = rij[1]*rinv; + eij[2] = rij[2]*rinv; local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; if (rsq < local_cut2) { r2inv = 1.0/rsq; - rinv = sqrt(r2inv); r3inv = r2inv*rinv; - compute_dipolar(i,j,rij,fmi,spi,spj,r3inv); - if (lattice_flag) compute_dipolar_mech(i,j,rij,fmi,spi,spj,r2inv); + compute_dipolar(i,j,eij,fmi,spi,spj,r3inv); + if (lattice_flag) compute_dipolar_mech(i,j,eij,fi,spi,spj,r2inv); } // force accumulation @@ -318,13 +320,11 @@ void PairSpinDipolarCut::compute(int eflag, int vflag) if (eflag) { if (rsq <= local_cut2) { - evdwl -= spi[0]*fmi[0] + spi[1]*fmi[1] + - spi[2]*fmi[2]; + evdwl -= (spi[0]*fmi[0] + spi[1]*fmi[1] + spi[2]*fmi[2]); evdwl *= hbar; } } else evdwl = 0.0; - if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair, evdwl,ecoul,fi[0],fi[1],fi[2],rij[0],rij[1],rij[2]); @@ -342,7 +342,7 @@ void PairSpinDipolarCut::compute_single_pair(int ii, double fmi[3]) { int i,j,jj,jnum,itype,jtype; double rsq,rinv,r2inv,r3inv; - double xi[3],rij[3]; + double xi[3],rij[3],eij[3]; double spi[4],spj[4]; double local_cut2; int *ilist,*jlist,*numneigh,**firstneigh; @@ -384,44 +384,41 @@ void PairSpinDipolarCut::compute_single_pair(int ii, double fmi[3]) rij[1] = x[j][1] - xi[1]; rij[2] = x[j][2] - xi[2]; rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + rinv = 1.0/sqrt(rsq); + eij[0] = rij[0]*rinv; + eij[1] = rij[1]*rinv; + eij[2] = rij[2]*rinv; local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; if (rsq < local_cut2) { r2inv = 1.0/rsq; - rinv = sqrt(r2inv); r3inv = r2inv*rinv; // compute dipolar interaction - compute_dipolar(i,j,rij,fmi,spi,spj,r3inv); + compute_dipolar(i,j,eij,fmi,spi,spj,r3inv); } } - - //printf("test fm: %g, %g, %g \n",fmi[0],fmi[1],fmi[2]); - - //fmi[0] *= mub2mu0hbinv; - //fmi[1] *= mub2mu0hbinv; - //fmi[2] *= mub2mu0hbinv; } /* ---------------------------------------------------------------------- compute dipolar interaction between spins i and j ------------------------------------------------------------------------- */ -void PairSpinDipolarCut::compute_dipolar(int i, int j, double rij[3], +void PairSpinDipolarCut::compute_dipolar(int i, int j, double eij[3], double fmi[3], double spi[4], double spj[4], double r3inv) { double sjdotr; - double gigjri3,pre; + double gigjiri3,pre; - sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; - gigjri3 = (spi[3] * spj[3])*r3inv; - pre = mub2mu0hbinv * gigjri3 / 4.0 / MY_PI; + sjdotr = spj[0]*eij[0] + spj[1]*eij[1] + spj[2]*eij[2]; + gigjiri3 = (spi[3] * spj[3])*r3inv; + pre = mub2mu0hbinv * gigjiri3; - fmi[0] += pre * gigjri3 * (3.0 * sjdotr *rij[0] - spj[0]); - fmi[1] += pre * gigjri3 * (3.0 * sjdotr *rij[1] - spj[1]); - fmi[2] += pre * gigjri3 * (3.0 * sjdotr *rij[2] - spj[2]); + fmi[0] += pre * (3.0 * sjdotr *eij[0] - spj[0]); + fmi[1] += pre * (3.0 * sjdotr *eij[1] - spj[1]); + fmi[2] += pre * (3.0 * sjdotr *eij[2] - spj[2]); } /* ---------------------------------------------------------------------- @@ -429,25 +426,25 @@ void PairSpinDipolarCut::compute_dipolar(int i, int j, double rij[3], atom i and atom j ------------------------------------------------------------------------- */ -void PairSpinDipolarCut::compute_dipolar_mech(int i, int j, double rij[3], +void PairSpinDipolarCut::compute_dipolar_mech(int i, int j, double eij[3], double fi[3], double spi[3], double spj[3], double r2inv) { - double sdots,sidotr,sjdotr,b2,b3; + double sisj,sieij,sjeij; double gigjri4,bij,pre; - gigjri4 = (spi[3] * spj[3])/r2inv/r2inv; - sdots = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; - sidotr = spi[0]*rij[0] + spi[1]*rij[1] + spi[2]*rij[2]; - sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + gigjri4 = (spi[3] * spj[3])*r2inv*r2inv; + sisj = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; + sieij = spi[0]*eij[0] + spi[1]*eij[1] + spi[2]*eij[2]; + sjeij = spj[0]*eij[0] + spj[1]*eij[1] + spj[2]*eij[2]; + + bij = sisj - 5.0*sieij*sjeij; + pre = mub2mu0*gigjri4; - bij = sdots - 5.0 * sidotr*sjdotr; - pre = mub2mu0 * bij / 4.0 / MY_PI; - fi[0] += pre * (rij[0] * bij + (sjdotr*spi[0] + sidotr*spj[0])); - fi[1] += pre * (rij[1] * bij + (sjdotr*spi[1] + sidotr*spj[1])); - fi[2] += pre * (rij[2] * bij + (sjdotr*spi[2] + sidotr*spj[2])); + fi[0] += pre * (eij[0] * bij + (sjeij*spi[0] + sieij*spj[0])); + fi[1] += pre * (eij[1] * bij + (sjeij*spi[1] + sieij*spj[1])); + fi[2] += pre * (eij[2] * bij + (sjeij*spi[2] + sieij*spj[2])); } - /* ---------------------------------------------------------------------- allocate all arrays ------------------------------------------------------------------------- */ -- GitLab From d66a1ac054222c06cb95285f364127e6bb9ee815 Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 13 Nov 2018 17:03:32 -0700 Subject: [PATCH 0061/1243] Commit JT 111318 - corrections pair/spin/dipolar/long --- examples/SPIN/pppm_spin/in.dipole.pppm_dipole | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole index 86ac5198b0..d029d0a97c 100644 --- a/examples/SPIN/pppm_spin/in.dipole.pppm_dipole +++ b/examples/SPIN/pppm_spin/in.dipole.pppm_dipole @@ -28,7 +28,7 @@ pair_coeff * * 0.0 0.0 #kspace_style pppm/disp 1.0e-4 #kspace_style pppm/dipole 1.0e-4 kspace_style ewald/dipole 1.0e-4 -#kspace_modify gewald 0.1 +#kspace_modify compute yes gewald 0.1 neighbor 0.3 bin neigh_modify every 2 delay 4 check yes -- GitLab From ddd5e61254d0f2b263ae0fe2bd30ab77470d66e8 Mon Sep 17 00:00:00 2001 From: julient31 Date: Wed, 14 Nov 2018 09:46:16 -0700 Subject: [PATCH 0062/1243] Commit JT 111418 - removed muk table (size kmax3d, mem fault) --- src/KSPACE/ewald_dipole.cpp | 91 +++++++++++++++-------------- src/KSPACE/ewald_dipole.h | 2 +- src/KSPACE/ewald_dipole_spin.cpp | 98 ++++++++++++++++---------------- 3 files changed, 95 insertions(+), 96 deletions(-) diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index 92470eb4a8..0cd5c95a9b 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -45,11 +45,10 @@ using namespace MathSpecial; /* ---------------------------------------------------------------------- */ EwaldDipole::EwaldDipole(LAMMPS *lmp, int narg, char **arg) : Ewald(lmp, narg, arg), - muk(NULL), tk(NULL), vc(NULL) + tk(NULL), vc(NULL) { ewaldflag = dipoleflag = 1; group_group_enable = 0; - muk = NULL; tk = NULL; vc = NULL; } @@ -60,7 +59,6 @@ EwaldDipole::EwaldDipole(LAMMPS *lmp, int narg, char **arg) : Ewald(lmp, narg, a EwaldDipole::~EwaldDipole() { - memory->destroy(muk); memory->destroy(tk); memory->destroy(vc); } @@ -326,14 +324,12 @@ void EwaldDipole::setup() memory->destroy(vc); memory->destroy3d_offset(cs,-kmax_created); memory->destroy3d_offset(sn,-kmax_created); - memory->destroy(muk); nmax = atom->nmax; memory->create(ek,nmax,3,"ewald_dipole:ek"); memory->create(tk,nmax,3,"ewald_dipole:tk"); memory->create(vc,kmax3d,6,"ewald_dipole:tk"); memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald_dipole:cs"); memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald_dipole:sn"); - memory->create(muk,kmax3d,nmax,"ewald_dipole:muk"); kmax_created = kmax; } @@ -393,14 +389,12 @@ void EwaldDipole::compute(int eflag, int vflag) memory->destroy(vc); memory->destroy3d_offset(cs,-kmax_created); memory->destroy3d_offset(sn,-kmax_created); - memory->destroy(muk); nmax = atom->nmax; memory->create(ek,nmax,3,"ewald_dipole:ek"); memory->create(tk,nmax,3,"ewald_dipole:tk"); memory->create(vc,kmax3d,6,"ewald_dipole:tk"); memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald_dipole:cs"); memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald_dipole:sn"); - memory->create(muk,kmax3d,nmax,"ewald_dipole:muk"); kmax_created = kmax; } @@ -425,6 +419,7 @@ void EwaldDipole::compute(int eflag, int vflag) double cypz,sypz,exprl,expim; double partial,partial2,partial_peratom; double vcik[6]; + double mudotk; for (i = 0; i < nlocal; i++) { ek[i][0] = ek[i][1] = ek[i][2] = 0.0; @@ -440,6 +435,9 @@ void EwaldDipole::compute(int eflag, int vflag) for (i = 0; i < nlocal; i++) { for (j = 0; j<6; j++) vcik[j] = 0.0; + + // re-evaluating mu dot k + mudotk = mu[i][0]*kx*unitk[0] + mu[i][1]*ky*unitk[1] + mu[i][2]*kz*unitk[2]; // calculating re and im of exp(i*k*ri) @@ -450,7 +448,7 @@ void EwaldDipole::compute(int eflag, int vflag) // taking im of struct_fact x exp(i*k*ri) (for force calc.) - partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); + partial = (mudotk)*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); ek[i][0] += partial * eg[k][0]; ek[i][1] += partial * eg[k][1]; ek[i][2] += partial * eg[k][2]; @@ -475,10 +473,10 @@ void EwaldDipole::compute(int eflag, int vflag) // (for per-atom energy and virial calc.) if (evflag_atom) { - if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; + if (eflag_atom) eatom[i] += mudotk*ug[k]*partial_peratom; if (vflag_atom) for (j = 0; j < 6; j++) - vatom[i][j] += (ug[k]*muk[k][i]*vg[k][j]*partial_peratom - vcik[j]); + vatom[i][j] += (ug[k]*mudotk*vg[k][j]*partial_peratom - vcik[j]); } } } @@ -552,6 +550,7 @@ void EwaldDipole::eik_dot_r() double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4; double sqk,clpm,slpm; double mux, muy, muz; + double mudotk; double **x = atom->x; double **mu = atom->mu; @@ -582,9 +581,9 @@ void EwaldDipole::eik_dot_r() sn[1][ic][i] = sin(unitk[ic]*x[i][ic]); cs[-1][ic][i] = cs[1][ic][i]; sn[-1][ic][i] = -sn[1][ic][i]; - muk[n][i] = (mu[i][ic]*unitk[ic]); - cstr1 += muk[n][i]*cs[1][ic][i]; - sstr1 += muk[n][i]*sn[1][ic][i]; + mudotk = (mu[i][ic]*unitk[ic]); + cstr1 += mudotk*cs[1][ic][i]; + sstr1 += mudotk*sn[1][ic][i]; } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -606,9 +605,9 @@ void EwaldDipole::eik_dot_r() cs[m-1][ic][i]*sn[1][ic][i]; cs[-m][ic][i] = cs[m][ic][i]; sn[-m][ic][i] = -sn[m][ic][i]; - muk[n][i] = (mu[i][ic]*m*unitk[ic]); - cstr1 += muk[n][i]*cs[m][ic][i]; - sstr1 += muk[n][i]*sn[m][ic][i]; + mudotk = (mu[i][ic]*m*unitk[ic]); + cstr1 += mudotk*cs[m][ic][i]; + sstr1 += mudotk*sn[m][ic][i]; } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -631,14 +630,14 @@ void EwaldDipole::eik_dot_r() muy = mu[i][1]; // dir 1: (k,l,0) - muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1]); - cstr1 += muk[n][i]*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); - sstr1 += muk[n][i]*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); + mudotk = (mux*k*unitk[0] + muy*l*unitk[1]); + cstr1 += mudotk*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); + sstr1 += mudotk*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); // dir 2: (k,-l,0) - muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1]); - cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); - sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); + mudotk = (mux*k*unitk[0] - muy*l*unitk[1]); + cstr2 += mudotk*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); + sstr2 += mudotk*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -663,14 +662,14 @@ void EwaldDipole::eik_dot_r() muz = mu[i][2]; // dir 1: (0,l,m) - muk[n][i] = (muy*l*unitk[1] + muz*m*unitk[2]); - cstr1 += muk[n][i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); - sstr1 += muk[n][i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); + mudotk = (muy*l*unitk[1] + muz*m*unitk[2]); + cstr1 += mudotk*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); + sstr1 += mudotk*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); // dir 2: (0,l,-m) - muk[n+1][i] = (muy*l*unitk[1] - muz*m*unitk[2]); - cstr2 += muk[n+1][i]*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); - sstr2 += muk[n+1][i]*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); + mudotk = (muy*l*unitk[1] - muz*m*unitk[2]); + cstr2 += mudotk*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); + sstr2 += mudotk*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -695,14 +694,14 @@ void EwaldDipole::eik_dot_r() muz = mu[i][2]; // dir 1: (k,0,m) - muk[n][i] = (mux*k*unitk[0] + muz*m*unitk[2]); - cstr1 += muk[n][i]*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); - sstr1 += muk[n][i]*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); + mudotk = (mux*k*unitk[0] + muz*m*unitk[2]); + cstr1 += mudotk*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); + sstr1 += mudotk*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); // dir 2: (k,0,-m) - muk[n+1][i] = (mux*k*unitk[0] - muz*m*unitk[2]); - cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); - sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); + mudotk = (mux*k*unitk[0] - muz*m*unitk[2]); + cstr2 += mudotk*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); + sstr2 += mudotk*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -734,32 +733,32 @@ void EwaldDipole::eik_dot_r() muz = mu[i][2]; // dir 1: (k,l,m) - muk[n][i] = (mux*k*unitk[0] + muy*l*unitk[1] + muz*m*unitk[2]); + mudotk = (mux*k*unitk[0] + muy*l*unitk[1] + muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; - cstr1 += muk[n][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr1 += muk[n][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr1 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr1 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); // dir 2: (k,-l,m) - muk[n+1][i] = (mux*k*unitk[0] - muy*l*unitk[1] + muz*m*unitk[2]); + mudotk = (mux*k*unitk[0] - muy*l*unitk[1] + muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; - cstr2 += muk[n+1][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr2 += muk[n+1][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr2 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr2 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); // dir 3: (k,l,-m) - muk[n+2][i] = (mux*k*unitk[0] + muy*l*unitk[1] - muz*m*unitk[2]); + mudotk = (mux*k*unitk[0] + muy*l*unitk[1] - muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; - cstr3 += muk[n+2][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr3 += muk[n+2][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr3 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr3 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); // dir 4: (k,-l,-m) - muk[n+3][i] = (mux*k*unitk[0] - muy*l*unitk[1] - muz*m*unitk[2]); + mudotk = (mux*k*unitk[0] - muy*l*unitk[1] - muz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; - cstr4 += muk[n+3][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr4 += muk[n+3][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr4 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr4 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; diff --git a/src/KSPACE/ewald_dipole.h b/src/KSPACE/ewald_dipole.h index 0a57f86d00..77c0af11c2 100644 --- a/src/KSPACE/ewald_dipole.h +++ b/src/KSPACE/ewald_dipole.h @@ -34,7 +34,7 @@ class EwaldDipole : public Ewald { protected: double musum,musqsum,mu2; - double **muk; // mu_i dot k + //double **muk; // mu_i dot k double **tk; // field for torque double **vc; // virial per k diff --git a/src/KSPACE/ewald_dipole_spin.cpp b/src/KSPACE/ewald_dipole_spin.cpp index 4313f7b57b..e6cfbfbaa6 100644 --- a/src/KSPACE/ewald_dipole_spin.cpp +++ b/src/KSPACE/ewald_dipole_spin.cpp @@ -318,14 +318,12 @@ void EwaldDipoleSpin::setup() memory->destroy(vc); memory->destroy3d_offset(cs,-kmax_created); memory->destroy3d_offset(sn,-kmax_created); - memory->destroy(muk); nmax = atom->nmax; memory->create(ek,nmax,3,"ewald_dipole_spin:ek"); memory->create(tk,nmax,3,"ewald_dipole_spin:tk"); memory->create(vc,kmax3d,6,"ewald_dipole_spin:tk"); memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald_dipole_spin:cs"); memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald_dipole_spin:sn"); - memory->create(muk,kmax3d,nmax,"ewald_dipole_spin:muk"); kmax_created = kmax; } @@ -369,14 +367,12 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) memory->destroy(vc); memory->destroy3d_offset(cs,-kmax_created); memory->destroy3d_offset(sn,-kmax_created); - memory->destroy(muk); nmax = atom->nmax; memory->create(ek,nmax,3,"ewald_dipole_spin:ek"); memory->create(tk,nmax,3,"ewald_dipole_spin:tk"); memory->create(vc,kmax3d,6,"ewald_dipole_spin:tk"); memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald_dipole_spin:cs"); memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald_dipole_spin:sn"); - memory->create(muk,kmax3d,nmax,"ewald_dipole_spin:muk"); kmax_created = kmax; } @@ -401,6 +397,7 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) double cypz,sypz,exprl,expim; double partial,partial2,partial_peratom; double vcik[6]; + double mudotk; for (i = 0; i < nlocal; i++) { ek[i][0] = ek[i][1] = ek[i][2] = 0.0; @@ -415,8 +412,14 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) for (i = 0; i < nlocal; i++) { - vcik[0] = vcik[1] = vcik[2] = 0.0; - vcik[3] = vcik[4] = vcik[5] = 0.0; + for (j = 0; j<6; j++) vcik[j] = 0.0; + + // re-evaluating sp dot k + + spx = sp[i][0]*sp[i][3]; + spy = sp[i][1]*sp[i][3]; + spz = sp[i][2]*sp[i][3]; + mudotk = spx*kx*unitk[0] + spy*ky*unitk[1] + spz*kz*unitk[2]; // calculating re and im of exp(i*k*ri) @@ -427,7 +430,7 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) // taking im of struct_fact x exp(i*k*ri) (for force calc.) - partial = (muk[k][i])*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); + partial = mudotk*(expim*sfacrl_all[k] - exprl*sfacim_all[k]); ek[i][0] += partial * eg[k][0]; ek[i][1] += partial * eg[k][1]; ek[i][2] += partial * eg[k][2]; @@ -442,10 +445,6 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) // total and per-atom virial correction - spx = sp[i][0]*sp[i][3]; - spy = sp[i][1]*sp[i][3]; - spz = sp[i][2]*sp[i][3]; - vc[k][0] += vcik[0] = -(partial_peratom * spx * eg[k][0]); vc[k][1] += vcik[1] = -(partial_peratom * spy * eg[k][1]); vc[k][2] += vcik[2] = -(partial_peratom * spz * eg[k][2]); @@ -458,10 +457,10 @@ void EwaldDipoleSpin::compute(int eflag, int vflag) if (evflag_atom) { //partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k]; - if (eflag_atom) eatom[i] += muk[k][i]*ug[k]*partial_peratom; + if (eflag_atom) eatom[i] += mudotk*ug[k]*partial_peratom; if (vflag_atom) for (j = 0; j < 6; j++) - vatom[i][j] += (ug[k]*muk[k][i]*vg[k][j]*partial_peratom - vcik[j]); + vatom[i][j] += (ug[k]*mudotk*vg[k][j]*partial_peratom - vcik[j]); //vatom[i][j] += ug[k] * (vg[k][j]*partial_peratom - vcik[j]); } } @@ -540,6 +539,7 @@ void EwaldDipoleSpin::eik_dot_r() double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4; double sqk,clpm,slpm; double spx, spy, spz, spi; + double mudotk; double **x = atom->x; double **sp = atom->sp; @@ -571,9 +571,9 @@ void EwaldDipoleSpin::eik_dot_r() cs[-1][ic][i] = cs[1][ic][i]; sn[-1][ic][i] = -sn[1][ic][i]; spi = sp[i][ic]*sp[i][3]; - muk[n][i] = (spi*unitk[ic]); - cstr1 += muk[n][i]*cs[1][ic][i]; - sstr1 += muk[n][i]*sn[1][ic][i]; + mudotk = (spi*unitk[ic]); + cstr1 += mudotk*cs[1][ic][i]; + sstr1 += mudotk*sn[1][ic][i]; } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -596,9 +596,9 @@ void EwaldDipoleSpin::eik_dot_r() cs[-m][ic][i] = cs[m][ic][i]; sn[-m][ic][i] = -sn[m][ic][i]; spi = sp[i][ic]*sp[i][3]; - muk[n][i] = (spi*m*unitk[ic]); - cstr1 += muk[n][i]*cs[m][ic][i]; - sstr1 += muk[n][i]*sn[m][ic][i]; + mudotk = (spi*m*unitk[ic]); + cstr1 += mudotk*cs[m][ic][i]; + sstr1 += mudotk*sn[m][ic][i]; } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -621,14 +621,14 @@ void EwaldDipoleSpin::eik_dot_r() spy = sp[i][1]*sp[i][3]; // dir 1: (k,l,0) - muk[n][i] = (spx*k*unitk[0] + spy*l*unitk[1]); - cstr1 += muk[n][i]*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); - sstr1 += muk[n][i]*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); + mudotk = (spx*k*unitk[0] + spy*l*unitk[1]); + cstr1 += mudotk*(cs[k][0][i]*cs[l][1][i]-sn[k][0][i]*sn[l][1][i]); + sstr1 += mudotk*(sn[k][0][i]*cs[l][1][i]+cs[k][0][i]*sn[l][1][i]); // dir 2: (k,-l,0) - muk[n+1][i] = (spx*k*unitk[0] - spy*l*unitk[1]); - cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); - sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); + mudotk = (spx*k*unitk[0] - spy*l*unitk[1]); + cstr2 += mudotk*(cs[k][0][i]*cs[l][1][i]+sn[k][0][i]*sn[l][1][i]); + sstr2 += mudotk*(sn[k][0][i]*cs[l][1][i]-cs[k][0][i]*sn[l][1][i]); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -653,14 +653,14 @@ void EwaldDipoleSpin::eik_dot_r() spz = sp[i][2]*sp[i][3]; // dir 1: (0,l,m) - muk[n][i] = (spy*l*unitk[1] + spz*m*unitk[2]); - cstr1 += muk[n][i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); - sstr1 += muk[n][i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); + mudotk = (spy*l*unitk[1] + spz*m*unitk[2]); + cstr1 += mudotk*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]); + sstr1 += mudotk*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]); // dir 2: (0,l,-m) - muk[n+1][i] = (spy*l*unitk[1] - spz*m*unitk[2]); - cstr2 += muk[n+1][i]*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); - sstr2 += muk[n+1][i]*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); + mudotk = (spy*l*unitk[1] - spz*m*unitk[2]); + cstr2 += mudotk*(cs[l][1][i]*cs[m][2][i]+sn[l][1][i]*sn[m][2][i]); + sstr2 += mudotk*(sn[l][1][i]*cs[m][2][i]-cs[l][1][i]*sn[m][2][i]); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -685,14 +685,14 @@ void EwaldDipoleSpin::eik_dot_r() spz = sp[i][2]*sp[i][3]; // dir 1: (k,0,m) - muk[n][i] = (spx*k*unitk[0] + spz*m*unitk[2]); - cstr1 += muk[n][i]*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); - sstr1 += muk[n][i]*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); + mudotk = (spx*k*unitk[0] + spz*m*unitk[2]); + cstr1 += mudotk*(cs[k][0][i]*cs[m][2][i]-sn[k][0][i]*sn[m][2][i]); + sstr1 += mudotk*(sn[k][0][i]*cs[m][2][i]+cs[k][0][i]*sn[m][2][i]); // dir 2: (k,0,-m) - muk[n+1][i] = (spx*k*unitk[0] - spz*m*unitk[2]); - cstr2 += muk[n+1][i]*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); - sstr2 += muk[n+1][i]*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); + mudotk = (spx*k*unitk[0] - spz*m*unitk[2]); + cstr2 += mudotk*(cs[k][0][i]*cs[m][2][i]+sn[k][0][i]*sn[m][2][i]); + sstr2 += mudotk*(sn[k][0][i]*cs[m][2][i]-cs[k][0][i]*sn[m][2][i]); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; @@ -724,32 +724,32 @@ void EwaldDipoleSpin::eik_dot_r() spz = sp[i][2]*sp[i][3]; // dir 1: (k,l,m) - muk[n][i] = (spx*k*unitk[0] + spy*l*unitk[1] + spz*m*unitk[2]); + mudotk = (spx*k*unitk[0] + spy*l*unitk[1] + spz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; - cstr1 += muk[n][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr1 += muk[n][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr1 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr1 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); // dir 2: (k,-l,m) - muk[n+1][i] = (spx*k*unitk[0] - spy*l*unitk[1] + spz*m*unitk[2]); + mudotk = (spx*k*unitk[0] - spy*l*unitk[1] + spz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]; - cstr2 += muk[n+1][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr2 += muk[n+1][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr2 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr2 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); // dir 3: (k,l,-m) - muk[n+2][i] = (spx*k*unitk[0] + spy*l*unitk[1] - spz*m*unitk[2]); + mudotk = (spx*k*unitk[0] + spy*l*unitk[1] - spz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]; slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; - cstr3 += muk[n+2][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr3 += muk[n+2][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr3 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr3 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); // dir 4: (k,-l,-m) - muk[n+3][i] = (spx*k*unitk[0] - spy*l*unitk[1] - spz*m*unitk[2]); + mudotk = (spx*k*unitk[0] - spy*l*unitk[1] - spz*m*unitk[2]); clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]; slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]; - cstr4 += muk[n+3][i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); - sstr4 += muk[n+3][i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); + cstr4 += mudotk*(cs[k][0][i]*clpm - sn[k][0][i]*slpm); + sstr4 += mudotk*(sn[k][0][i]*clpm + cs[k][0][i]*slpm); } sfacrl[n] = cstr1; sfacim[n++] = sstr1; -- GitLab From 03b1129abde8d85fe20dd450a43976aca8fe623a Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 14 Nov 2018 13:11:47 -0500 Subject: [PATCH 0063/1243] Update pair_kim to check for ModelRoutine requirements Also fixup cmake settings for PKG_KIM --- cmake/CMakeLists.txt | 2 +- src/KIM/pair_kim.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++ src/KIM/pair_kim.h | 1 + 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 3e6c57c667..1e0d207a7e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -609,7 +609,7 @@ if(PKG_KIM) message(FATAL_ERROR "KIM not found, help CMake to find it by setting PKG_CONFIG_PATH, or set DOWNLOAD_KIM=ON to download it") endif() endif() - list(APPEND LAMMPS_LINK_LIBS ${KIM-API-V2_LIBRARIES}) + list(APPEND LAMMPS_LINK_LIBS "${KIM-API-V2_LDFLAGS}") include_directories(${KIM-API-V2_INCLUDE_DIRS}) endif() diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 072c3a6296..6981b028b2 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -789,6 +789,14 @@ void PairKIM::kim_init() error->all(FLERR,"KIM Model did not accept the requested unit system"); } + // check that the model does not require unknown capabilities + kimerror = check_for_routine_compatibility(); + if (kimerror) + { + error->all(FLERR, + "KIM Model requires unknown Routines. Unable to proceed."); + } + kimerror = KIM_Model_ComputeArgumentsCreate(pkim, &pargs); if (kimerror) { @@ -987,6 +995,49 @@ void PairKIM::set_lmps_flags() /* ---------------------------------------------------------------------- */ +int PairKIM::check_for_routine_compatibility() +{ + /* Check that we know about all required routines */ + int numberOfModelRoutineNames; + KIM_MODEL_ROUTINE_NAME_GetNumberOfModelRoutineNames( + &numberOfModelRoutineNames); + for (int i = 0; i < numberOfModelRoutineNames; ++i) + { + KIM_ModelRoutineName modelRoutineName; + KIM_MODEL_ROUTINE_NAME_GetModelRoutineName(i, &modelRoutineName); + + int present; + int required; + int error = KIM_Model_IsRoutinePresent( + pkim, modelRoutineName, &present, &required); + if (error) { return true; } + + if ((present == true) && (required == true)) + { + if (!(KIM_ModelRoutineName_Equal(modelRoutineName, + KIM_MODEL_ROUTINE_NAME_Create) + || KIM_ModelRoutineName_Equal( + modelRoutineName, + KIM_MODEL_ROUTINE_NAME_ComputeArgumentsCreate) + || KIM_ModelRoutineName_Equal(modelRoutineName, + KIM_MODEL_ROUTINE_NAME_Compute) + || KIM_ModelRoutineName_Equal(modelRoutineName, + KIM_MODEL_ROUTINE_NAME_Refresh) + || KIM_ModelRoutineName_Equal( + modelRoutineName, + KIM_MODEL_ROUTINE_NAME_ComputeArgumentsDestroy) + || KIM_ModelRoutineName_Equal(modelRoutineName, + KIM_MODEL_ROUTINE_NAME_Destroy))) + { return true; } + } + } + + /* everything is good */ + return false; +} + +/* ---------------------------------------------------------------------- */ + void PairKIM::set_kim_model_has_flags() { int numberOfComputeArgumentNames; diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 1b8051ea1e..a23d5cd317 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -158,6 +158,7 @@ namespace LAMMPS_NS { virtual void set_argument_pointers(); virtual void set_lmps_flags(); virtual void set_kim_model_has_flags(); + virtual int check_for_routine_compatibility(); // static methods used as callbacks from KIM static int get_neigh( void const * const dataObject, -- GitLab From c59b3439c682430e063270b42fa58b51e2ec167d Mon Sep 17 00:00:00 2001 From: Cyril Falvo Date: Tue, 3 Jul 2018 16:07:15 +0200 Subject: [PATCH 0064/1243] changes the values of some parameters in REBO in accordance to the original Brenner paper --- potentials/CH.rebo | 37595 +++++++++++++++++++++++++++++++++++ src/MANYBODY/pair_rebo.cpp | 260 +- src/MANYBODY/pair_rebo.h | 1 + 3 files changed, 37853 insertions(+), 3 deletions(-) create mode 100644 potentials/CH.rebo diff --git a/potentials/CH.rebo b/potentials/CH.rebo new file mode 100644 index 0000000000..08b1b19dc2 --- /dev/null +++ b/potentials/CH.rebo @@ -0,0 +1,37595 @@ +# DATE: 2018-7-3 CONTRIBUTOR: Cyril Falvo, cyril.falvo@u-psud.fr +# REBO2 Brenner potential modified from CH.airebo +# Cite as D. W. Brenner, O. A. Shenderova, J. A. Harrison, S. J. Stuart, B. Ni, and S. B. Sinnott, +# "A second- generation reactive empirical bond order (rebo) potential energy expression for hydrocarbons.", +# J. Phys. Cond. Mat., 14:783, 2002. + +1.7 rcmin_CC +1.3 rcmin_CH +1.1 rcmin_HH +2.0 rcmax_CC +1.8 rcmax_CH +1.7 rcmax_HH +2.0 rcmaxp_CC +1.6 rcmaxp_CH +1.7 rcmaxp_HH +0.1 smin +2.0 Nmin +3.0 Nmax +3.2 NCmin +3.7 NCmax +0.3134602960833 Q_CC +0.340775728 Q_CH +0.370471487045 Q_HH +4.7465390606595 alpha_CC +4.10254983 alpha_CH +3.536298648 alpha_HH +10953.544162170 A_CC +149.94098723 A_CH +32.817355747 A_HH +12388.79197798 BIJc_CC1 +17.56740646509 BIJc_CC2 +30.71493208065 BIJc_CC3 +32.3551866587 BIJc_CH1 +0.0 BIJc_CH2 +0.0 BIJc_CH3 +29.632593 BIJc_HH1 +0.0 BIJc_HH2 +0.0 BIJc_HH3 +4.7204523127 Beta_CC1 +1.4332132499 Beta_CC2 +1.3826912506 Beta_CC3 +1.434458059249837 Beta_CH1 +0.0 Beta_CH2 +0.0 Beta_CH3 +1.71589217 Beta_HH1 +1.0 Beta_HH2 +1.0 Beta_HH3 +0.0 rho_CC +1.09 rho_CH +0.7415887 rho_HH +3.4 rcLJmin_CC +3.025 rcLJmin_CH +2.65 rcLJmin_HH +3.816370964 rcLJmax_CC +3.395447696 rcLJmax_CH +2.974524428 rcLJmax_HH +0.77 bLJmin_CC +0.75 bLJmin_CH +0.32 bLJmin_HH +0.81 bLJmax_CC +0.9 bLJmax_CH +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 +0.3078851086 epsilonT_CCCC +0.1786600912 epsilonT_CCCH +0.1249753356 epsilonT_HCCH + +# gC1 and gC2 + +5 +-1.0 +-0.6666666667 +-0.5 +-0.3333333333 +1.0 + + 0.2816950000 + 1.0627430000 + 2.1363075000 + 2.5334145000 + 1.5544035000 + 0.3862485000 + 0.2827390000 + 1.0718770000 + 2.1681365000 + 2.5885710000 + 1.6019100000 + 0.4025160000 + 0.6900250000 + 5.4601600000 + 23.0108000000 + 54.9086400000 + 68.6124000000 + 34.7051520000 + 0.2718560918 + 0.4892740137 + -0.4328177539 + -0.5616817383 + 1.2708702246 + -0.0375008379 + + 0.2816950000 + 1.0627430000 + 2.1363075000 + 2.5334145000 + 1.5544035000 + 0.3862485000 + 0.2827390000 + 1.0718770000 + 2.1681365000 + 2.5885710000 + 1.6019100000 + 0.4025160000 + 0.6900250000 + 5.4601600000 + 23.0108000000 + 54.9086400000 + 68.6124000000 + 34.7051520000 + 0.3754514434 + 1.4072691309 + 2.2551320117 + 2.0288747461 + 1.4269207324 + 0.5063519355 + +# gH + +4 +-1.0 +-0.8333333333 +-0.5 +1.0 + + 270.4568000026 + 1549.6358000143 + 3781.7719000316 + 4582.1544000348 + 2721.4308000191 + 630.6336000042 + 16.9534406250 + -21.0823875000 + -102.4683000000 + -210.6432299999 + -229.8471299999 + -94.9946400000 + 19.0650249321 + 2.0177562840 + -2.5664219198 + 3.2913322346 + -2.6535615062 + 0.8376699753 + +# pCC + +4 +0.0 +4.0 +0.0 +4.0 + + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0986400000 + 0.0657600000 + 0.0000000000 + 0.0000000000 + 0.0657600000 + -0.0438400000 + -0.0025000000 + 0.0060000000 + -0.0045000000 + 0.0010000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2339100000 + -0.6402960000 + 0.4802220000 + -0.1067160000 + -0.1559400000 + 0.4268640000 + -0.3201480000 + 0.0711440000 + 0.4650000000 + -0.5985000000 + 0.2493750000 + -0.0332500000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.9074060000 + 2.4787080000 + -1.0327950000 + 0.1377060000 + 1.2716040000 + -1.6524720000 + 0.6885300000 + -0.0918040000 + -1.2900000000 + 1.1610000000 + -0.3386250000 + 0.0322500000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.8700000000 + -3.4830000000 + 1.0158750000 + -0.0967500000 + -2.5800000000 + 2.3220000000 + -0.6772500000 + 0.0645000000 + -0.1380150000 + 0.0000000000 + 0.5932650000 + -0.3955100000 + 0.3312360000 + 0.0000000000 + -1.5027480000 + 1.0018320000 + -0.2484270000 + 0.0000000000 + 1.1270610000 + -0.7513740000 + 0.0552060000 + 0.0000000000 + -0.2504580000 + 0.1669720000 + -0.3654800000 + 1.0205280000 + -0.7653960000 + 0.1700880000 + 1.0582800000 + -2.9471040000 + 2.2103280000 + -0.4911840000 + -0.7937100000 + 2.2103280000 + -1.6577460000 + 0.3683880000 + 0.1763800000 + -0.4911840000 + 0.3683880000 + -0.0818640000 + 0.6832080000 + -0.9109440000 + 0.3795600000 + -0.0506080000 + -2.0496240000 + 2.7328320000 + -1.1386800000 + 0.1518240000 + 1.5372180000 + -2.0496240000 + 0.8540100000 + -0.1138680000 + -0.3416040000 + 0.4554720000 + -0.1897800000 + 0.0253040000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.7452810000 + 0.0000000000 + -2.4934230000 + 1.6622820000 + -0.9937080000 + 0.0000000000 + 3.3245640000 + -2.2163760000 + 0.4140450000 + 0.0000000000 + -1.3852350000 + 0.9234900000 + -0.0552060000 + 0.0000000000 + 0.1846980000 + -0.1231320000 + 0.3434400000 + -1.0303200000 + 0.7727400000 + -0.1717200000 + -0.4579200000 + 1.3737600000 + -1.0303200000 + 0.2289600000 + 0.1908000000 + -0.5724000000 + 0.4293000000 + -0.0954000000 + -0.0254400000 + 0.0763200000 + -0.0572400000 + 0.0127200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + +# pCH + +4 +0.0 +4.0 +0.0 +4.0 + + 0.0000000000 + 0.0000000000 + 0.6280110000 + -0.4186740000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0300000000 + 0.0000000000 + -3.1001400000 + 2.0667600000 + -0.0200000000 + 0.0000000000 + 2.0667600000 + -1.3778400000 + -1.1595980000 + 3.2854440000 + -2.4640830000 + 0.5475740000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4966950000 + -3.6001800000 + 2.7001350000 + -0.6000300000 + -0.3311300000 + 2.4001200000 + -1.8000900000 + 0.4000200000 + -6.7698340000 + 8.6212080000 + -3.5921700000 + 0.4789560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 44.5208070000 + -58.1453640000 + 24.2272350000 + -3.2302980000 + -29.6805380000 + 38.7635760000 + -16.1514900000 + 2.1535320000 + 24.3142400000 + -21.8828160000 + 6.3824880000 + -0.6078560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -72.9427200000 + 65.6484480000 + -19.1474640000 + 1.8235680000 + 48.6284800000 + -43.7656320000 + 12.7649760000 + -1.2157120000 + -0.6502100000 + 0.0000000000 + -1.0558290000 + 0.7038860000 + 1.5845040000 + 0.0000000000 + 1.5611040000 + -1.0407360000 + -1.1883780000 + 0.0000000000 + -1.1708280000 + 0.7805520000 + 0.2640840000 + 0.0000000000 + 0.2601840000 + -0.1734560000 + 9.9867120000 + -26.3732760000 + 19.7799570000 + -4.3955460000 + -26.3537880000 + 68.3007840000 + -51.2255880000 + 11.3834640000 + 19.7653410000 + -51.2255880000 + 38.4191910000 + -8.5375980000 + -4.3922980000 + 11.3834640000 + -8.5375980000 + 1.8972440000 + -32.2817400000 + 43.0423200000 + -17.9343000000 + 2.3912400000 + 96.8452200000 + -129.1269600000 + 53.8029000000 + -7.1737200000 + -72.6339150000 + 96.8452200000 + -40.3521750000 + 5.3802900000 + 16.1408700000 + -21.5211600000 + 8.9671500000 + -1.1956200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.3172460000 + 0.0000000000 + 40.2945870000 + -26.8630580000 + 6.6795480000 + 0.0000000000 + -52.4957760000 + 34.9971840000 + -2.7831450000 + 0.0000000000 + 21.8732400000 + -14.5821600000 + 0.3710860000 + 0.0000000000 + -2.9164320000 + 1.9442880000 + -32.4571320000 + 97.3713960000 + -73.0285470000 + 16.2285660000 + 43.2761760000 + -129.8285280000 + 97.3713960000 + -21.6380880000 + -18.0317400000 + 54.0952200000 + -40.5714150000 + 9.0158700000 + 2.4042320000 + -7.2126960000 + 5.4095220000 + -1.2021160000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 24.6068000000 + 0.0000000000 + -73.8204000000 + 49.2136000000 + -22.1461200000 + 0.0000000000 + 66.4383600000 + -44.2922400000 + 6.4592850000 + 0.0000000000 + -19.3778550000 + 12.9185700000 + -0.6151700000 + 0.0000000000 + 1.8455100000 + -1.2303400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + +# piCC + +6 +0.0 +4.0 +0.0 +4.0 +0.0 +9.0 + + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1952414550000000 + -0.1301609700000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1301609700000000 + 0.0867739800000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1952414550000000 + -0.1301609700000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2460512699999999 + -0.1640341799999999 + 0.0000000000000000 + 0.0000000000000000 + -0.1640341799999999 + 0.1093561200000001 + 0.0000000000000000 + 0.0000000000000000 + -0.1301609700000000 + 0.0867739800000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1640341799999999 + 0.1093561200000001 + 0.0000000000000000 + 0.0000000000000000 + 0.1093561200000001 + -0.0729040800000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1859428215000000 + 0.6024559355999999 + -0.4518419517000000 + 0.1004093226000000 + 0.1239618810000000 + -0.4016372904000000 + 0.3012279677999999 + -0.0669395484000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1859428215000000 + 0.6024559355999999 + -0.4518419517000000 + 0.1004093226000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3234498210000000 + 0.9186318863999997 + -0.6208630397999997 + 0.1076980643999998 + 0.2156332139999999 + -0.6124212575999999 + 0.4139086932000001 + -0.0717987096000001 + 0.1239618810000000 + -0.4016372904000000 + 0.3012279677999999 + -0.0669395484000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2156332139999999 + -0.6124212575999999 + 0.4139086932000001 + -0.0717987096000001 + -0.1437554760000001 + 0.4082808384000002 + -0.2759391288000001 + 0.0478658064000000 + 0.1388410212000000 + -0.1785098844000000 + 0.0743791185000000 + -0.0099172158000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4016472399000000 + 0.5355296532000000 + -0.2231373555000000 + 0.0297516474000000 + 0.2677648266000000 + -0.3570197688000000 + 0.1487582370000000 + -0.0198344316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4016472399000000 + 0.5355296532000000 + -0.2231373555000000 + 0.0297516474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 4.5450778986000007 + -5.3987902596000001 + 2.0451633165000001 + -0.2545255422000000 + -3.0300519324000001 + 3.5991935063999998 + -1.3634422110000000 + 0.1696836948000000 + 0.2677648266000000 + -0.3570197688000000 + 0.1487582370000000 + -0.0198344316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0300519324000001 + 3.5991935063999998 + -1.3634422110000000 + 0.1696836948000000 + 2.0200346216000002 + -2.3994623376000002 + 0.9089614740000000 + -0.1131224632000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1170126711000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0520056316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1170126711000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0520056316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1170126711000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0520056316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1170126711000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0520056316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1170126711000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0520056316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1170126711000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0780084474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0520056316000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1101605377500000 + -0.0734403585000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1081921266000000 + 0.0721280844000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0811440949500000 + -0.0540960633000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0180320211000000 + 0.0120213474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.5308662927499996 + 1.0205775285000001 + 0.0000000000000000 + 0.0000000000000000 + 4.2922496105999990 + -2.8614997404000002 + 0.0000000000000000 + 0.0000000000000000 + -3.1601247079499992 + 2.1067498053000002 + 0.0000000000000000 + 0.0000000000000000 + 0.6759999350999999 + -0.4506666234000001 + 0.0000000000000000 + 0.0000000000000000 + 1.0205775285000001 + -0.6803850190000000 + 0.0000000000000000 + 0.0000000000000000 + -2.8614997404000002 + 1.9076664936000003 + 0.0000000000000000 + 0.0000000000000000 + 2.1067498053000002 + -1.4044998702000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4506666234000001 + 0.3004444156000000 + -0.3953362375000001 + 1.0369354002000000 + -0.7777015501500000 + 0.1728225667000000 + 0.8000527127999999 + -2.0066802120000000 + 1.5050101590000000 + -0.3344467020000000 + -0.6000395345999999 + 1.5050101590000000 + -1.1287576192500000 + 0.2508350265000000 + 0.1333421188000000 + -0.3344467020000000 + 0.2508350265000000 + -0.0557411170000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.3103306184999992 + -9.0968349185999990 + 6.7318116889499997 + -1.4555961530999999 + -8.5868161127999993 + 23.8242035591999937 + -17.5957091693999956 + 3.7890715931999996 + 6.3613620845999996 + -17.6319026693999987 + 13.0195943770499980 + -2.8024286948999997 + -1.3786360187999998 + 3.8132005931999995 + -2.8144931948999998 + 0.6052619321999999 + -2.2068870789999999 + 6.0645566123999997 + -4.4878744592999995 + 0.9703974353999998 + 5.7245440751999999 + -15.8828023728000005 + 11.7304727795999995 + -2.5260477287999996 + -4.2409080563999995 + 11.7546017795999980 + -8.6797295846999987 + 1.8682857965999997 + 0.9190906791999999 + -2.5421337287999997 + 1.8763287965999997 + -0.4035079547999999 + 1.4805008319000001 + -1.9673896319999999 + 0.8197456799999999 + -0.1092994240000000 + -3.5413013375999998 + 4.7217351167999997 + -1.9673896319999997 + 0.2623186176000000 + 2.6559760031999997 + -3.5413013375999993 + 1.4755422239999998 + -0.1967389632000000 + -0.5902168896000000 + 0.7869558527999999 + -0.3278982720000000 + 0.0437197696000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -19.2295206957000033 + 24.4584372960000032 + -9.9185720400000008 + 1.2982590720000002 + 48.8229586128000079 + -61.7340105504000007 + 24.9051738960000009 + -3.2480382528000007 + -36.6172189596000024 + 46.3005079128000006 + -18.6788804219999989 + 2.4360286896000005 + 8.1371597688000001 + -10.2890017584000013 + 4.1508623160000004 + -0.5413397088000000 + 12.8196804638000010 + -16.3056248640000021 + 6.6123813600000005 + -0.8655060480000000 + -32.5486390752000005 + 41.1560070336000052 + -16.6034492640000018 + 2.1653588352000002 + 24.4114793064000004 + -30.8670052752000004 + 12.4525869480000004 + -1.6240191264000001 + -5.4247731792000007 + 6.8593345056000006 + -2.7672415440000000 + 0.3608931392000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.2914572557999993 + -3.1368362039999997 + 0.9712843094999998 + -0.0996618390000000 + -7.9931075507999978 + 7.5284068895999994 + -2.3310823427999994 + 0.2391884136000000 + 5.9948306630999983 + -5.6463051671999986 + 1.7483117570999998 + -0.1793913102000000 + -1.3321845917999997 + 1.2547344815999997 + -0.3885137237999999 + 0.0398647356000000 + -2.1943048371999994 + 2.0912241359999992 + -0.6475228729999998 + 0.0664412260000000 + 5.3287383671999988 + -5.0189379263999987 + 1.5540548951999997 + -0.1594589424000000 + -3.9965537753999993 + 3.7642034447999992 + -1.1655411713999997 + 0.1195942068000000 + 0.8881230611999998 + -0.8364896543999999 + 0.2590091492000000 + -0.0265764904000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 51.2174335277999973 + -34.7252003400000007 + 7.7793458265000002 + -0.5762478390000000 + -125.8865034036000026 + 85.2980168160000147 + -19.1108755836000022 + 1.4156204136000001 + 98.0036935526999997 + -66.4204326120000133 + 14.8837136877000020 + -1.1024973102000000 + -23.3736279005999990 + 15.8476161360000010 + -3.5521839306000000 + 0.2631247356000000 + -34.1449556852000029 + 23.1501335600000040 + -5.1862305510000013 + 0.3841652260000000 + 83.9243356024000065 + -56.8653445440000098 + 12.7405837224000020 + -0.9437469424000001 + -65.3357957018000093 + 44.2802884080000041 + -9.9224757918000019 + 0.7349982068000001 + 15.5824186004000005 + -10.5650774240000018 + 2.3681226204000003 + -0.1754164904000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 18.8699219402999923 + -9.8715457799999946 + 1.7195853929999991 + -0.0996618419999999 + -45.3977355935999753 + 23.6917098719999899 + -4.1270049431999976 + 0.2391884207999999 + 34.0686926951999851 + -17.7687824039999924 + 3.0952537073999986 + -0.1793913155999999 + -7.5798832655999968 + 3.9486183119999980 + -0.6878341571999995 + 0.0398647368000000 + -12.5799479601999984 + 6.5810305199999988 + -1.1463902619999997 + 0.0664412280000000 + 30.2651570623999930 + -15.7944732479999974 + 2.7513366287999990 + -0.1594589472000000 + -22.7124617967999924 + 11.8458549359999967 + -2.0635024715999997 + 0.1195942104000000 + 5.0532555103999988 + -2.6324122079999994 + 0.4585561047999999 + -0.0265764912000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0187635363000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1549554239999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1366075680000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0394199040000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0125090242000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1033036160000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0910717120000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0262799360000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0187635363000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1549554239999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1366075680000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0394199040000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0125090242000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1033036160000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0910717120000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0262799360000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0187635363000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1549554239999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1366075680000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0394199040000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0125090242000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1033036160000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0910717120000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0262799360000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.0321606498499998 + 4.6881070998999999 + 0.0000000000000000 + 0.0000000000000000 + 9.1366163297999989 + -6.0910775531999999 + 0.0000000000000000 + 0.0000000000000000 + -3.8069234707500001 + 2.5379489805000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5075897961000000 + -0.3383931974000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 24.1765592188500023 + -16.1177061459000015 + 0.0000000000000000 + 0.0000000000000000 + -30.8078686818000023 + 20.5385791212000015 + 0.0000000000000000 + 0.0000000000000000 + 12.6594244507500004 + -8.4396163005000009 + 0.0000000000000000 + 0.0000000000000000 + -1.6721732601000001 + 1.1147821734000001 + 0.0000000000000000 + 0.0000000000000000 + -16.1177061459000015 + 10.7451374305999998 + 0.0000000000000000 + 0.0000000000000000 + 20.5385791212000015 + -13.6923860807999986 + 0.0000000000000000 + 0.0000000000000000 + -8.4396163005000009 + 5.6264108669999997 + 0.0000000000000000 + 0.0000000000000000 + 1.1147821734000001 + -0.7431881155999999 + 1.7964189073000001 + -9.9371338973999990 + 7.4528504230499992 + -1.6561889829000001 + -2.4750911663999995 + 13.2495118631999986 + -9.9371338973999990 + 2.2082519771999998 + 1.0312879859999999 + -5.5206299429999994 + 4.1404724572499996 + -0.9201049905000001 + -0.1375050648000000 + 0.7360839924000000 + -0.5520629942999999 + 0.1226806654000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -44.4148786822999924 + 125.9369562125999806 + -94.4527171594499890 + 20.9894927020999980 + 57.1409193383999963 + -161.7845013575999928 + 121.3383760181999946 + -26.9640835595999988 + -23.5724663909999990 + 66.7014588990000021 + -50.0260941742499909 + 11.1169098164999998 + 3.1219955187999995 + -8.8305278531999996 + 6.6228958898999997 + -1.4717546421999999 + 30.4859639041999984 + -86.0604782867999916 + 64.5453587151000079 + -14.3434130477999986 + -39.2202895175999942 + 110.5595581391999929 + -82.9196686044000018 + 18.4265930231999988 + 16.1842872989999975 + -45.5939825580000004 + 34.1954869185000021 + -7.5989970929999995 + -2.1439049731999997 + 6.0371976743999998 + -4.5278982558000003 + 1.0061996123999999 + 41.0697356006999996 + -54.7530359903999937 + 22.8137649960000033 + -3.0418353327999998 + -52.4181452760000042 + 69.8908603680000056 + -29.1211918200000000 + 3.8828255760000001 + 21.8408938650000017 + -29.1211918200000000 + 12.1338299250000006 + -1.6178439899999999 + -2.9121191820000001 + 3.8828255760000001 + -1.6178439899999999 + 0.2157125320000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -58.7754249068999997 + 72.4365406656000062 + -30.1818919440000002 + 4.0242522591999998 + 71.7688591056000007 + -88.1435659967999925 + 36.7264858320000016 + -4.8968647776000003 + -29.9036912940000015 + 36.7264858320000016 + -15.3027024300000001 + 2.0403603240000003 + 3.9871588392000001 + -4.8968647776000003 + 2.0403603240000003 + -0.2720480432000001 + 34.4529747782000015 + -41.9835046752000025 + 17.4931269480000005 + -2.3324169264000001 + -41.7636522936000034 + 50.6527056287999997 + -21.1052940120000017 + 2.8140392016000000 + 17.4015217890000002 + -21.1052940120000017 + 8.7938725049999995 + -1.1725163339999998 + -2.3202029051999999 + 2.8140392016000000 + -1.1725163339999998 + 0.1563355111999999 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -22.5910445969999856 + 16.9389155015999862 + -5.2449352712999966 + 0.5381739305999996 + 29.8518848603999807 + -22.5852206687999839 + 6.9932470283999955 + -0.7175652407999995 + -12.4382853584999911 + 9.4105086119999921 + -2.9138529284999981 + 0.2989855169999998 + 1.6584380477999987 + -1.2547344815999988 + 0.3885137237999997 + -0.0398647356000000 + 15.0606963979999851 + -11.2926103343999884 + 3.4966235141999964 + -0.3587826203999996 + -19.9012565735999800 + 15.0568137791999828 + -4.6621646855999952 + 0.4783768271999995 + 8.2921902389999929 + -6.2736724079999924 + 1.9425686189999980 + -0.1993236779999998 + -1.1056253651999990 + 0.8364896543999990 + -0.2590091491999997 + 0.0265764904000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 132.0402867341999809 + -94.3691021639999832 + 21.4156989368999930 + -1.5863480693999996 + -133.2574315811999668 + 96.4624295519999748 + -21.9475812491999918 + 1.6257467591999992 + 44.7574818254999798 + -32.8519189799999864 + 7.4931545204999956 + -0.5550484829999996 + -5.0106466433999977 + 3.7277438639999976 + -0.8522720693999993 + 0.0631312643999999 + -88.0268578227999967 + 62.9127347760000006 + -14.2771326246000001 + 1.0575653796000002 + 88.8382877207999968 + -64.3082863680000116 + 14.6317208328000028 + -1.0838311728000001 + -29.8383212170000043 + 21.9012793200000040 + -4.9954363470000018 + 0.3700323220000001 + 3.3404310956000010 + -2.4851625760000013 + 0.5681813796000004 + -0.0420875096000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -104.3657106932998886 + 53.3063472119999489 + -9.2857611221999896 + 0.5381739467999993 + 139.1294649887998673 + -71.0751296159999271 + 12.3810148295999856 + -0.7175652623999991 + -58.0317834119999389 + 29.6146373399999696 + -5.1587561789999938 + 0.2989855259999996 + 7.7430087215999910 + -3.9486183119999954 + 0.6878341571999992 + -0.0398647367999999 + 69.5771404621999920 + -35.5375648079999991 + 6.1905074148000008 + -0.3587826312000001 + -92.7529766592000016 + 47.3834197440000082 + -8.2540098864000022 + 0.4783768416000003 + 38.6878556080000138 + -19.7430915600000105 + 3.4391707860000027 + -0.1993236840000002 + -5.1620058144000041 + 2.6324122080000025 + -0.4585561048000005 + 0.0265764912000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5694553116999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.4011244799999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.4783081999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2025453600000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.7129702077999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2674163199999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9855388000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1350302400000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5694553116999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.4011244799999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.4783081999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2025453600000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.7129702077999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2674163199999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9855388000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1350302400000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5694553116999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.4011244799999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.4783081999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2025453600000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.7129702077999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2674163199999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9855388000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1350302400000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1796984025000000 + 0.1197989350000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5390952075000000 + -0.3593968050000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3593968050000000 + 0.2395978700000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0598994675000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.7523780425000002 + -15.7744311360000005 + 11.8308233519999995 + -2.6290718559999999 + -6.7580597519999994 + 16.2193434048000000 + -12.1645075536000000 + 2.7032239007999999 + 1.9711007609999998 + -4.7306418263999994 + 3.5479813698000000 + -0.7884403043999999 + -0.1877238820000000 + 0.4505373168000000 + -0.3379029876000000 + 0.0750895528000000 + -7.0045704549999996 + 16.5234516479999982 + -12.3925887360000004 + 2.7539086080000001 + 6.7580597519999994 + -16.2193434048000000 + 12.1645075536000000 + -2.7032239007999999 + -1.9711007609999998 + 4.7306418263999994 + -3.5479813698000000 + 0.7884403043999999 + 0.1877238820000000 + -0.4505373168000000 + 0.3379029876000000 + -0.0750895528000000 + 1.7561266437000007 + -2.3348907144000020 + 0.9728711310000014 + -0.1297161508000003 + -0.0000000000000012 + 0.0000000000000029 + -0.0000000000000020 + 0.0000000000000004 + 0.0000000000000005 + -0.0000000000000012 + 0.0000000000000008 + -0.0000000000000002 + -0.0000000000000001 + 0.0000000000000002 + -0.0000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -46.0039935710999970 + 61.0691501591999995 + -25.4454792330000004 + 3.3927305643999999 + 36.4935226607999965 + -48.6580302144000001 + 20.2741792560000000 + -2.7032239007999999 + -10.6439441093999996 + 14.1919254792000000 + -5.9133022830000002 + 0.7884403043999999 + 1.0137089628000000 + -1.3516119503999999 + 0.5631716460000000 + -0.0750895528000000 + 44.1854485514000146 + -58.7342594448000099 + 24.4726081020000059 + -3.2630144136000014 + -36.4935226608000107 + 48.6580302144000143 + -20.2741792560000071 + 2.7032239008000012 + 10.6439441094000031 + -14.1919254792000071 + 5.9133022830000037 + -0.7884403044000006 + -1.0137089628000004 + 1.3516119504000006 + -0.5631716460000002 + 0.0750895528000001 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1101605377500000 + -0.0734403585000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.5308662927499996 + 1.0205775285000001 + 0.0000000000000000 + 0.0000000000000000 + 1.0205775285000001 + -0.6803850190000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1081921266000000 + 0.0721280844000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 4.2922496105999990 + -2.8614997404000002 + 0.0000000000000000 + 0.0000000000000000 + -2.8614997404000002 + 1.9076664936000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0811440949500000 + -0.0540960633000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.1601247079499992 + 2.1067498053000002 + 0.0000000000000000 + 0.0000000000000000 + 2.1067498053000002 + -1.4044998702000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0180320211000000 + 0.0120213474000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6759999350999999 + -0.4506666234000001 + 0.0000000000000000 + 0.0000000000000000 + -0.4506666234000001 + 0.3004444156000000 + -0.3953362375000001 + 1.0369354002000000 + -0.7777015501500000 + 0.1728225667000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.3103306184999992 + -9.0968349185999990 + 6.7318116889499997 + -1.4555961531000001 + -2.2068870789999999 + 6.0645566123999997 + -4.4878744593000004 + 0.9703974354000000 + 0.8000527127999999 + -2.0066802120000000 + 1.5050101590000000 + -0.3344467020000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.5868161127999993 + 23.8242035591999972 + -17.5957091693999992 + 3.7890715932000001 + 5.7245440751999999 + -15.8828023728000005 + 11.7304727795999995 + -2.5260477288000001 + -0.6000395345999999 + 1.5050101590000000 + -1.1287576192500000 + 0.2508350265000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.3613620845999996 + -17.6319026693999987 + 13.0195943770500016 + -2.8024286949000006 + -4.2409080564000003 + 11.7546017796000015 + -8.6797295847000004 + 1.8682857965999999 + 0.1333421188000000 + -0.3344467020000000 + 0.2508350265000000 + -0.0557411170000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.3786360188000000 + 3.8132005932000004 + -2.8144931949000003 + 0.6052619322000001 + 0.9190906792000001 + -2.5421337288000001 + 1.8763287966000000 + -0.4035079547999999 + 1.4805008319000001 + -1.9673896319999999 + 0.8197456799999999 + -0.1092994240000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -19.2295206957000033 + 24.4584372960000032 + -9.9185720400000008 + 1.2982590720000002 + 12.8196804638000010 + -16.3056248640000021 + 6.6123813600000005 + -0.8655060480000000 + -3.5413013375999998 + 4.7217351167999997 + -1.9673896319999997 + 0.2623186176000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 48.8229586128000079 + -61.7340105504000007 + 24.9051738960000009 + -3.2480382528000007 + -32.5486390752000005 + 41.1560070336000052 + -16.6034492640000018 + 2.1653588352000002 + 2.6559760031999997 + -3.5413013375999993 + 1.4755422239999998 + -0.1967389632000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -36.6172189596000024 + 46.3005079128000006 + -18.6788804219999989 + 2.4360286896000005 + 24.4114793064000004 + -30.8670052752000004 + 12.4525869480000004 + -1.6240191264000001 + -0.5902168896000000 + 0.7869558527999999 + -0.3278982720000000 + 0.0437197696000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 8.1371597688000001 + -10.2890017584000013 + 4.1508623160000004 + -0.5413397088000000 + -5.4247731792000007 + 6.8593345056000006 + -2.7672415440000000 + 0.3608931392000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.2914572557999993 + -3.1368362039999997 + 0.9712843094999998 + -0.0996618390000000 + -2.1943048371999994 + 2.0912241359999992 + -0.6475228729999998 + 0.0664412260000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.9931075507999978 + 7.5284068895999994 + -2.3310823427999994 + 0.2391884136000000 + 5.3287383671999988 + -5.0189379263999987 + 1.5540548951999997 + -0.1594589424000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.9948306630999983 + -5.6463051671999986 + 1.7483117570999998 + -0.1793913102000000 + -3.9965537753999993 + 3.7642034447999992 + -1.1655411713999997 + 0.1195942068000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.3321845917999997 + 1.2547344815999997 + -0.3885137237999999 + 0.0398647356000000 + 0.8881230611999998 + -0.8364896543999999 + 0.2590091492000000 + -0.0265764904000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 51.2174335277999973 + -34.7252003400000007 + 7.7793458265000002 + -0.5762478390000000 + -34.1449556852000029 + 23.1501335600000040 + -5.1862305510000013 + 0.3841652260000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -125.8865034036000026 + 85.2980168160000147 + -19.1108755836000022 + 1.4156204136000001 + 83.9243356024000065 + -56.8653445440000098 + 12.7405837224000020 + -0.9437469424000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 98.0036935526999997 + -66.4204326120000133 + 14.8837136877000020 + -1.1024973102000000 + -65.3357957018000093 + 44.2802884080000041 + -9.9224757918000019 + 0.7349982068000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -23.3736279005999990 + 15.8476161360000010 + -3.5521839306000000 + 0.2631247356000000 + 15.5824186004000005 + -10.5650774240000018 + 2.3681226204000003 + -0.1754164904000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 18.8699219402999923 + -9.8715457799999946 + 1.7195853929999991 + -0.0996618419999999 + -12.5799479601999984 + 6.5810305199999988 + -1.1463902619999997 + 0.0664412280000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -45.3977355935999753 + 23.6917098719999899 + -4.1270049431999976 + 0.2391884207999999 + 30.2651570623999930 + -15.7944732479999974 + 2.7513366287999990 + -0.1594589472000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 34.0686926951999851 + -17.7687824039999924 + 3.0952537073999986 + -0.1793913155999999 + -22.7124617967999924 + 11.8458549359999967 + -2.0635024715999997 + 0.1195942104000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5798832655999968 + 3.9486183119999980 + -0.6878341571999995 + 0.0398647368000000 + 5.0532555103999988 + -2.6324122079999994 + 0.4585561047999999 + -0.0265764912000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0187635363000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0125090242000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1549554239999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1033036160000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1366075680000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0910717120000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0394199040000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0262799360000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0187635363000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0125090242000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1549554239999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1033036160000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1366075680000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0910717120000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0394199040000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0262799360000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0187635363000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0125090242000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1549554239999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1033036160000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1366075680000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0910717120000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0394199040000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0262799360000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 4.2228846869999987 + -2.8152564579999999 + 0.0000000000000000 + 0.0000000000000000 + -11.0322309923999988 + 7.3548206615999998 + 0.0000000000000000 + 0.0000000000000000 + 8.1954232442999988 + -5.4636154962000010 + 0.0000000000000000 + 0.0000000000000000 + -1.7862051654000000 + 1.1908034436000001 + 0.0000000000000000 + 0.0000000000000000 + -11.0322309923999988 + 7.3548206615999998 + 0.0000000000000000 + 0.0000000000000000 + 29.4624929663999993 + -19.6416619776000019 + 0.0000000000000000 + 0.0000000000000000 + -21.8606197247999994 + 14.5737464832000008 + 0.0000000000000000 + 0.0000000000000000 + 4.7529154943999998 + -3.1686103296000003 + 0.0000000000000000 + 0.0000000000000000 + 8.1954232442999988 + -5.4636154962000010 + 0.0000000000000000 + 0.0000000000000000 + -21.8606197247999994 + 14.5737464832000008 + 0.0000000000000000 + 0.0000000000000000 + 16.2182772935999999 + -10.8121848624000023 + 0.0000000000000000 + 0.0000000000000000 + -3.5253116208000002 + 2.3502077472000003 + 0.0000000000000000 + 0.0000000000000000 + -1.7862051654000000 + 1.1908034436000001 + 0.0000000000000000 + 0.0000000000000000 + 4.7529154943999998 + -3.1686103296000003 + 0.0000000000000000 + 0.0000000000000000 + -3.5253116208000002 + 2.3502077472000003 + 0.0000000000000000 + 0.0000000000000000 + 0.7659025824000001 + -0.5106017216000001 + -6.4539249160000001 + 18.7708587479999949 + -13.9570580609999997 + 3.0477524580000002 + 17.1048773232000002 + -49.5868839695999952 + 36.8269049772000017 + -8.0223086616000003 + -12.7236579923999980 + 36.8751629771999987 + -27.3839287329000030 + 5.9642314962000009 + 2.7808128872000002 + -8.0544806615999995 + 5.9803174962000005 + -1.3020514436000004 + 17.1048773232000002 + -49.5868839695999952 + 36.8269049772000017 + -8.0223086616000003 + -45.7490319551999889 + 132.4958518656000024 + -98.2821148992000104 + 21.3561259776000014 + 33.9967739664000064 + -98.4268888992000086 + 73.0028361744000023 + -15.8595944832000022 + -7.4148386592000008 + 21.4526419776000026 + -15.9078524832000010 + 3.4543543296000006 + -12.7236579923999997 + 36.8751629771999987 + -27.3839287329000030 + 5.9642314962000009 + 33.9967739663999993 + -98.4268888992000086 + 73.0028361744000165 + -15.8595944832000004 + -25.2613304747999976 + 73.1114166744000045 + -54.2205646307999984 + 11.7765708624000016 + 5.5086289944000004 + -15.9319814832000013 + 11.8127643624000012 + -2.5645157472000006 + 2.7808128872000002 + -8.0544806615999995 + 5.9803174962000005 + -1.3020514436000004 + -7.4148386592000008 + 21.4526419776000026 + -15.9078524832000010 + 3.4543543296000006 + 5.5086289944000004 + -15.9319814832000013 + 11.8127643624000012 + -2.5645157472000006 + -1.2008064432000003 + 3.4704403296000006 + -2.5725587472000004 + 0.5582257216000001 + 39.8894121000000013 + -50.7093326999999903 + 20.7656306250000000 + -2.7364611499999998 + -107.5650035999999830 + 136.5474131999999940 + -55.8049815000000038 + 7.3437953999999994 + 80.6737526999999801 + -102.4105598999999955 + 41.8537361250000046 + -5.5078465500000000 + -17.9275005999999983 + 22.7579021999999966 + -9.3008302500000006 + 1.2239659000000001 + -107.5650035999999972 + 136.5474131999999940 + -55.8049815000000038 + 7.3437953999999994 + 288.7152523199999905 + -365.7688358399999515 + 149.1343596000000105 + -19.5939748799999975 + -216.5364392399999645 + 274.3266268799999921 + -111.8507697000000007 + 14.6954811599999999 + 48.1192087200000032 + -60.9614726399999967 + 24.8557266000000006 + -3.2656624800000000 + 80.6737526999999943 + -102.4105598999999955 + 41.8537361250000046 + -5.5078465500000000 + -216.5364392400000213 + 274.3266268799999921 + -111.8507697000000007 + 14.6954811599999999 + 162.4023294299999804 + -205.7449701599999798 + 83.8880772750000006 + -11.0216108699999999 + -36.0894065399999988 + 45.7211044800000010 + -18.6417949500000013 + 2.4492468600000001 + -17.9275005999999983 + 22.7579021999999966 + -9.3008302500000006 + 1.2239659000000001 + 48.1192087200000032 + -60.9614726399999967 + 24.8557266000000006 + -3.2656624800000000 + -36.0894065399999988 + 45.7211044800000010 + -18.6417949500000013 + 2.4492468600000001 + 8.0198681199999999 + -10.1602454400000006 + 4.1426211000000004 + -0.5442770800000001 + -11.9141455994999941 + 11.5908520439999947 + -3.4999733044999992 + 0.3484810289999999 + 31.2390159023999878 + -30.3275138687999863 + 9.1769633783999964 + -0.9160839407999998 + -23.4292619267999918 + 22.7456354015999942 + -6.8827225337999982 + 0.6870629555999997 + 5.2065026503999983 + -5.0545856447999986 + 1.5294938963999996 + -0.1526806568000000 + 31.2390159023999843 + -30.3275138687999899 + 9.1769633783999964 + -0.9160839407999998 + -81.3681242063999548 + 78.8087587967999639 + -23.8895779823999916 + 2.3899521887999993 + 61.0260931547999803 + -59.1065690975999729 + 17.9171834867999920 + -1.7924641415999993 + -13.5613540343999954 + 13.1347931327999969 + -3.9815963303999986 + 0.3983253647999999 + -23.4292619267999882 + 22.7456354015999906 + -6.8827225337999982 + 0.6870629555999997 + 61.0260931547999803 + -59.1065690975999729 + 17.9171834867999955 + -1.7924641415999993 + -45.7695698660999852 + 44.3299268231999832 + -13.4378876150999957 + 1.3443481061999996 + 10.1710155257999979 + -9.8510948495999990 + 2.9861972477999990 + -0.2987440236000000 + 5.2065026503999983 + -5.0545856447999986 + 1.5294938963999996 + -0.1526806568000000 + -13.5613540343999954 + 13.1347931327999969 + -3.9815963303999986 + 0.3983253647999999 + 10.1710155257999979 + -9.8510948495999990 + 2.9861972477999990 + -0.2987440236000000 + -2.2602256723999994 + 2.1891321887999995 + -0.6635993883999999 + 0.0663875608000000 + -135.7455229915000245 + 92.5172767399999998 + -20.7448023915000022 + 1.5366520290000003 + 370.6031730607999748 + -252.4316724479999721 + 56.5982632008000053 + -4.1924639408000006 + -282.7374677955999687 + 192.5863143359999867 + -43.1827734005999986 + 3.1987239556000002 + 64.9572541768000065 + -44.2469854080000005 + 9.9224278667999997 + -0.7349946568000001 + 370.6031730607999748 + -252.4316724480000289 + 56.5982632008000053 + -4.1924639408000006 + -1001.6410292688001391 + 681.9045713280002019 + -152.8863145488000157 + 11.3249121888000026 + 765.5860359516002518 + -521.2161084960000608 + 116.8669639116000099 + -8.6568121415999997 + -176.5103475448000268 + 120.1758818880000064 + -26.9492044248000013 + 1.9962373648000000 + -282.7374677955999687 + 192.5863143359999867 + -43.1827734005999986 + 3.1987239556000002 + 765.5860359516000244 + -521.2161084960000608 + 116.8669639116000099 + -8.6568121415999997 + -584.9559749637001005 + 398.2528413720000344 + -89.3018939337000006 + 6.6149551062000000 + 134.7753046586000210 + -91.7631914159999980 + 20.5789413186000019 + -1.5243660235999998 + 64.9572541768000065 + -44.2469854080000005 + 9.9224278667999997 + -0.7349946568000001 + -176.5103475448000268 + 120.1758818880000064 + -26.9492044248000013 + 1.9962373648000000 + 134.7753046586000210 + -91.7631914159999980 + 20.5789413186000019 + -1.5243660235999998 + -31.0134205908000027 + 21.1168336479999965 + -4.7362260707999999 + 0.3508315608000000 + -49.4848264664999746 + 26.2405983299999868 + -4.5854146104999991 + 0.2657560369999998 + 133.8931721307999396 + -70.8746726159999696 + 12.3806633795999943 + -0.7175439623999997 + -100.4470670980999500 + 53.1560044619999772 + -9.2854975346999957 + 0.5381579717999998 + 22.3336540217999939 + -11.8124454359999937 + 2.0634438965999995 + -0.1195906604000000 + 133.8931721307999396 + -70.8746726159999696 + 12.3806633795999943 + -0.7175439623999997 + -357.7270527887998810 + 189.0525821759999303 + -33.0151960655999872 + 1.9134562463999991 + 268.3768535915999109 + -141.7894366319999335 + 24.7613970491999922 + -1.4350921847999993 + -59.6755514647999803 + 31.5087636959999884 + -5.5025326775999988 + 0.3189093743999999 + -100.4470670980999643 + 53.1560044619999914 + -9.2854975346999957 + 0.5381579717999998 + 268.3768535915999109 + -141.7894366319999335 + 24.7613970491999922 + -1.4350921847999993 + -201.3438131936999298 + 106.3420774739999501 + -18.5710477868999924 + 1.0763191385999997 + 44.7702575985999829 + -23.6315727719999913 + 4.1268995081999993 + -0.2391820307999999 + 22.3336540217999939 + -11.8124454359999937 + 2.0634438965999995 + -0.1195906604000000 + -59.6755514647999803 + 31.5087636959999884 + -5.5025326775999988 + 0.3189093743999999 + 44.7702575985999829 + -23.6315727719999913 + 4.1268995081999993 + -0.2391820307999999 + -9.9549879107999981 + 5.2514606159999992 + -0.9170887795999998 + 0.0531515624000000 + 0.7858877775000047 + -0.0838432500000021 + 0.0001730625000003 + -0.0000088750000000 + -1.8374687780000103 + 0.2012238000000045 + -0.0004153500000007 + 0.0000213000000000 + 1.3509135835000063 + -0.1509178500000028 + 0.0003115125000004 + -0.0000159750000000 + -0.2881194630000009 + 0.0335373000000004 + -0.0000692250000000 + 0.0000035500000000 + -1.8374687780000101 + 0.2012238000000045 + -0.0004153500000007 + 0.0000213000000000 + 4.2207095280000200 + -0.4829371200000090 + 0.0009968400000013 + -0.0000511200000001 + -3.0839681460000103 + 0.3622028400000043 + -0.0007476300000006 + 0.0000383400000000 + 0.6490755880000003 + -0.0804895199999999 + 0.0001661399999999 + -0.0000085200000000 + 1.3509135835000063 + -0.1509178500000028 + 0.0003115125000004 + -0.0000159750000000 + -3.0839681460000108 + 0.3622028400000043 + -0.0007476300000006 + 0.0000383400000000 + 2.2518031095000022 + -0.2716521300000003 + 0.0005607224999999 + -0.0000287550000000 + -0.4732126909999979 + 0.0603671399999987 + -0.0001246049999998 + 0.0000063900000000 + -0.2881194630000009 + 0.0335373000000004 + -0.0000692250000000 + 0.0000035500000000 + 0.6490755880000003 + -0.0804895199999999 + 0.0001661399999999 + -0.0000085200000000 + -0.4732126909999979 + 0.0603671399999987 + -0.0001246049999998 + 0.0000063900000000 + 0.0991165979999985 + -0.0134149199999992 + 0.0000276899999999 + -0.0000014200000000 + 0.7871924025000062 + -0.0842160000000026 + 0.0001996875000003 + -0.0000088750000000 + -1.8405998780000177 + 0.2021184000000074 + -0.0004792500000010 + 0.0000213000000000 + 1.3532619085000168 + -0.1515888000000072 + 0.0003594375000010 + -0.0000159750000000 + -0.2886413130000054 + 0.0336864000000023 + -0.0000798750000003 + 0.0000035500000000 + -1.8405998780000132 + 0.2021184000000054 + -0.0004792500000007 + 0.0000213000000000 + 4.2282241680000388 + -0.4850841600000161 + 0.0011502000000022 + -0.0000511200000001 + -3.0896041260000380 + 0.3638131200000160 + -0.0008626500000022 + 0.0000383400000001 + 0.6503280280000123 + -0.0808473600000053 + 0.0001917000000008 + -0.0000085200000000 + 1.3532619085000075 + -0.1515888000000030 + 0.0003594375000004 + -0.0000159750000000 + -3.0896041260000238 + 0.3638131200000099 + -0.0008626500000014 + 0.0000383400000001 + 2.2560300945000247 + -0.2728598400000106 + 0.0006469875000015 + -0.0000287550000001 + -0.4741520210000086 + 0.0606355200000037 + -0.0001437750000005 + 0.0000063900000000 + -0.2886413130000007 + 0.0336864000000003 + -0.0000798750000000 + 0.0000035500000000 + 0.6503280280000028 + -0.0808473600000012 + 0.0001917000000002 + -0.0000085200000000 + -0.4741520210000038 + 0.0606355200000017 + -0.0001437750000003 + 0.0000063900000000 + 0.0993253380000016 + -0.0134745600000007 + 0.0000319500000001 + -0.0000014200000000 + -46.8607035974999846 + 17.1221579999999953 + -2.0678986874999996 + 0.0827161250000000 + 112.5143505220000009 + -41.0931791999999874 + 4.9629568499999985 + -0.1985187000000000 + -84.4129508914999889 + 30.8198843999999923 + -3.7222176374999982 + 0.1488890250000000 + 18.7705170869999911 + -6.8488631999999967 + 0.8271594749999995 + -0.0330864500000000 + 112.5143505219999867 + -41.0931791999999945 + 4.9629568499999994 + -0.1985187000000000 + -270.2236567919999288 + 98.6236300799999697 + -11.9110964399999943 + 0.4764448799999998 + 202.7493065939999042 + -73.9677225599999701 + 8.9333223299999958 + -0.3573336599999999 + -45.0916521319999788 + 16.4372716799999949 + -1.9851827399999988 + 0.0794074800000000 + -84.4129508914999889 + 30.8198843999999923 + -3.7222176374999991 + 0.1488890250000000 + 202.7493065939999610 + -73.9677225599999844 + 8.9333223299999975 + -0.3573336599999999 + -152.1231529454999531 + 55.4757919199999776 + -6.6999917474999968 + 0.2680002449999999 + 33.8323330989999818 + -12.3279537599999927 + 1.4888870549999993 + -0.0595556100000000 + 18.7705170869999982 + -6.8488631999999985 + 0.8271594750000000 + -0.0330864500000000 + -45.0916521319999930 + 16.4372716799999985 + -1.9851827399999995 + 0.0794074800000000 + 33.8323330989999960 + -12.3279537599999962 + 1.4888870549999995 + -0.0595556100000000 + -7.5243380219999976 + 2.7395452799999989 + -0.3308637899999998 + 0.0132345800000000 + 0.0000000000000000 + 0.0000000000000000 + -32.6217780473999994 + 21.7478520315999972 + 0.0000000000000000 + 0.0000000000000000 + 42.1036102331999942 + -28.0690734888000009 + 0.0000000000000000 + 0.0000000000000000 + -17.3069209304999987 + 11.5379472869999997 + 0.0000000000000000 + 0.0000000000000000 + 2.2865894573999999 + -1.5243929716000000 + 0.0000000000000000 + 0.0000000000000000 + 80.7563291291999974 + -53.8375527528000006 + 0.0000000000000000 + 0.0000000000000000 + -103.7670803135999904 + 69.1780535423999936 + 0.0000000000000000 + 0.0000000000000000 + 42.5275334640000011 + -28.3516889759999984 + 0.0000000000000000 + 0.0000000000000000 + -5.6073377951999994 + 3.7382251968000002 + 0.0000000000000000 + 0.0000000000000000 + -60.5672468468999909 + 40.3781645645999987 + 0.0000000000000000 + 0.0000000000000000 + 77.8253102351999928 + -51.8835401567999952 + 0.0000000000000000 + 0.0000000000000000 + -31.8956500979999973 + 21.2637667320000006 + 0.0000000000000000 + 0.0000000000000000 + 4.2055033464000005 + -2.8036688975999997 + 0.0000000000000000 + 0.0000000000000000 + 13.4593881881999984 + -8.9729254587999989 + 0.0000000000000000 + 0.0000000000000000 + -17.2945133855999984 + 11.5296755904000001 + 0.0000000000000000 + 0.0000000000000000 + 7.0879222439999996 + -4.7252814960000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9345562992000001 + 0.6230375328000000 + 44.2256531812000020 + -132.2389900727999930 + 99.1792425546000089 + -22.0398316788000024 + -57.1087958436000065 + 170.7439982111999939 + -128.0579986584000096 + 28.4573330352000013 + 23.4803316015000050 + -70.1983325880000137 + 52.6487494410000068 + -11.6997220980000023 + -3.1027108802000005 + 9.2757776784000008 + -6.9568332588000015 + 1.5459629464000002 + -138.5907206816000041 + 397.2227929391999623 + -297.9170947044000286 + 66.2037988232000032 + 178.4133265968000046 + -511.2056480831998897 + 383.4042360623999457 + -85.2009413472000006 + -73.3938860820000087 + 210.1673533679999650 + -157.6255150260000164 + 35.0278922279999989 + 9.7018514776000000 + -27.7703137824000024 + 20.8277353368000036 + -4.6283856304000004 + 105.4788598592000142 + -301.6030611396000722 + 226.2022958546999973 + -50.2671768566000026 + -135.7846198235999964 + 388.1433357647999856 + -291.1075018236000460 + 64.6905559607999976 + 55.8681749264999965 + -159.6001399019999667 + 119.7001049265000034 + -26.6000233170000016 + -7.3860899902000003 + 21.0910186536000026 + -15.8182639902000002 + 3.5151697756000004 + -23.2462882296000011 + 66.5586023016000041 + -49.9189517261999995 + 11.0931003835999995 + 29.9256277248000018 + -85.6571172480000058 + 64.2428379360000008 + -14.2761862080000022 + -12.3115115519999989 + 35.2179655199999999 + -26.4134741400000017 + 5.8696609200000003 + 1.6275348736000002 + -4.6537287359999997 + 3.4902965520000002 + -0.7756214560000001 + -50.0478950811999894 + 64.5349948775999991 + -26.8895811989999984 + 3.5852774931999991 + 69.5343934043999923 + -89.6509583711999767 + 37.3545659879999903 + -4.9806087983999987 + -28.9726639184999897 + 37.3545659879999903 + -15.5644024949999960 + 2.0752536659999996 + 3.8630218557999996 + -4.9806087983999987 + 2.0752536659999996 + -0.2767004887999999 + 183.1902844943999753 + -243.4800953951999531 + 101.4500397479999805 + -13.5266719663999986 + -250.0931194127999788 + 331.8487242623999691 + -138.2703017759999966 + 18.4360402367999967 + 104.2054664220000006 + -138.2703017759999966 + 57.6126257399999915 + -7.6816834319999989 + -13.8940621895999961 + 18.4360402367999967 + -7.6816834319999989 + 1.0242244575999997 + -151.8031018499999618 + 201.5326388519999909 + -83.9719328549999915 + 11.1962577139999979 + 206.0974818899999832 + -273.2155583040000124 + 113.8398159599999957 + -15.1786421279999963 + -85.8739507874999930 + 113.8398159599999815 + -47.4332566499999970 + 6.3244342199999988 + 11.4498601049999991 + -15.1786421279999963 + 6.3244342199999988 + -0.8432578959999998 + 35.4079979087999988 + -46.8875383343999914 + 19.5364743059999952 + -2.6048632407999994 + -47.9516943455999893 + 63.4177924127999972 + -26.4240801719999965 + 3.5232106895999991 + 19.9798726439999967 + -26.4240801719999965 + 11.0100334049999979 + -1.4680044539999997 + -2.6639830191999998 + 3.5232106895999991 + -1.4680044539999997 + 0.1957339271999999 + 42.6442853668999575 + -40.0053803687999618 + 11.9066088158999897 + -1.1642323157999992 + -56.7584044271999559 + 53.3405071583999586 + -15.8754784211999898 + 1.5523097543999986 + 23.6493351779999799 + -22.2252113159999816 + 6.6147826754999954 + -0.6467957309999994 + -3.1532446903999967 + 2.9633615087999976 + -0.8819710233999991 + 0.0862394307999999 + -120.2324494991998876 + 109.5640452863999030 + -32.7718093751999717 + 3.2246967023999971 + 159.8769737135998525 + -146.0853937151998707 + 43.6957458335999576 + -4.2995956031999967 + -66.6154057139999480 + 60.8689140479999509 + -18.2065607639999811 + 1.7914981679999984 + 8.8820540951999920 + -8.1158552063999920 + 2.4275414351999975 + -0.2388664223999998 + 89.9558741243999265 + -82.1730339647999273 + 24.5788570313999770 + -2.4185225267999977 + -119.6268492851999099 + 109.5640452863999030 + -32.7718093751999717 + 3.2246967023999975 + 49.8445205354999530 + -45.6516855359999596 + 13.6549205729999876 + -1.3436236259999990 + -6.6459360713999933 + 6.0868914047999940 + -1.8206560763999984 + 0.1791498167999998 + -19.8930995831999802 + 18.2606742143999838 + -5.4619682291999947 + 0.5374494503999995 + 26.4589082855999749 + -24.3475656191999761 + 7.2826243055999935 + -0.7165992671999993 + -11.0245451189999901 + 10.1448190079999918 + -3.0344267939999972 + 0.2985830279999998 + 1.4699393491999986 + -1.3526425343999988 + 0.4045902391999996 + -0.0398110704000000 + -184.9754434746999721 + 126.2750600519999864 + -28.5549122366999981 + 2.1151786841999995 + 189.3135113616000069 + -129.2160267359999750 + 29.2643043155999933 + -2.1677262455999999 + -64.5253657339999904 + 44.0523311399999926 + -9.9912321314999986 + 0.7400912689999999 + 7.3273586311999983 + -5.0036281519999983 + 1.1364106841999997 + -0.0841785692000000 + 549.7599647855997773 + -378.5554258559998857 + 85.6643485175999899 + -6.3455072976000002 + -561.1830773327999395 + 387.2884078079999881 + -87.7923953568000002 + 6.5031403967999992 + 190.7604902219999872 + -132.0071299200000112 + 29.9734807320000023 + -2.2202578319999997 + -21.6066616295999978 + 14.9909026559999994 + -3.4092032976000000 + 0.2525335776000000 + -412.5384365891999892 + 283.9165693919999285 + -64.2482613882000066 + 4.7591304731999999 + 421.1681889995999200 + -290.4663058559999627 + 65.8442965176000001 + -4.8773552975999994 + -143.1874014164999949 + 99.0053474399999942 + -22.4801105490000026 + 1.6651933740000002 + 16.2206007222000004 + -11.2431769920000004 + 2.5569024732000005 + -0.1894001832000000 + 91.7723027975999912 + -63.0925709760000046 + 14.2773914196000007 + -1.0575845496000000 + -93.7177668888000142 + 64.5480679679999980 + -14.6320658928000018 + 1.0838567328000002 + 31.8714375370000056 + -22.0011883200000042 + 4.9955801220000016 + -0.3700429720000001 + -3.6115132716000011 + 2.4984837760000009 + -0.5682005496000003 + 0.0420889296000000 + 130.2289587202998575 + -70.6241013659999197 + 12.3802240670999844 + -0.7175173373999989 + -173.8642248983998115 + 94.1654684879999024 + -16.5069654227999791 + 0.9566897831999988 + 72.5249910409999359 + -39.2356118699999570 + 6.8779022594999919 + -0.3986207429999995 + -9.6772489387999912 + 5.2314149159999950 + -0.9170536345999990 + 0.0531494323999999 + -395.8553984243995956 + 212.1429210479998346 + -37.1411466587999683 + 2.1525807671999981 + 528.3530069471995603 + -282.8572280639997985 + 49.5215288783999625 + -2.8701076895999975 + -220.3917782279998789 + 117.8571783599999208 + -20.6339703659999856 + 1.1958782039999993 + 29.4073208303999856 + -15.7142904479999928 + 2.7511960487999989 + -0.1594504272000000 + 296.6730858182997963 + -159.1071907859998760 + 27.8558599940999869 + -1.6144355753999990 + -395.9838742103997902 + 212.1429210479998915 + -37.1411466587999826 + 2.1525807671999990 + 165.1767999209999402 + -88.3928837699999690 + 15.4754777744999963 + -0.8969086529999999 + -22.0398861227999987 + 11.7857178359999999 + -2.0633970366000001 + 0.1195878204000000 + -65.8302577373999753 + 35.3571535079999890 + -6.1901911097999989 + 0.3587634612000000 + 87.8715804911999783 + -47.1428713439999996 + 8.2535881464000003 + -0.4783512816000001 + -36.6539405380000005 + 19.6428630600000034 + -3.4389950610000017 + 0.1993130340000001 + 4.8908171384000028 + -2.6190484080000020 + 0.4585326748000005 + -0.0265750712000000 + -5.5045576885001175 + 0.4527535500000591 + -0.0009345375000100 + 0.0000479250000006 + 7.1137969800001573 + -0.6036714000000785 + 0.0012460500000132 + -0.0000639000000007 + -2.8825180750000672 + 0.2515297500000336 + -0.0005191875000056 + 0.0000266250000003 + 0.3770856100000094 + -0.0335373000000047 + 0.0000692250000008 + -0.0000035500000000 + 11.3420452620003189 + -1.0866085200001598 + 0.0022428900000267 + -0.0001150200000015 + -14.5769179680004157 + 1.4488113600002079 + -0.0029905200000346 + 0.0001533600000019 + 5.8290238200001756 + -0.6036714000000871 + 0.0012460500000144 + -0.0000639000000008 + -0.7554527760000237 + 0.0804895200000117 + -0.0001661400000019 + 0.0000085200000001 + -8.7249969465002888 + 0.8149563900001421 + -0.0016821675000234 + 0.0000862650000013 + 11.2135694760003659 + -1.0866085200001803 + 0.0022428900000296 + -0.0001150200000016 + -4.4888016150001500 + 0.4527535500000732 + -0.0009345375000119 + 0.0000479250000006 + 0.5821940820000193 + -0.0603671400000094 + 0.0001246050000015 + -0.0000063900000001 + 2.0359828770000856 + -0.1811014200000415 + 0.0003738150000067 + -0.0000191700000004 + -2.6167403280001054 + 0.2414685600000509 + -0.0004984200000082 + 0.0000255600000004 + 1.0495264700000413 + -0.1006119000000198 + 0.0002076750000032 + -0.0000106500000002 + -0.1363117960000050 + 0.0134149200000024 + -0.0000276900000004 + 0.0000014200000000 + -5.5116026635001862 + 0.4547664000000811 + -0.0010783125000117 + 0.0000479250000006 + 7.1231902800002480 + -0.6063552000001071 + 0.0014377500000154 + -0.0000639000000007 + -2.8864319500001070 + 0.2526480000000459 + -0.0005990625000066 + 0.0000266250000003 + 0.3776074600000149 + -0.0336864000000064 + 0.0000798750000009 + -0.0000035500000000 + 11.3589532020005066 + -1.0914393600002181 + 0.0025879500000312 + -0.0001150200000015 + -14.5994618880006595 + 1.4552524800002826 + -0.0034506000000403 + 0.0001533600000019 + 5.8384171200002770 + -0.6063552000001183 + 0.0014377500000168 + -0.0000639000000008 + -0.7567052160000375 + 0.0808473600000159 + -0.0001917000000022 + 0.0000085200000001 + -8.7376779015004544 + 0.8185795200001927 + -0.0019409625000273 + 0.0000862650000013 + 11.2304774160005767 + -1.0914393600002443 + 0.0025879500000344 + -0.0001150200000016 + -4.4958465900002356 + 0.4547664000000990 + -0.0010783125000139 + 0.0000479250000006 + 0.5831334120000303 + -0.0606355200000127 + 0.0001437750000018 + -0.0000063900000001 + 2.0388008670001336 + -0.1819065600000558 + 0.0004313250000078 + -0.0000191700000004 + -2.6204976480001649 + 0.2425420800000685 + -0.0005751000000095 + 0.0000255600000004 + 1.0510920200000642 + -0.1010592000000266 + 0.0002396250000037 + -0.0000106500000002 + -0.1365205360000077 + 0.0134745600000031 + -0.0000319500000004 + 0.0000014200000000 + 251.7870357364997460 + -92.4596531999998916 + 11.1666529124999840 + -0.4466670749999995 + -335.9416609199996060 + 123.2795375999998271 + -14.8888705499999823 + 0.5955560999999993 + 140.0572560499998076 + -51.3664739999999256 + 6.2036960624999917 + -0.2481483749999996 + -18.6815509399999762 + 6.8488631999999914 + -0.8271594749999989 + 0.0330864500000000 + -606.1577789579991986 + 221.9031676799996831 + -26.7999669899999589 + 1.0720009799999985 + 808.7561809919991447 + -295.8708902399996532 + 35.7332893199999475 + -1.4293346399999980 + -337.2264340799995921 + 123.2795375999998413 + -14.8888705499999787 + 0.5955560999999991 + 44.9852749439999400 + -16.4372716799999807 + 1.9851827399999973 + -0.0794074799999999 + 454.3998712184992428 + -166.4273757599997339 + 20.0999752424999656 + -0.8040007349999987 + -606.2862547439991658 + 221.9031676799996831 + -26.7999669899999589 + 1.0720009799999983 + 252.8027918099996327 + -92.4596531999998632 + 11.1666529124999840 + -0.4466670749999994 + -33.7233517079999530 + 12.3279537599999820 + -1.4888870549999980 + 0.0595556099999999 + -100.8806544929998097 + 36.9838612799999282 + -4.4666611649999908 + 0.1786668299999996 + 134.6054428319997385 + -49.3118150399999138 + 5.9555482199999883 + -0.2382224399999995 + -56.1263831799999053 + 20.5465895999999653 + -2.4814784249999957 + 0.0992593499999998 + 7.4871428239999887 + -2.7395452799999958 + 0.3308637899999995 + -0.0132345800000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3353203725000000 + 0.2235469150000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.8047688940000000 + -0.5365125960000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6035766705000000 + 0.4023844470000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1341281490000000 + -0.0894187660000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 56.1396151825000089 + -135.0033327360000044 + 101.2524995520000033 + -22.5005554560000007 + -49.5027190080000068 + 118.8065256192000163 + -89.1048942144000051 + 19.8010876031999992 + 14.4382930439999981 + -34.6519033056000012 + 25.9889274792000009 + -5.7753172175999996 + -1.3750755280000000 + 3.3001812671999997 + -2.4751359503999999 + 0.5500302112000000 + -125.9664885020000042 + 302.9633875199999693 + -227.2225406400000054 + 50.4938979200000020 + 110.2406780160000039 + -264.5776272383999412 + 198.4332204287999843 + -44.0962712064000044 + -32.1535310880000011 + 77.1684746111999971 + -57.8763559583999978 + 12.8614124351999983 + 3.0622410560000000 + -7.3493785343999996 + 5.5120339008000006 + -1.2248964224000001 + 90.0868110965000000 + -216.6912079679999863 + 162.5184059759999968 + -36.1152013279999977 + -78.7312587600000029 + 188.9550210239999899 + -141.7162657679999995 + 31.4925035040000019 + 22.9632838050000032 + -55.1118811320000077 + 41.3339108490000058 + -9.1853135219999995 + -2.1869794100000002 + 5.2487505839999997 + -3.9365629379999998 + 0.8747917640000000 + -20.5720296569999981 + 49.4801736959999943 + -37.1101302719999921 + 8.2466956160000002 + 17.9932997519999986 + -43.1839194047999939 + 32.3879395535999990 + -7.1973199008000002 + -5.2480457610000002 + 12.5953098263999994 + -9.4464823697999982 + 2.0992183043999999 + 0.4998138820000000 + -1.1995533167999999 + 0.8996649876000000 + -0.1999255528000000 + -157.0620940015000429 + 216.2579120640000099 + -90.1074633599999970 + 12.0143284479999988 + 141.4799946432000013 + -194.6321208576000004 + 81.0967170240000002 + -10.8128956031999994 + -41.2649984375999992 + 56.7677019167999930 + -23.6532091320000006 + 3.1537612175999996 + 3.9299998511999998 + -5.4064478016000006 + 2.2526865840000001 + -0.3003582112000000 + 311.4225038820000009 + -432.5158241280000198 + 180.2149267199999656 + -24.0286568960000011 + -280.7129412863999391 + 389.2642417152000007 + -162.1934340479999719 + 21.6257912063999989 + 81.8746078751999846 + -113.5354038336000144 + 47.3064182640000013 + -6.3075224351999992 + -7.7975817024000005 + 10.8128956032000012 + -4.5053731680000002 + 0.6007164224000000 + -192.3943393994999838 + 270.3223900799999342 + -112.6343291999999963 + 15.0179105600000007 + 173.4794213039999988 + -243.2901510719999578 + 101.3708962799999824 + -13.5161195039999988 + -50.5981645469999961 + 70.9596273960000019 + -29.5665114150000008 + 3.9422015220000004 + 4.8188728140000006 + -6.7580597520000003 + 2.8158582299999999 + -0.3754477640000000 + 37.9715111430000007 + -54.0644780160000025 + 22.5268658399999993 + -3.0035821120000001 + -34.2464746608000041 + 48.6580302144000001 + -20.2741792560000036 + 2.7032239008000003 + 9.9885551094000000 + -14.1919254791999983 + 5.9133022830000002 + -0.7884403044000000 + -0.9512909627999999 + 1.3516119504000002 + -0.5631716460000000 + 0.0750895528000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352400000000010 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769450000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215560000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473690000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352400000000010 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769450000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215560000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473690000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352400000000010 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769450000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215560000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473690000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352400000000010 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769450000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215560000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473690000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352400000000010 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769450000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215560000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473690000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352400000000010 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769450000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215560000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473690000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.0321606498499998 + 4.6881070998999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 24.1765592188499987 + -16.1177061459000015 + 0.0000000000000000 + 0.0000000000000000 + -16.1177061459000015 + 10.7451374305999998 + 0.0000000000000000 + 0.0000000000000000 + 9.1366163297999989 + -6.0910775531999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -30.8078686817999952 + 20.5385791212000015 + 0.0000000000000000 + 0.0000000000000000 + 20.5385791212000015 + -13.6923860808000022 + 0.0000000000000000 + 0.0000000000000000 + -3.8069234707500001 + 2.5379489805000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 12.6594244507499987 + -8.4396163005000009 + 0.0000000000000000 + 0.0000000000000000 + -8.4396163005000009 + 5.6264108670000006 + 0.0000000000000000 + 0.0000000000000000 + 0.5075897961000000 + -0.3383931974000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.6721732600999999 + 1.1147821734000001 + 0.0000000000000000 + 0.0000000000000000 + 1.1147821734000001 + -0.7431881156000000 + 1.7964189073000001 + -9.9371338973999990 + 7.4528504230499992 + -1.6561889829000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -44.4148786822999995 + 125.9369562125999948 + -94.4527171594500032 + 20.9894927021000015 + 30.4859639041999984 + -86.0604782868000200 + 64.5453587151000079 + -14.3434130477999986 + -2.4750911663999995 + 13.2495118631999986 + -9.9371338973999990 + 2.2082519771999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 57.1409193383999963 + -161.7845013575999928 + 121.3383760181999946 + -26.9640835595999988 + -39.2202895176000013 + 110.5595581392000071 + -82.9196686044000160 + 18.4265930231999988 + 1.0312879859999999 + -5.5206299429999994 + 4.1404724572499996 + -0.9201049905000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -23.5724663909999990 + 66.7014588990000021 + -50.0260941742499980 + 11.1169098164999998 + 16.1842872989999975 + -45.5939825580000075 + 34.1954869185000021 + -7.5989970929999995 + -0.1375050648000000 + 0.7360839924000000 + -0.5520629942999999 + 0.1226806654000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1219955187999999 + -8.8305278531999996 + 6.6228958898999997 + -1.4717546422000001 + -2.1439049731999997 + 6.0371976743999998 + -4.5278982558000003 + 1.0061996123999999 + 41.0697356006999996 + -54.7530359903999937 + 22.8137649960000033 + -3.0418353327999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -58.7754249068999925 + 72.4365406655999919 + -30.1818919439999931 + 4.0242522591999990 + 34.4529747782000015 + -41.9835046751999954 + 17.4931269480000005 + -2.3324169264000001 + -52.4181452760000042 + 69.8908603680000056 + -29.1211918200000000 + 3.8828255760000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 71.7688591055999865 + -88.1435659967999783 + 36.7264858319999945 + -4.8968647775999994 + -41.7636522935999963 + 50.6527056287999997 + -21.1052940120000017 + 2.8140392016000000 + 21.8408938650000017 + -29.1211918200000000 + 12.1338299250000006 + -1.6178439899999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -29.9036912939999979 + 36.7264858319999945 + -15.3027024299999965 + 2.0403603239999999 + 17.4015217890000002 + -21.1052940120000017 + 8.7938725049999995 + -1.1725163340000000 + -2.9121191820000001 + 3.8828255760000001 + -1.6178439899999999 + 0.2157125320000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.9871588391999992 + -4.8968647775999994 + 2.0403603239999999 + -0.2720480432000000 + -2.3202029051999999 + 2.8140392016000000 + -1.1725163340000000 + 0.1563355112000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -22.5910445969999856 + 16.9389155015999862 + -5.2449352712999966 + 0.5381739305999996 + 15.0606963979999851 + -11.2926103343999884 + 3.4966235141999964 + -0.3587826203999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 29.8518848603999807 + -22.5852206687999839 + 6.9932470283999955 + -0.7175652407999995 + -19.9012565735999800 + 15.0568137791999828 + -4.6621646855999952 + 0.4783768271999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.4382853584999911 + 9.4105086119999921 + -2.9138529284999981 + 0.2989855169999998 + 8.2921902389999929 + -6.2736724079999924 + 1.9425686189999980 + -0.1993236779999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.6584380477999987 + -1.2547344815999988 + 0.3885137237999997 + -0.0398647356000000 + -1.1056253651999990 + 0.8364896543999990 + -0.2590091491999997 + 0.0265764904000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 132.0402867341999809 + -94.3691021639999832 + 21.4156989368999930 + -1.5863480693999996 + -88.0268578227999967 + 62.9127347760000006 + -14.2771326246000001 + 1.0575653796000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -133.2574315811999668 + 96.4624295519999748 + -21.9475812491999918 + 1.6257467591999992 + 88.8382877207999968 + -64.3082863680000116 + 14.6317208328000028 + -1.0838311728000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 44.7574818254999798 + -32.8519189799999864 + 7.4931545204999956 + -0.5550484829999996 + -29.8383212170000043 + 21.9012793200000040 + -4.9954363470000018 + 0.3700323220000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.0106466433999977 + 3.7277438639999976 + -0.8522720693999993 + 0.0631312643999999 + 3.3404310956000010 + -2.4851625760000013 + 0.5681813796000004 + -0.0420875096000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -104.3657106932998886 + 53.3063472119999489 + -9.2857611221999896 + 0.5381739467999993 + 69.5771404621999920 + -35.5375648079999991 + 6.1905074148000008 + -0.3587826312000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 139.1294649887998673 + -71.0751296159999271 + 12.3810148295999856 + -0.7175652623999991 + -92.7529766592000016 + 47.3834197440000082 + -8.2540098864000022 + 0.4783768416000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -58.0317834119999389 + 29.6146373399999696 + -5.1587561789999938 + 0.2989855259999996 + 38.6878556080000138 + -19.7430915600000105 + 3.4391707860000027 + -0.1993236840000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.7430087215999910 + -3.9486183119999954 + 0.6878341571999992 + -0.0398647367999999 + -5.1620058144000041 + 2.6324122080000025 + -0.4585561048000005 + 0.0265764912000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5694553116999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.7129702077999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.4011244799999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2674163199999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.4783081999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9855388000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2025453600000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1350302400000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5694553116999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.7129702077999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.4011244799999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2674163199999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.4783081999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9855388000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2025453600000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1350302400000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5694553116999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.7129702077999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.4011244799999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2674163199999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.4783081999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9855388000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2025453600000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1350302400000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.6217780473999994 + 21.7478520315999972 + 0.0000000000000000 + 0.0000000000000000 + 80.7563291291999974 + -53.8375527528000006 + 0.0000000000000000 + 0.0000000000000000 + -60.5672468468999909 + 40.3781645645999987 + 0.0000000000000000 + 0.0000000000000000 + 13.4593881881999984 + -8.9729254587999989 + 0.0000000000000000 + 0.0000000000000000 + 42.1036102331999942 + -28.0690734887999973 + 0.0000000000000000 + 0.0000000000000000 + -103.7670803135999904 + 69.1780535423999936 + 0.0000000000000000 + 0.0000000000000000 + 77.8253102351999928 + -51.8835401567999952 + 0.0000000000000000 + 0.0000000000000000 + -17.2945133855999984 + 11.5296755904000001 + 0.0000000000000000 + 0.0000000000000000 + -17.3069209304999987 + 11.5379472869999997 + 0.0000000000000000 + 0.0000000000000000 + 42.5275334640000011 + -28.3516889759999984 + 0.0000000000000000 + 0.0000000000000000 + -31.8956500979999973 + 21.2637667320000006 + 0.0000000000000000 + 0.0000000000000000 + 7.0879222439999996 + -4.7252814960000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2865894573999999 + -1.5243929716000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6073377951999994 + 3.7382251968000002 + 0.0000000000000000 + 0.0000000000000000 + 4.2055033464000005 + -2.8036688975999997 + 0.0000000000000000 + 0.0000000000000000 + -0.9345562992000001 + 0.6230375328000000 + 44.2256531812000020 + -132.2389900727999930 + 99.1792425546000089 + -22.0398316788000024 + -138.5907206816000041 + 397.2227929391999623 + -297.9170947044000286 + 66.2037988232000032 + 105.4788598592000000 + -301.6030611396000722 + 226.2022958547000258 + -50.2671768566000026 + -23.2462882296000011 + 66.5586023016000041 + -49.9189517262000066 + 11.0931003835999995 + -57.1087958435999994 + 170.7439982111999939 + -128.0579986583999812 + 28.4573330352000013 + 178.4133265968000046 + -511.2056480832000034 + 383.4042360624000594 + -85.2009413472000006 + -135.7846198235999964 + 388.1433357647999856 + -291.1075018236000460 + 64.6905559607999976 + 29.9256277248000018 + -85.6571172480000058 + 64.2428379360000008 + -14.2761862080000022 + 23.4803316015000014 + -70.1983325879999995 + 52.6487494410000068 + -11.6997220980000023 + -73.3938860819999945 + 210.1673533680000219 + -157.6255150260000164 + 35.0278922279999989 + 55.8681749265000036 + -159.6001399020000235 + 119.7001049265000034 + -26.6000233170000016 + -12.3115115520000007 + 35.2179655199999999 + -26.4134741400000017 + 5.8696609200000003 + -3.1027108802000001 + 9.2757776784000008 + -6.9568332588000015 + 1.5459629464000002 + 9.7018514776000000 + -27.7703137823999988 + 20.8277353368000000 + -4.6283856304000004 + -7.3860899902000003 + 21.0910186535999991 + -15.8182639902000002 + 3.5151697756000004 + 1.6275348736000002 + -4.6537287359999997 + 3.4902965520000002 + -0.7756214560000001 + -50.0478950811999823 + 64.5349948775999849 + -26.8895811989999878 + 3.5852774931999987 + 183.1902844943999753 + -243.4800953951999247 + 101.4500397479999805 + -13.5266719663999968 + -151.8031018499999618 + 201.5326388519999625 + -83.9719328549999773 + 11.1962577139999979 + 35.4079979087999988 + -46.8875383343999914 + 19.5364743059999952 + -2.6048632407999994 + 69.5343934043999639 + -89.6509583711999625 + 37.3545659879999832 + -4.9806087983999978 + -250.0931194127999504 + 331.8487242623999123 + -138.2703017759999398 + 18.4360402367999932 + 206.0974818899999548 + -273.2155583039999556 + 113.8398159599999815 + -15.1786421279999963 + -47.9516943455999893 + 63.4177924127999830 + -26.4240801719999965 + 3.5232106895999991 + -28.9726639184999897 + 37.3545659879999832 + -15.5644024949999924 + 2.0752536659999992 + 104.2054664219999722 + -138.2703017759999682 + 57.6126257399999844 + -7.6816834319999980 + -85.8739507874999788 + 113.8398159599999815 + -47.4332566499999899 + 6.3244342199999988 + 19.9798726439999967 + -26.4240801719999965 + 11.0100334049999979 + -1.4680044539999997 + 3.8630218557999982 + -4.9806087983999978 + 2.0752536659999992 + -0.2767004887999999 + -13.8940621895999961 + 18.4360402367999932 + -7.6816834319999980 + 1.0242244575999997 + 11.4498601049999973 + -15.1786421279999963 + 6.3244342199999988 + -0.8432578959999998 + -2.6639830191999998 + 3.5232106895999991 + -1.4680044539999997 + 0.1957339272000000 + 42.6442853668999931 + -40.0053803687999974 + 11.9066088159000003 + -1.1642323158000001 + -120.2324494991999728 + 109.5640452863999741 + -32.7718093751999930 + 3.2246967023999997 + 89.9558741243999833 + -82.1730339647999841 + 24.5788570313999983 + -2.4185225267999999 + -19.8930995831999979 + 18.2606742143999980 + -5.4619682291999991 + 0.5374494503999999 + -56.7584044271999986 + 53.3405071583999941 + -15.8754784212000004 + 1.5523097544000002 + 159.8769737135999662 + -146.0853937151999560 + 43.6957458335999860 + -4.2995956031999993 + -119.6268492851999810 + 109.5640452863999741 + -32.7718093751999930 + 3.2246967023999993 + 26.4589082855999962 + -24.3475656191999974 + 7.2826243055999988 + -0.7165992671999999 + 23.6493351779999976 + -22.2252113159999993 + 6.6147826754999990 + -0.6467957310000000 + -66.6154057139999907 + 60.8689140479999864 + -18.2065607639999953 + 1.7914981679999997 + 49.8445205354999885 + -45.6516855359999880 + 13.6549205729999983 + -1.3436236259999998 + -11.0245451189999990 + 10.1448190079999989 + -3.0344267939999998 + 0.2985830280000000 + -3.1532446904000002 + 2.9633615088000003 + -0.8819710234000000 + 0.0862394308000000 + 8.8820540951999991 + -8.1158552063999991 + 2.4275414351999998 + -0.2388664223999999 + -6.6459360713999995 + 6.0868914047999993 + -1.8206560763999997 + 0.1791498168000000 + 1.4699393491999997 + -1.3526425343999997 + 0.4045902391999999 + -0.0398110704000000 + -184.9754434747000289 + 126.2750600520000148 + -28.5549122367000052 + 2.1151786842000004 + 549.7599647856001184 + -378.5554258559999994 + 85.6643485176000183 + -6.3455072976000011 + -412.5384365892000460 + 283.9165693920000422 + -64.2482613882000066 + 4.7591304732000008 + 91.7723027976000196 + -63.0925709760000046 + 14.2773914196000042 + -1.0575845496000000 + 189.3135113616000353 + -129.2160267360000034 + 29.2643043156000076 + -2.1677262455999999 + -561.1830773328000532 + 387.2884078080000450 + -87.7923953568000144 + 6.5031403968000010 + 421.1681889996000336 + -290.4663058560000763 + 65.8442965176000143 + -4.8773552976000012 + -93.7177668888000142 + 64.5480679680000122 + -14.6320658928000036 + 1.0838567328000002 + -64.5253657340000046 + 44.0523311400000068 + -9.9912321315000003 + 0.7400912690000001 + 190.7604902220000156 + -132.0071299200000112 + 29.9734807320000058 + -2.2202578320000006 + -143.1874014165000233 + 99.0053474400000084 + -22.4801105490000026 + 1.6651933740000002 + 31.8714375370000056 + -22.0011883200000042 + 4.9955801220000016 + -0.3700429720000001 + 7.3273586312000010 + -5.0036281520000010 + 1.1364106842000001 + -0.0841785692000000 + -21.6066616296000049 + 14.9909026560000029 + -3.4092032976000008 + 0.2525335776000001 + 16.2206007222000039 + -11.2431769920000022 + 2.5569024732000005 + -0.1894001832000000 + -3.6115132716000002 + 2.4984837760000005 + -0.5682005496000001 + 0.0420889296000000 + 130.2289587202999428 + -70.6241013659999624 + 12.3802240670999915 + -0.7175173373999993 + -395.8553984243998229 + 212.1429210479999199 + -37.1411466587999826 + 2.1525807671999990 + 296.6730858182999100 + -159.1071907859999612 + 27.8558599940999905 + -1.6144355753999995 + -65.8302577373999895 + 35.3571535079999961 + -6.1901911097999989 + 0.3587634612000000 + -173.8642248983998968 + 94.1654684879999451 + -16.5069654227999898 + 0.9566897831999992 + 528.3530069471997876 + -282.8572280639999121 + 49.5215288783999910 + -2.8701076895999988 + -395.9838742103999607 + 212.1429210479999483 + -37.1411466587999897 + 2.1525807671999995 + 87.8715804911999925 + -47.1428713439999996 + 8.2535881464000003 + -0.4783512816000000 + 72.5249910409999643 + -39.2356118699999783 + 6.8779022594999955 + -0.3986207429999997 + -220.3917782279999642 + 117.8571783599999776 + -20.6339703659999927 + 1.1958782039999996 + 165.1767999209999687 + -88.3928837699999974 + 15.4754777744999981 + -0.8969086529999999 + -36.6539405380000005 + 19.6428630599999998 + -3.4389950610000004 + 0.1993130340000000 + -9.6772489387999947 + 5.2314149159999976 + -0.9170536345999994 + 0.0531494324000000 + 29.4073208303999962 + -15.7142904479999963 + 2.7511960487999998 + -0.1594504272000000 + -22.0398861227999987 + 11.7857178359999999 + -2.0633970366000001 + 0.1195878204000000 + 4.8908171384000010 + -2.6190484080000003 + 0.4585326748000001 + -0.0265750712000000 + -5.5045576884998377 + 0.4527535499999218 + -0.0009345374999876 + 0.0000479249999993 + 11.3420452619995764 + -1.0866085199997961 + 0.0022428899999674 + -0.0001150199999983 + -8.7249969464996404 + 0.8149563899998263 + -0.0016821674999721 + 0.0000862649999985 + 2.0359828769999018 + -0.1811014199999522 + 0.0003738149999923 + -0.0000191699999996 + 7.1137969799997833 + -0.6036713999998966 + 0.0012460499999836 + -0.0000638999999991 + -14.5769179679994441 + 1.4488113599997343 + -0.0029905199999576 + 0.0001533599999978 + 11.2135694759995364 + -1.0866085199997786 + 0.0022428899999646 + -0.0001150199999981 + -2.6167403279998775 + 0.2414685599999410 + -0.0004984199999905 + 0.0000255599999995 + -2.8825180749999051 + 0.2515297499999547 + -0.0005191874999928 + 0.0000266249999996 + 5.8290238199997608 + -0.6036713999998863 + 0.0012460499999820 + -0.0000638999999990 + -4.4888016149998080 + 0.4527535499999084 + -0.0009345374999855 + 0.0000479249999992 + 1.0495264699999514 + -0.1006118999999768 + 0.0002076749999963 + -0.0000106499999998 + 0.3770856099999864 + -0.0335372999999935 + 0.0000692249999990 + -0.0000035499999999 + -0.7554527759999667 + 0.0804895199999842 + -0.0001661399999975 + 0.0000085199999999 + 0.5821940819999744 + -0.0603671399999879 + 0.0001246049999981 + -0.0000063899999999 + -0.1363117959999940 + 0.0134149199999972 + -0.0000276899999996 + 0.0000014200000000 + -5.5116026634997457 + 0.4547663999998953 + -0.0010783124999857 + 0.0000479249999993 + 11.3589532019993378 + -1.0914393599997261 + 0.0025879499999623 + -0.0001150199999983 + -8.7376779014994366 + 0.8185795199997661 + -0.0019409624999676 + 0.0000862649999985 + 2.0388008669998454 + -0.1819065599999353 + 0.0004313249999910 + -0.0000191699999996 + 7.1231902799996636 + -0.6063551999998610 + 0.0014377499999810 + -0.0000638999999991 + -14.5994618879991389 + 1.4552524799996427 + -0.0034505999999509 + 0.0001533599999978 + 11.2304774159992817 + -1.0914393599997021 + 0.0025879499999590 + -0.0001150199999981 + -2.6204976479998088 + 0.2425420799999205 + -0.0005750999999890 + 0.0000255599999995 + -2.8864319499998530 + 0.2526479999999392 + -0.0005990624999917 + 0.0000266249999996 + 5.8384171199996304 + -0.6063551999998473 + 0.0014377499999791 + -0.0000638999999990 + -4.4958465899997018 + 0.4547663999998769 + -0.0010783124999832 + 0.0000479249999992 + 1.0510920199999245 + -0.1010591999999689 + 0.0002396249999957 + -0.0000106499999998 + 0.3776074599999789 + -0.0336863999999913 + 0.0000798749999988 + -0.0000035499999999 + -0.7567052159999486 + 0.0808473599999789 + -0.0001916999999971 + 0.0000085199999999 + 0.5831334119999604 + -0.0606355199999838 + 0.0001437749999978 + -0.0000063899999999 + -0.1365205359999907 + 0.0134745599999963 + -0.0000319499999995 + 0.0000014200000000 + 251.7870357365003713 + -92.4596532000001332 + 11.1666529125000178 + -0.4466670750000007 + -606.1577789580009039 + 221.9031676800003083 + -26.7999669900000406 + 1.0720009800000017 + 454.3998712185007207 + -166.4273757600003023 + 20.0999752425000366 + -0.8040007350000014 + -100.8806544930002360 + 36.9838612800000845 + -4.4666611650000103 + 0.1786668300000004 + -335.9416609200004586 + 123.2795376000001681 + -14.8888705500000214 + 0.5955561000000008 + 808.7561809920013047 + -295.8708902400004490 + 35.7332893200000541 + -1.4293346400000022 + -606.2862547440010985 + 221.9031676800003652 + -26.7999669900000441 + 1.0720009800000017 + 134.6054428320002785 + -49.3118150400000985 + 5.9555482200000114 + -0.2382224400000005 + 140.0572560500002055 + -51.3664740000000748 + 6.2036960625000095 + -0.2481483750000004 + -337.2264340800005584 + 123.2795376000001966 + -14.8888705500000231 + 0.5955561000000009 + 252.8027918100004001 + -92.4596532000001616 + 11.1666529125000178 + -0.4466670750000007 + -56.1263831800001043 + 20.5465896000000399 + -2.4814784250000046 + 0.0992593500000002 + -18.6815509400000295 + 6.8488632000000109 + -0.8271594750000013 + 0.0330864500000001 + 44.9852749440000750 + -16.4372716800000234 + 1.9851827400000031 + -0.0794074800000001 + -33.7233517080000524 + 12.3279537600000193 + -1.4888870550000024 + 0.0595556100000001 + 7.4871428240000135 + -2.7395452800000046 + 0.3308637900000005 + -0.0132345800000000 + 0.0000000000000000 + 0.0000000000000000 + 204.6814854389999709 + -136.4543236259999901 + 0.0000000000000000 + 0.0000000000000000 + -270.4943405699999630 + 180.3295603799999753 + 0.0000000000000000 + 0.0000000000000000 + 112.7059752374999988 + -75.1373168249999992 + 0.0000000000000000 + 0.0000000000000000 + -15.0274633649999991 + 10.0183089100000000 + 0.0000000000000000 + 0.0000000000000000 + -270.4943405699999630 + 180.3295603799999753 + 0.0000000000000000 + 0.0000000000000000 + 357.4400451840000414 + -238.2933634559999803 + 0.0000000000000000 + 0.0000000000000000 + -148.9333521599999983 + 99.2889014399999894 + 0.0000000000000000 + 0.0000000000000000 + 19.8577802880000007 + -13.2385201919999993 + 0.0000000000000000 + 0.0000000000000000 + 112.7059752374999988 + -75.1373168249999992 + 0.0000000000000000 + 0.0000000000000000 + -148.9333521599999983 + 99.2889014399999894 + 0.0000000000000000 + 0.0000000000000000 + 62.0555634000000040 + -41.3703755999999956 + 0.0000000000000000 + 0.0000000000000000 + -8.2740751199999991 + 5.5160500800000003 + 0.0000000000000000 + 0.0000000000000000 + -15.0274633649999991 + 10.0183089100000000 + 0.0000000000000000 + 0.0000000000000000 + 19.8577802880000007 + -13.2385201919999993 + 0.0000000000000000 + 0.0000000000000000 + -8.2740751199999991 + 5.5160500800000003 + 0.0000000000000000 + 0.0000000000000000 + 1.1032100160000000 + -0.7354733440000000 + -221.1055395120000071 + 694.3984831799999711 + -520.7988623850000067 + 115.7330805300000094 + 278.7592949099999373 + -885.4177802399999564 + 664.0633351800000810 + -147.5696300400000212 + -112.8727612125000093 + 361.0594071000000440 + -270.7945553250000330 + 60.1765678499999979 + 14.7584174950000016 + -47.4421726800000059 + 35.5816295099999991 + -7.9070287800000010 + 278.7592949099999942 + -885.4177802400001838 + 664.0633351800000810 + -147.5696300400000212 + -351.5299650720000955 + 1129.6239523200001713 + -847.2179642400000148 + 188.2706587200000001 + 142.2576037800000108 + -460.5649308000000133 + 345.4236981000000242 + -76.7608218000000022 + -18.5931725040000018 + 60.5098382400000006 + -45.3823786800000022 + 10.0849730400000013 + -112.8727612125000093 + 361.0594071000000440 + -270.7945553250000330 + 60.1765678499999979 + 142.2576037800000108 + -460.5649308000000133 + 345.4236981000000242 + -76.7608218000000022 + -57.5184953249999964 + 187.6888395000000003 + -140.7666296250000073 + 31.2814732499999977 + 7.5130877100000006 + -24.6506705999999980 + 18.4880029500000020 + -4.1084451000000000 + 14.7584174950000016 + -47.4421726800000059 + 35.5816295099999991 + -7.9070287800000001 + -18.5931725040000018 + 60.5098382400000006 + -45.3823786800000022 + 10.0849730399999995 + 7.5130877100000006 + -24.6506705999999980 + 18.4880029499999985 + -4.1084451000000000 + -0.9809390280000001 + 3.2368216800000003 + -2.4276162599999997 + 0.5394702800000000 + 191.0667307679999567 + -232.3364261399999577 + 96.8068442249999919 + -12.9075792299999978 + -257.3214441299999748 + 309.7819015199999626 + -129.0757922999999892 + 17.2101056399999948 + 107.8726573874999985 + -129.0757922999999892 + 53.7815801249999978 + -7.1708773499999996 + -14.4412777849999969 + 17.2101056399999983 + -7.1708773499999996 + 0.9561169799999999 + -257.3214441299999748 + 309.7819015199999058 + -129.0757922999999892 + 17.2101056399999948 + 346.2666576479999776 + -413.0425353599999312 + 172.1010563999999761 + -22.9468075199999966 + -145.1204170199999908 + 172.1010564000000045 + -71.7087734999999924 + 9.5611698000000001 + 19.4242905360000009 + -22.9468075200000001 + 9.5611698000000001 + -1.2748226400000000 + 107.8726573874999701 + -129.0757922999999892 + 53.7815801249999907 + -7.1708773499999987 + -145.1204170199999908 + 172.1010563999999761 + -71.7087734999999924 + 9.5611697999999983 + 60.8179416749999930 + -71.7087734999999924 + 29.8786556250000004 + -3.9838207499999996 + -8.1402678900000005 + 9.5611698000000001 + -3.9838207500000000 + 0.5311760999999999 + -14.4412777849999969 + 17.2101056399999948 + -7.1708773499999987 + 0.9561169799999998 + 19.4242905359999973 + -22.9468075199999966 + 9.5611697999999983 + -1.2748226399999998 + -8.1402678900000005 + 9.5611697999999983 + -3.9838207499999996 + 0.5311760999999999 + 1.0895302519999999 + -1.2748226400000000 + 0.5311760999999999 + -0.0708234800000000 + -91.7268526394999384 + 94.0688623799999277 + -26.5321536524999857 + 2.4120022049999981 + 119.7366670799999042 + -125.4251498399999036 + 35.3762048699999738 + -3.2160029399999974 + -49.2348889499999558 + 52.2604790999999622 + -14.7400853624999861 + 1.3400012249999991 + 6.5063950599999956 + -6.9680638799999954 + 1.9653447149999987 + -0.1786668299999999 + 119.7366670799999042 + -125.4251498399999036 + 35.3762048699999738 + -3.2160029399999974 + -156.4774906319998422 + 167.2335331199998905 + -47.1682731599999627 + 4.2880039199999960 + 64.3563114299999484 + -69.6806387999999401 + 19.6534471499999839 + -1.7866682999999985 + -8.5059399239999927 + 9.2907518399999933 + -2.6204596199999983 + 0.2382224399999998 + -49.2348889499999558 + 52.2604790999999622 + -14.7400853624999897 + 1.3400012249999991 + 64.3563114299999484 + -69.6806387999999401 + 19.6534471499999839 + -1.7866682999999985 + -26.4640285124999792 + 29.0335994999999798 + -8.1889363124999939 + 0.7444451249999995 + 3.4973281349999974 + -3.8711465999999977 + 1.0918581749999994 + -0.0992593499999999 + 6.5063950599999956 + -6.9680638799999954 + 1.9653447149999987 + -0.1786668299999999 + -8.5059399239999927 + 9.2907518399999933 + -2.6204596199999983 + 0.2382224399999998 + 3.4973281349999974 + -3.8711465999999977 + 1.0918581749999994 + -0.0992593499999999 + -0.4621492179999996 + 0.5161528799999997 + -0.1455810899999999 + 0.0132345800000000 + 24.0740975205001106 + -2.4277887000000864 + 0.0034937325000216 + -0.0002587950000018 + -34.6645998000001612 + 3.2370516000001230 + -0.0046583100000299 + 0.0003450600000024 + 15.0989722500000738 + -1.3487715000000551 + 0.0019409625000130 + -0.0001437750000010 + -2.0714531000000118 + 0.1798362000000081 + -0.0002587950000018 + 0.0000191700000001 + -34.6645998000001612 + 3.2370516000001235 + -0.0046583100000299 + 0.0003450600000024 + 49.3908652080002355 + -4.3160688000001688 + 0.0062110800000399 + -0.0004600800000031 + -21.4221701700001006 + 1.7983620000000724 + -0.0025879500000166 + 0.0001917000000013 + 2.9311909560000142 + -0.2397816000000101 + 0.0003450600000022 + -0.0000255600000002 + 15.0989722500000720 + -1.3487715000000551 + 0.0019409625000130 + -0.0001437750000010 + -21.4221701700001006 + 1.7983620000000724 + -0.0025879500000166 + 0.0001917000000013 + 9.2770054875000412 + -0.7493175000000296 + 0.0010783125000066 + -0.0000798750000005 + -1.2681430650000054 + 0.0999090000000038 + -0.0001437750000008 + 0.0000106500000001 + -2.0714531000000118 + 0.1798362000000081 + -0.0002587950000018 + 0.0000191700000001 + 2.9311909560000142 + -0.2397816000000101 + 0.0003450600000022 + -0.0000255600000002 + -1.2681430650000054 + 0.0999090000000038 + -0.0001437750000008 + 0.0000106500000001 + 0.1732469420000007 + -0.0133212000000004 + 0.0000191700000001 + -0.0000014200000000 + 24.0935071455002721 + -2.4355525500001534 + 0.0042701175000289 + -0.0002587950000018 + -34.6904793000003693 + 3.2474034000002079 + -0.0056934900000389 + 0.0003450600000024 + 15.1097553750001588 + -1.3530847500000884 + 0.0023722875000164 + -0.0001437750000010 + -2.0728908500000220 + 0.1804113000000122 + -0.0003163050000022 + 0.0000191700000001 + -34.6904793000003622 + 3.2474034000002079 + -0.0056934900000389 + 0.0003450600000024 + 49.4253712080004988 + -4.3298712000002757 + 0.0075913200000511 + -0.0004600800000031 + -21.4365476700002091 + 1.8041130000001138 + -0.0031630500000209 + 0.0001917000000013 + 2.9331079560000273 + -0.2405484000000150 + 0.0004217400000027 + -0.0000255600000002 + 15.1097553750001588 + -1.3530847500000884 + 0.0023722875000164 + -0.0001437750000010 + -21.4365476700002091 + 1.8041130000001140 + -0.0031630500000209 + 0.0001917000000013 + 9.2829961125000828 + -0.7517137500000454 + 0.0013179375000082 + -0.0000798750000005 + -1.2689418150000105 + 0.1002285000000056 + -0.0001757250000010 + 0.0000106500000001 + -2.0728908500000220 + 0.1804113000000122 + -0.0003163050000022 + 0.0000191700000001 + 2.9331079560000273 + -0.2405484000000150 + 0.0004217400000027 + -0.0000255600000002 + -1.2689418150000105 + 0.1002285000000056 + -0.0001757250000010 + 0.0000106500000001 + 0.1733534420000013 + -0.0133638000000006 + 0.0000234300000001 + -0.0000014200000000 + 24.1214570055004529 + -2.4448691700002163 + 0.0050465025000343 + -0.0002587950000018 + -34.7277457800006175 + 3.2598255600002939 + -0.0067286700000462 + 0.0003450600000024 + 15.1252830750002651 + -1.3582606500001246 + 0.0028036125000195 + -0.0001437750000010 + -2.0749612100000361 + 0.1811014200000171 + -0.0003738150000026 + 0.0000191700000001 + -34.7277457800006175 + 3.2598255600002939 + -0.0067286700000462 + 0.0003450600000024 + 49.4750598480008250 + -4.3464340800003880 + 0.0089715600000605 + -0.0004600800000031 + -21.4572512700003450 + 1.8110142000001597 + -0.0037381500000247 + 0.0001917000000013 + 2.9358684360000451 + -0.2414685600000209 + 0.0004984200000032 + -0.0000255600000002 + 15.1252830750002616 + -1.3582606500001246 + 0.0028036125000195 + -0.0001437750000010 + -21.4572512700003450 + 1.8110142000001597 + -0.0037381500000247 + 0.0001917000000013 + 9.2916226125001380 + -0.7545892500000633 + 0.0015575625000096 + -0.0000798750000005 + -1.2700920150000172 + 0.1006119000000078 + -0.0002076750000012 + 0.0000106500000001 + -2.0749612100000361 + 0.1811014200000171 + -0.0003738150000026 + 0.0000191700000001 + 2.9358684360000451 + -0.2414685600000209 + 0.0004984200000032 + -0.0000255600000002 + -1.2700920150000172 + 0.1006119000000078 + -0.0002076750000012 + 0.0000106500000001 + 0.1735068020000020 + -0.0134149200000009 + 0.0000276900000001 + -0.0000014200000000 + 24.1594998705007029 + -2.4557385600002908 + 0.0058228875000397 + -0.0002587950000018 + -34.7784696000009532 + 3.2743180800003930 + -0.0077638500000534 + 0.0003450600000024 + 15.1464180000004074 + -1.3642992000001666 + 0.0032349375000225 + -0.0001437750000010 + -2.0777792000000561 + 0.1819065600000228 + -0.0004313250000031 + 0.0000191700000001 + -34.7784696000009532 + 3.2743180800003930 + -0.0077638500000534 + 0.0003450600000024 + 49.5426916080012703 + -4.3657574400005181 + 0.0103518000000699 + -0.0004600800000031 + -21.4854311700005276 + 1.8190656000002128 + -0.0043132500000285 + 0.0001917000000013 + 2.9396257560000691 + -0.2425420800000277 + 0.0005751000000037 + -0.0000255600000002 + 15.1464180000004074 + -1.3642992000001666 + 0.0032349375000225 + -0.0001437750000010 + -21.4854311700005276 + 1.8190656000002128 + -0.0043132500000285 + 0.0001917000000013 + 9.3033642375002099 + -0.7579440000000840 + 0.0017971875000111 + -0.0000798750000005 + -1.2716575650000261 + 0.1010592000000103 + -0.0002396250000013 + 0.0000106500000001 + -2.0777792000000561 + 0.1819065600000228 + -0.0004313250000031 + 0.0000191700000001 + 2.9396257560000691 + -0.2425420800000277 + 0.0005751000000037 + -0.0000255600000002 + -1.2716575650000261 + 0.1010592000000103 + -0.0002396250000013 + 0.0000106500000001 + 0.1737155420000029 + -0.0134745600000011 + 0.0000319500000001 + -0.0000014200000000 + -1365.2531474894988150 + 499.2821272799995995 + -60.2999257274999536 + 2.4120022049999981 + 1817.7717268799983685 + -665.7095030399993902 + 80.3999009699999192 + -3.2160029399999974 + -756.7494971999993822 + 277.3789595999998028 + -33.4999587374999663 + 1.3400012249999991 + 100.8416761599999063 + -36.9838612799999709 + 4.4666611649999961 + -0.1786668299999999 + 1817.7717268799983685 + -665.7095030399995039 + 80.3999009699999192 + -3.2160029399999974 + -2420.5242370319979273 + 887.6126707199993007 + -107.1998679599999207 + 4.2880039199999960 + 1007.7091224299991836 + -369.8386127999996802 + 44.6666116499999646 + -1.7866682999999985 + -134.2863147239999080 + 49.3118150399999564 + -5.9555482199999954 + 0.2382224399999998 + -756.7494971999992686 + 277.3789595999998028 + -33.4999587374999663 + 1.3400012249999991 + 1007.7091224299990699 + -369.8386127999996802 + 44.6666116499999646 + -1.7866682999999985 + -419.5276997624996511 + 154.0994219999998904 + -18.6110881874999841 + 0.7444451249999995 + 55.9058176349999627 + -20.5465895999999830 + 2.4814784249999979 + -0.0992593499999999 + 100.8416761599999063 + -36.9838612799999709 + 4.4666611649999961 + -0.1786668299999999 + -134.2863147239999080 + 49.3118150399999564 + -5.9555482199999954 + 0.2382224399999998 + 55.9058176349999627 + -20.5465895999999830 + 2.4814784249999979 + -0.0992593499999999 + -7.4499478179999956 + 2.7395452799999984 + -0.3308637899999998 + 0.0132345800000000 + 0.0000000000000000 + 0.0000000000000000 + 1.8107300115000000 + -1.2071533409999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.4143066819999999 + 1.6095377879999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.0059611175000001 + -0.6706407450000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1341281490000000 + 0.0894187660000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 225.3083766705000244 + -539.2915199999999913 + 404.4686400000000503 + -89.8819200000000080 + -202.2343199999999968 + 485.3623680000000604 + -364.0217760000000453 + 80.8937280000000101 + 58.9850100000000026 + -141.5640239999999892 + 106.1730180000000132 + -23.5940039999999982 + -5.6176200000000005 + 13.4822880000000005 + -10.1117160000000013 + 2.2470479999999999 + -262.9603688939999984 + 629.1734400000000278 + -471.8800800000000208 + 104.8622400000000141 + 235.9400400000000104 + -566.2560960000000705 + 424.6920720000000529 + -94.3760159999999928 + -68.8158449999999959 + 165.1580280000000300 + -123.8685210000000154 + 27.5263379999999991 + 6.5538900000000009 + -15.7293360000000000 + 11.7970019999999991 + -2.6215560000000000 + 100.2041203725000003 + -239.6851199999999835 + 179.7638400000000161 + -39.9475199999999973 + -89.8819200000000080 + 215.7166080000000079 + -161.7874560000000201 + 35.9527679999999989 + 26.2155599999999964 + -62.9173439999999999 + 47.1880080000000035 + -10.4862240000000000 + -2.4967199999999998 + 5.9921279999999992 + -4.4940959999999999 + 0.9986880000000000 + -12.5283093829999999 + 29.9606400000000015 + -22.4704800000000020 + 4.9934399999999997 + 11.2352400000000010 + -26.9645760000000010 + 20.2234320000000025 + -4.4940959999999999 + -3.2769449999999996 + 7.8646680000000000 + -5.8985010000000004 + 1.3107780000000000 + 0.3120900000000000 + -0.7490160000000000 + 0.5617620000000000 + -0.1248360000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888939999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880079999999964 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803724999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763839999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1796984025000000 + 0.1197989350000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5390952075000000 + -0.3593968050000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3593968050000000 + 0.2395978700000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0598994675000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.7523780425000002 + -15.7744311360000005 + 11.8308233519999995 + -2.6290718559999999 + -7.0045704549999996 + 16.5234516479999982 + -12.3925887360000004 + 2.7539086080000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -6.7580597519999994 + 16.2193434048000000 + -12.1645075536000000 + 2.7032239007999999 + 6.7580597519999994 + -16.2193434048000000 + 12.1645075536000000 + -2.7032239007999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.9711007609999998 + -4.7306418263999994 + 3.5479813698000000 + -0.7884403043999999 + -1.9711007609999998 + 4.7306418263999994 + -3.5479813698000000 + 0.7884403043999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1877238820000000 + 0.4505373168000000 + -0.3379029876000000 + 0.0750895528000000 + 0.1877238820000000 + -0.4505373168000000 + 0.3379029876000000 + -0.0750895528000000 + 1.7561266437000007 + -2.3348907144000020 + 0.9728711310000014 + -0.1297161508000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -46.0039935710999970 + 61.0691501591999995 + -25.4454792330000004 + 3.3927305643999999 + 44.1854485514000146 + -58.7342594448000099 + 24.4726081020000059 + -3.2630144136000014 + -0.0000000000000012 + 0.0000000000000029 + -0.0000000000000020 + 0.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 36.4935226607999965 + -48.6580302144000001 + 20.2741792560000000 + -2.7032239007999999 + -36.4935226608000107 + 48.6580302144000143 + -20.2741792560000071 + 2.7032239008000012 + 0.0000000000000005 + -0.0000000000000012 + 0.0000000000000008 + -0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -10.6439441093999996 + 14.1919254792000000 + -5.9133022830000002 + 0.7884403043999999 + 10.6439441094000031 + -14.1919254792000071 + 5.9133022830000037 + -0.7884403044000006 + -0.0000000000000001 + 0.0000000000000002 + -0.0000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.0137089628000000 + -1.3516119503999999 + 0.5631716460000000 + -0.0750895528000000 + -1.0137089628000004 + 1.3516119504000006 + -0.5631716460000002 + 0.0750895528000001 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0049586079000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2021309517000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1347539678000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3353203725000000 + 0.2235469150000000 + 0.0000000000000000 + 0.0000000000000000 + 0.8047688940000000 + -0.5365125960000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6035766705000000 + 0.4023844470000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1341281490000000 + -0.0894187660000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 56.1396151825000018 + -135.0033327360000044 + 101.2524995520000033 + -22.5005554560000007 + -125.9664885020000042 + 302.9633875199999693 + -227.2225406399999770 + 50.4938979199999949 + 90.0868110964999858 + -216.6912079679999579 + 162.5184059759999968 + -36.1152013279999977 + -20.5720296569999981 + 49.4801736959999943 + -37.1101302719999921 + 8.2466956160000002 + -49.5027190080000068 + 118.8065256192000163 + -89.1048942144000051 + 19.8010876031999992 + 110.2406780160000039 + -264.5776272383999412 + 198.4332204287999843 + -44.0962712064000044 + -78.7312587600000029 + 188.9550210239999615 + -141.7162657679999711 + 31.4925035039999983 + 17.9932997519999986 + -43.1839194047999939 + 32.3879395535999990 + -7.1973199008000002 + 14.4382930439999981 + -34.6519033056000012 + 25.9889274792000009 + -5.7753172175999996 + -32.1535310880000011 + 77.1684746111999971 + -57.8763559583999978 + 12.8614124351999983 + 22.9632838049999997 + -55.1118811319999935 + 41.3339108489999987 + -9.1853135219999995 + -5.2480457610000002 + 12.5953098263999994 + -9.4464823697999982 + 2.0992183043999999 + -1.3750755280000000 + 3.3001812671999997 + -2.4751359503999999 + 0.5500302112000000 + 3.0622410560000000 + -7.3493785343999996 + 5.5120339008000006 + -1.2248964224000001 + -2.1869794100000002 + 5.2487505839999997 + -3.9365629379999998 + 0.8747917640000000 + 0.4998138820000000 + -1.1995533167999999 + 0.8996649876000000 + -0.1999255528000000 + -157.0620940015000429 + 216.2579120640000099 + -90.1074633599999970 + 12.0143284479999988 + 311.4225038820000009 + -432.5158241280000198 + 180.2149267199999940 + -24.0286568960000011 + -192.3943393995000122 + 270.3223900799999910 + -112.6343292000000105 + 15.0179105600000007 + 37.9715111430000007 + -54.0644780160000025 + 22.5268658399999993 + -3.0035821120000001 + 141.4799946432000013 + -194.6321208576000004 + 81.0967170240000002 + -10.8128956031999994 + -280.7129412863999960 + 389.2642417152000007 + -162.1934340480000003 + 21.6257912063999989 + 173.4794213039999988 + -243.2901510719999862 + 101.3708962799999966 + -13.5161195040000006 + -34.2464746608000041 + 48.6580302144000001 + -20.2741792560000036 + 2.7032239008000003 + -41.2649984375999992 + 56.7677019167999930 + -23.6532091319999971 + 3.1537612175999996 + 81.8746078751999988 + -113.5354038336000144 + 47.3064182640000013 + -6.3075224351999992 + -50.5981645469999961 + 70.9596273959999877 + -29.5665114149999972 + 3.9422015219999995 + 9.9885551094000000 + -14.1919254791999983 + 5.9133022830000002 + -0.7884403044000000 + 3.9299998511999998 + -5.4064478016000006 + 2.2526865840000001 + -0.3003582112000000 + -7.7975817024000005 + 10.8128956032000012 + -4.5053731680000002 + 0.6007164224000000 + 4.8188728140000006 + -6.7580597520000003 + 2.8158582299999999 + -0.3754477640000000 + -0.9512909628000000 + 1.3516119504000002 + -0.5631716460000000 + 0.0750895528000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473689999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352399999999992 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999980 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769449999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215559999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553889999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473689999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352399999999992 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999980 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769449999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215559999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553889999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473689999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352399999999992 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999980 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769449999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215559999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553889999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473689999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352399999999992 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999980 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769449999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215559999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553889999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473689999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352399999999992 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999980 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769449999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215559999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553889999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.1313400465000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -12.9643642139999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 10.3474531604999989 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5768473689999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4940959999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2352399999999992 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.9881919999999980 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.2769449999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.6215559999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553889999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1248360000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3120900000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2496720000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.8107300115000000 + -1.2071533409999999 + 0.0000000000000000 + 0.0000000000000000 + -2.4143066819999999 + 1.6095377879999999 + 0.0000000000000000 + 0.0000000000000000 + 1.0059611175000001 + -0.6706407450000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1341281490000000 + 0.0894187660000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 225.3083766704999960 + -539.2915199999999913 + 404.4686400000000503 + -89.8819200000000080 + -262.9603688939999984 + 629.1734400000000278 + -471.8800800000000208 + 104.8622400000000141 + 100.2041203725000003 + -239.6851200000000119 + 179.7638400000000161 + -39.9475200000000044 + -12.5283093829999999 + 29.9606400000000015 + -22.4704800000000020 + 4.9934399999999997 + -202.2343199999999968 + 485.3623680000000036 + -364.0217760000000453 + 80.8937280000000101 + 235.9400400000000104 + -566.2560960000000705 + 424.6920720000000529 + -94.3760160000000070 + -89.8819200000000080 + 215.7166080000000079 + -161.7874560000000201 + 35.9527680000000061 + 11.2352400000000010 + -26.9645760000000010 + 20.2234320000000025 + -4.4940959999999999 + 58.9850100000000026 + -141.5640239999999892 + 106.1730180000000132 + -23.5940039999999982 + -68.8158449999999959 + 165.1580280000000016 + -123.8685210000000154 + 27.5263379999999991 + 26.2155600000000035 + -62.9173440000000070 + 47.1880080000000035 + -10.4862240000000000 + -3.2769449999999996 + 7.8646680000000000 + -5.8985010000000004 + 1.3107780000000000 + -5.6176200000000005 + 13.4822880000000005 + -10.1117160000000013 + 2.2470479999999999 + 6.5538900000000009 + -15.7293360000000000 + 11.7970019999999991 + -2.6215560000000000 + -2.4967199999999998 + 5.9921279999999992 + -4.4940959999999999 + 0.9986880000000000 + 0.3120900000000000 + -0.7490160000000000 + 0.5617620000000000 + -0.1248360000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 45.5445366704999941 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -53.2358888940000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 20.3090803725000022 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.5414293830000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.4468640000000050 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 47.1880080000000035 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9763840000000030 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2470479999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.7970019999999991 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.7631689999999995 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.2431120000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6553890000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.1235240000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3107780000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4993440000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0624180000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + +# piCH + +6 +0.0 +4.0 +0.0 +4.0 +0.0 +9.0 + + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.3500000000000001 + 0.9000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000000 + -0.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000000 + -0.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + -0.6000000000000001 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -63.4499999999999886 + 80.9999999999999858 + -33.7499999999999929 + 4.4999999999999991 + 42.2999999999999972 + -53.9999999999999858 + 22.4999999999999964 + -2.9999999999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 42.2999999999999972 + -53.9999999999999858 + 22.4999999999999964 + -2.9999999999999996 + -28.1999999999999957 + 36.0000000000000000 + -15.0000000000000000 + 2.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 179.5499999999999545 + -161.9999999999999716 + 47.2499999999999929 + -4.4999999999999991 + -119.6999999999999886 + 107.9999999999999716 + -31.4999999999999964 + 2.9999999999999996 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -119.6999999999999886 + 107.9999999999999716 + -31.4999999999999964 + 2.9999999999999996 + 79.7999999999999972 + -72.0000000000000000 + 21.0000000000000000 + -2.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.8000000000000003 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + -5.4000000000000004 + 3.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 4.0500000000000007 + -2.7000000000000002 + 0.0000000000000000 + 0.0000000000000000 + -0.9000000000000000 + 0.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.6000000000000005 + -2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + -2.7000000000000002 + 1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.6000000000000001 + -0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.1499999999999986 + 45.0000000000000000 + -33.7500000000000000 + 7.5000000000000000 + 43.2000000000000028 + -108.0000000000000000 + 81.0000000000000000 + -18.0000000000000000 + -32.3999999999999986 + 81.0000000000000000 + -60.7500000000000000 + 13.5000000000000000 + 7.2000000000000002 + -18.0000000000000000 + 13.5000000000000000 + -3.0000000000000000 + 12.0999999999999996 + -30.0000000000000000 + 22.5000000000000000 + -5.0000000000000000 + -28.8000000000000007 + 72.0000000000000000 + -54.0000000000000000 + 12.0000000000000000 + 21.6000000000000014 + -54.0000000000000000 + 40.5000000000000000 + -9.0000000000000000 + -4.7999999999999998 + 12.0000000000000000 + -9.0000000000000000 + 2.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 80.8499999999999943 + -108.0000000000000000 + 45.0000000000000000 + -6.0000000000000000 + -244.8000000000000114 + 324.0000000000000000 + -135.0000000000000000 + 18.0000000000000000 + 183.5999999999999943 + -243.0000000000000000 + 101.2500000000000000 + -13.5000000000000000 + -40.7999999999999972 + 54.0000000000000000 + -22.5000000000000000 + 3.0000000000000000 + -53.9000000000000057 + 72.0000000000000000 + -30.0000000000000000 + 4.0000000000000000 + 163.1999999999999886 + -216.0000000000000000 + 90.0000000000000000 + -12.0000000000000000 + -122.4000000000000057 + 162.0000000000000000 + -67.5000000000000000 + 9.0000000000000000 + 27.1999999999999993 + -36.0000000000000000 + 15.0000000000000000 + -2.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 60.6000000000000369 + -54.0000000000000284 + 15.7500000000000107 + -1.5000000000000011 + -1.8000000000001068 + 0.0000000000000999 + -0.0000000000000306 + 0.0000000000000031 + 1.3500000000000831 + -0.0000000000000759 + 0.0000000000000226 + -0.0000000000000022 + -0.3000000000000198 + 0.0000000000000173 + -0.0000000000000049 + 0.0000000000000004 + -40.4000000000000270 + 36.0000000000000213 + -10.5000000000000036 + 1.0000000000000004 + 1.2000000000000515 + -0.0000000000000426 + 0.0000000000000111 + -0.0000000000000009 + -0.9000000000000317 + 0.0000000000000253 + -0.0000000000000062 + 0.0000000000000004 + 0.2000000000000040 + -0.0000000000000027 + 0.0000000000000004 + 0.0000000000000000 + -3.9810265070966766 + 2.7143362548386434 + -0.6107256573386948 + 0.0452389375806441 + 9.5544636170320238 + -6.5144070116127439 + 1.4657415776128673 + -0.1085734501935457 + -7.1658477127740188 + 4.8858052587095582 + -1.0993061832096505 + 0.0814300876451593 + 1.5924106028386709 + -1.0857345019354574 + 0.2442902629354779 + -0.0180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 12.5430795212900357 + -8.1430087645159333 + 1.8321769720160854 + -0.1357168127419323 + -30.4633908510960865 + 19.5432210348382434 + -4.3972247328386054 + 0.3257203505806374 + 22.8475431383220666 + -14.6574157761286834 + 3.2979185496289536 + -0.2442902629354781 + -5.0772318085160153 + 3.2572035058063742 + -0.7328707888064342 + 0.0542867250967729 + -8.3620530141933571 + 5.4286725096772885 + -1.2214513146773900 + 0.0904778751612881 + 20.3089272340640541 + -13.0288140232254914 + 2.9314831552257354 + -0.2171469003870915 + -15.2316954255480397 + 9.7716105174191163 + -2.1986123664193014 + 0.1628601752903186 + 3.3848212056773415 + -2.1714690038709143 + 0.4885805258709557 + -0.0361911500645152 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -25.2000000000000028 + 16.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 32.4000000000000057 + -21.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + -13.5000000000000000 + 9.0000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 1.8000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 16.8000000000000007 + -11.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + -21.6000000000000014 + 14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 9.0000000000000018 + -6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 82.3499999999999943 + -217.8000000000000114 + 163.3499999999999943 + -36.2999999999999972 + -110.6999999999999886 + 291.6000000000000227 + -218.6999999999999886 + 48.6000000000000085 + 46.1250000000000000 + -121.5000000000000000 + 91.1250000000000000 + -20.2500000000000036 + -6.1500000000000004 + 16.2000000000000028 + -12.1500000000000021 + 2.7000000000000002 + -54.8999999999999986 + 145.1999999999999886 + -108.9000000000000057 + 24.1999999999999993 + 73.7999999999999972 + -194.4000000000000341 + 145.8000000000000114 + -32.3999999999999986 + -30.7500000000000000 + 81.0000000000000000 + -60.7500000000000000 + 13.5000000000000000 + 4.0999999999999996 + -10.8000000000000007 + 8.0999999999999996 + -1.7999999999999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 9.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.6250000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -6.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 9.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1460.4000000000000909 + 1306.8000000000001819 + -381.1499999999999773 + 36.2999999999999972 + 1954.8000000000001819 + -1749.6000000000001364 + 510.3000000000000114 + -48.6000000000000085 + -814.5000000000001137 + 729.0000000000001137 + -212.6250000000000000 + 20.2500000000000036 + 108.5999999999999943 + -97.2000000000000028 + 28.3500000000000014 + -2.7000000000000002 + 973.5999999999999091 + -871.2000000000000455 + 254.0999999999999943 + -24.2000000000000028 + -1303.2000000000000455 + 1166.4000000000000909 + -340.2000000000000455 + 32.4000000000000057 + 543.0000000000000000 + -486.0000000000000568 + 141.7500000000000000 + -13.5000000000000000 + -72.4000000000000057 + 64.8000000000000114 + -18.8999999999999986 + 1.8000000000000000 + 21.4975431383220581 + -14.6574157761286745 + 3.2979185496289514 + -0.2442902629354779 + -28.6633908510960751 + 19.5432210348382327 + -4.3972247328386018 + 0.3257203505806372 + 11.9430795212900307 + -8.1430087645159297 + 1.8321769720160841 + -0.1357168127419322 + -1.5924106028386709 + 1.0857345019354574 + -0.2442902629354779 + 0.0180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -72.8926294149661658 + 43.9722473283860253 + -9.8937556488868559 + 0.7328707888064337 + 96.7901725532882438 + -58.6296631045147052 + 13.1916741985158090 + -0.9771610517419118 + -40.3292385638700992 + 24.4290262935477962 + -5.4965309160482541 + 0.4071504382257967 + 5.3772318085160133 + -3.2572035058063733 + 0.7328707888064341 + -0.0542867250967729 + 48.5950862766441105 + -29.3148315522573526 + 6.5958370992579045 + -0.4885805258709559 + -64.5267817021921530 + 39.0864420696764654 + -8.7944494656772036 + 0.6514407011612744 + 26.8861590425800614 + -16.2860175290318594 + 3.6643539440321682 + -0.2714336254838643 + -3.5848212056773412 + 2.1714690038709143 + -0.4885805258709557 + 0.0361911500645152 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9000000000000000 + 0.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6000000000000001 + -0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6749999999999999 + 0.8999999999999997 + -0.6749999999999997 + 0.1499999999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4499999999999999 + -0.5999999999999998 + 0.4499999999999998 + -0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3750000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.6999999999999975 + -5.3999999999999968 + 1.5749999999999993 + -0.1499999999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.7999999999999985 + 3.5999999999999988 + -1.0499999999999998 + 0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.8000000000000003 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.4000000000000004 + 3.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 3.6000000000000005 + -2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 4.0500000000000007 + -2.7000000000000002 + 0.0000000000000000 + 0.0000000000000000 + -2.7000000000000002 + 1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9000000000000000 + 0.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.6000000000000001 + -0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.1499999999999986 + 45.0000000000000000 + -33.7500000000000000 + 7.5000000000000000 + 12.0999999999999996 + -30.0000000000000000 + 22.5000000000000000 + -5.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + -108.0000000000000000 + 81.0000000000000000 + -18.0000000000000000 + -28.8000000000000007 + 72.0000000000000000 + -54.0000000000000000 + 12.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.3999999999999986 + 81.0000000000000000 + -60.7500000000000000 + 13.5000000000000000 + 21.6000000000000014 + -54.0000000000000000 + 40.5000000000000000 + -9.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000002 + -18.0000000000000000 + 13.5000000000000000 + -3.0000000000000000 + -4.7999999999999998 + 12.0000000000000000 + -9.0000000000000000 + 2.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 80.8499999999999943 + -108.0000000000000000 + 45.0000000000000000 + -6.0000000000000000 + -53.9000000000000057 + 72.0000000000000000 + -30.0000000000000000 + 4.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -244.8000000000000114 + 324.0000000000000000 + -135.0000000000000000 + 18.0000000000000000 + 163.1999999999999886 + -216.0000000000000000 + 90.0000000000000000 + -12.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 183.5999999999999943 + -243.0000000000000000 + 101.2500000000000000 + -13.5000000000000000 + -122.4000000000000057 + 162.0000000000000000 + -67.5000000000000000 + 9.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.7999999999999972 + 54.0000000000000000 + -22.5000000000000000 + 3.0000000000000000 + 27.1999999999999993 + -36.0000000000000000 + 15.0000000000000000 + -2.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 60.6000000000000369 + -54.0000000000000284 + 15.7500000000000107 + -1.5000000000000011 + -40.4000000000000270 + 36.0000000000000213 + -10.5000000000000036 + 1.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000001068 + 0.0000000000000999 + -0.0000000000000306 + 0.0000000000000031 + 1.2000000000000515 + -0.0000000000000426 + 0.0000000000000111 + -0.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3500000000000831 + -0.0000000000000759 + 0.0000000000000226 + -0.0000000000000022 + -0.9000000000000317 + 0.0000000000000253 + -0.0000000000000062 + 0.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000198 + 0.0000000000000173 + -0.0000000000000049 + 0.0000000000000004 + 0.2000000000000040 + -0.0000000000000027 + 0.0000000000000004 + 0.0000000000000000 + -3.9810265070966766 + 2.7143362548386434 + -0.6107256573386948 + 0.0452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 12.5430795212900303 + -8.1430087645159297 + 1.8321769720160841 + -0.1357168127419322 + -8.3620530141933536 + 5.4286725096772868 + -1.2214513146773895 + 0.0904778751612881 + 9.5544636170320238 + -6.5144070116127439 + 1.4657415776128673 + -0.1085734501935457 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -30.4633908510960723 + 19.5432210348382327 + -4.3972247328386018 + 0.3257203505806372 + 20.3089272340640505 + -13.0288140232254879 + 2.9314831552257345 + -0.2171469003870915 + -7.1658477127740188 + 4.8858052587095582 + -1.0993061832096505 + 0.0814300876451593 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 22.8475431383220560 + -14.6574157761286745 + 3.2979185496289514 + -0.2442902629354779 + -15.2316954255480361 + 9.7716105174191163 + -2.1986123664193009 + 0.1628601752903186 + 1.5924106028386709 + -1.0857345019354574 + 0.2442902629354779 + -0.0180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.0772318085160126 + 3.2572035058063720 + -0.7328707888064336 + 0.0542867250967729 + 3.3848212056773415 + -2.1714690038709148 + 0.4885805258709558 + -0.0361911500645152 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0226194687903220 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6678584063709662 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4452389375806441 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0542867250967729 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.9628601752903188 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.3085734501935460 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0407150438225796 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.4721451314677392 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9814300876451594 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.4000000000000004 + 1.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + -4.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + -5.4000000000000004 + 3.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 1.2000000000000002 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + -4.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + -21.6000000000000014 + 14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 16.2000000000000028 + -10.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + -3.6000000000000005 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + -5.4000000000000004 + 3.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 16.2000000000000028 + -10.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + -12.1500000000000021 + 8.1000000000000014 + 0.0000000000000000 + 0.0000000000000000 + 2.7000000000000002 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 1.2000000000000002 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.6000000000000005 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 2.7000000000000002 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + -0.6000000000000001 + 0.4000000000000000 + 49.2000000000000028 + -120.0000000000000000 + 90.0000000000000000 + -20.0000000000000000 + -132.6000000000000227 + 324.0000000000000000 + -243.0000000000000000 + 54.0000000000000000 + 99.4500000000000171 + -243.0000000000000000 + 182.2500000000000000 + -40.5000000000000000 + -22.1000000000000014 + 54.0000000000000000 + -40.5000000000000000 + 9.0000000000000000 + -132.5999999999999943 + 324.0000000000000000 + -243.0000000000000000 + 54.0000000000000000 + 352.8000000000000114 + -864.0000000000000000 + 648.0000000000000000 + -144.0000000000000000 + -264.6000000000000227 + 648.0000000000000000 + -486.0000000000000000 + 108.0000000000000000 + 58.7999999999999972 + -144.0000000000000000 + 108.0000000000000000 + -24.0000000000000000 + 99.4500000000000028 + -243.0000000000000000 + 182.2500000000000000 + -40.5000000000000000 + -264.6000000000000227 + 648.0000000000000000 + -486.0000000000000000 + 108.0000000000000000 + 198.4499999999999886 + -486.0000000000000000 + 364.5000000000000000 + -81.0000000000000000 + -44.1000000000000014 + 108.0000000000000000 + -81.0000000000000000 + 18.0000000000000000 + -22.1000000000000014 + 54.0000000000000000 + -40.5000000000000000 + 9.0000000000000000 + 58.7999999999999972 + -144.0000000000000000 + 108.0000000000000000 + -24.0000000000000000 + -44.1000000000000014 + 108.0000000000000000 + -81.0000000000000000 + 18.0000000000000000 + 9.8000000000000007 + -24.0000000000000000 + 18.0000000000000000 + -4.0000000000000000 + -102.7999999999999972 + 144.0000000000000000 + -60.0000000000000000 + 8.0000000000000000 + 311.3999999999999773 + -432.0000000000000000 + 180.0000000000000000 + -24.0000000000000000 + -233.5499999999999829 + 324.0000000000000000 + -135.0000000000000000 + 18.0000000000000000 + 51.8999999999999986 + -72.0000000000000000 + 30.0000000000000000 + -4.0000000000000000 + 311.3999999999999773 + -432.0000000000000000 + 180.0000000000000000 + -24.0000000000000000 + -943.2000000000000455 + 1296.0000000000000000 + -540.0000000000000000 + 72.0000000000000000 + 707.3999999999999773 + -972.0000000000000000 + 405.0000000000000000 + -54.0000000000000000 + -157.1999999999999886 + 216.0000000000000000 + -90.0000000000000000 + 12.0000000000000000 + -233.5499999999999829 + 324.0000000000000000 + -135.0000000000000000 + 18.0000000000000000 + 707.4000000000000909 + -972.0000000000000000 + 405.0000000000000000 + -54.0000000000000000 + -530.5499999999999545 + 729.0000000000000000 + -303.7500000000000000 + 40.5000000000000000 + 117.9000000000000057 + -162.0000000000000000 + 67.5000000000000000 + -9.0000000000000000 + 51.8999999999999986 + -72.0000000000000000 + 30.0000000000000000 + -4.0000000000000000 + -157.1999999999999886 + 216.0000000000000000 + -90.0000000000000000 + 12.0000000000000000 + 117.9000000000000057 + -162.0000000000000000 + 67.5000000000000000 + -9.0000000000000000 + -26.1999999999999993 + 36.0000000000000000 + -15.0000000000000000 + 2.0000000000000000 + -480.8000000000000114 + 432.0000000000000000 + -126.0000000000000000 + 12.0000000000000000 + 1202.4000000000000909 + -1080.0000000000000000 + 315.0000000000000568 + -30.0000000000000036 + -901.8000000000000682 + 810.0000000000001137 + -236.2500000000000000 + 22.5000000000000036 + 200.4000000000000341 + -180.0000000000000284 + 52.5000000000000071 + -5.0000000000000000 + 1202.4000000000003183 + -1080.0000000000002274 + 315.0000000000000568 + -30.0000000000000071 + -2887.2000000000007276 + 2592.0000000000004547 + -756.0000000000001137 + 72.0000000000000142 + 2165.4000000000005457 + -1944.0000000000002274 + 567.0000000000000000 + -54.0000000000000071 + -481.2000000000000455 + 432.0000000000000568 + -126.0000000000000142 + 12.0000000000000000 + -901.8000000000000682 + 810.0000000000002274 + -236.2500000000000284 + 22.5000000000000036 + 2165.4000000000005457 + -1944.0000000000004547 + 567.0000000000000000 + -54.0000000000000071 + -1624.0500000000001819 + 1458.0000000000002274 + -425.2500000000000568 + 40.5000000000000071 + 360.9000000000000341 + -324.0000000000000568 + 94.5000000000000000 + -9.0000000000000000 + 200.4000000000000341 + -180.0000000000000284 + 52.5000000000000071 + -5.0000000000000000 + -481.2000000000000455 + 432.0000000000000568 + -126.0000000000000142 + 12.0000000000000000 + 360.9000000000000341 + -324.0000000000000568 + 94.5000000000000000 + -9.0000000000000000 + -80.2000000000000028 + 72.0000000000000000 + -21.0000000000000000 + 2.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.0500000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.0500000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.0500000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.0500000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.0500000000000007 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 33.6000000000000014 + -22.3999999999999986 + 0.0000000000000000 + 0.0000000000000000 + -43.2000000000000028 + 28.8000000000000043 + 0.0000000000000000 + 0.0000000000000000 + 18.0000000000000000 + -12.0000000000000018 + 0.0000000000000000 + 0.0000000000000000 + -2.4000000000000004 + 1.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + -100.8000000000000114 + 67.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 129.6000000000000227 + -86.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + -54.0000000000000000 + 36.0000000000000071 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + -4.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 75.6000000000000085 + -50.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + -97.2000000000000171 + 64.8000000000000114 + 0.0000000000000000 + 0.0000000000000000 + 40.5000000000000000 + -27.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + -5.4000000000000004 + 3.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + -16.8000000000000007 + 11.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 21.6000000000000014 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + -9.0000000000000018 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 1.2000000000000002 + -0.8000000000000000 + -109.8000000000000114 + 290.3999999999999773 + -217.7999999999999829 + 48.3999999999999986 + 147.5999999999999943 + -388.8000000000000114 + 291.6000000000000227 + -64.7999999999999972 + -61.5000000000000000 + 162.0000000000000000 + -121.5000000000000000 + 27.0000000000000000 + 8.1999999999999993 + -21.6000000000000014 + 16.1999999999999993 + -3.6000000000000001 + 329.4000000000000341 + -871.2000000000000455 + 653.3999999999999773 + -145.1999999999999886 + -442.8000000000000114 + 1166.4000000000000909 + -874.8000000000000682 + 194.4000000000000341 + 184.5000000000000000 + -486.0000000000000568 + 364.5000000000000000 + -81.0000000000000000 + -24.6000000000000014 + 64.8000000000000114 + -48.6000000000000085 + 10.8000000000000007 + -247.0499999999999829 + 653.4000000000000909 + -490.0499999999999545 + 108.9000000000000057 + 332.0999999999999659 + -874.8000000000000682 + 656.1000000000000227 + -145.8000000000000114 + -138.3750000000000000 + 364.5000000000000568 + -273.3750000000000000 + 60.7500000000000000 + 18.4499999999999993 + -48.6000000000000085 + 36.4500000000000028 + -8.0999999999999996 + 54.8999999999999986 + -145.1999999999999886 + 108.9000000000000057 + -24.1999999999999993 + -73.7999999999999972 + 194.4000000000000341 + -145.8000000000000114 + 32.3999999999999986 + 30.7500000000000000 + -81.0000000000000000 + 60.7500000000000000 + -13.5000000000000000 + -4.0999999999999996 + 10.8000000000000007 + -8.0999999999999996 + 1.7999999999999998 + -13.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 39.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -54.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 22.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -29.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 40.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -16.8750000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -9.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1947.2000000000000455 + -1742.3999999999998636 + 508.1999999999999318 + -48.3999999999999986 + -2606.4000000000005457 + 2332.8000000000001819 + -680.3999999999999773 + 64.8000000000000114 + 1086.0000000000000000 + -972.0000000000001137 + 283.5000000000000000 + -27.0000000000000036 + -144.8000000000000114 + 129.5999999999999943 + -37.7999999999999972 + 3.6000000000000005 + -5841.6000000000003638 + 5227.2000000000007276 + -1524.5999999999999091 + 145.1999999999999886 + 7819.2000000000007276 + -6998.4000000000005457 + 2041.2000000000002728 + -194.4000000000000341 + -3258.0000000000004547 + 2916.0000000000004547 + -850.5000000000000000 + 81.0000000000000142 + 434.4000000000000341 + -388.8000000000000114 + 113.4000000000000057 + -10.8000000000000007 + 4381.2000000000007276 + -3920.4000000000005457 + 1143.4500000000000455 + -108.9000000000000057 + -5864.4000000000014552 + 5248.8000000000001819 + -1530.9000000000000909 + 145.8000000000000114 + 2443.5000000000004547 + -2187.0000000000004547 + 637.8750000000000000 + -60.7500000000000142 + -325.8000000000000114 + 291.6000000000000227 + -85.0500000000000114 + 8.1000000000000014 + -973.5999999999999091 + 871.2000000000000455 + -254.0999999999999943 + 24.2000000000000028 + 1303.2000000000000455 + -1166.4000000000000909 + 340.2000000000000455 + -32.4000000000000057 + -543.0000000000000000 + 486.0000000000000568 + -141.7500000000000000 + 13.5000000000000000 + 72.4000000000000057 + -64.8000000000000114 + 18.8999999999999986 + -1.8000000000000000 + 11.1999999999999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.1999999999999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.1999999999999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.1999999999999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.1999999999999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.2000000000000002 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.6000000000000005 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.7000000000000002 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6000000000000001 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.8999999999999998 + -1.1999999999999997 + 0.8999999999999996 + -0.1999999999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.6999999999999993 + 3.5999999999999988 + -2.6999999999999988 + 0.5999999999999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.0249999999999995 + -2.6999999999999988 + 2.0249999999999995 + -0.4499999999999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4499999999999999 + 0.5999999999999998 + -0.4499999999999998 + 0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.1250000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5999999999999961 + 7.1999999999999966 + -2.0999999999999992 + 0.1999999999999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 22.7999999999999901 + -21.5999999999999908 + 6.2999999999999972 + -0.5999999999999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.0999999999999943 + 16.1999999999999922 + -4.7249999999999979 + 0.4499999999999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.7999999999999985 + -3.5999999999999988 + 1.0499999999999998 + -0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -25.2000000000000028 + 16.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + 16.8000000000000007 + -11.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 32.4000000000000057 + -21.6000000000000014 + 0.0000000000000000 + 0.0000000000000000 + -21.6000000000000014 + 14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.5000000000000000 + 9.0000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 9.0000000000000018 + -6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.8000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 82.3499999999999943 + -217.8000000000000114 + 163.3499999999999943 + -36.2999999999999972 + -54.8999999999999986 + 145.1999999999999886 + -108.9000000000000057 + 24.1999999999999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -110.6999999999999886 + 291.6000000000000227 + -218.6999999999999886 + 48.6000000000000085 + 73.7999999999999972 + -194.4000000000000341 + 145.8000000000000114 + -32.3999999999999986 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 46.1250000000000000 + -121.5000000000000000 + 91.1250000000000000 + -20.2500000000000036 + -30.7500000000000000 + 81.0000000000000000 + -60.7500000000000000 + 13.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -6.1500000000000004 + 16.2000000000000028 + -12.1500000000000021 + 2.7000000000000002 + 4.0999999999999996 + -10.8000000000000007 + 8.0999999999999996 + -1.7999999999999998 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 9.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -6.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -13.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 9.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.6250000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1460.4000000000000909 + 1306.8000000000001819 + -381.1499999999999773 + 36.2999999999999972 + 973.5999999999999091 + -871.2000000000000455 + 254.0999999999999943 + -24.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1954.8000000000001819 + -1749.6000000000001364 + 510.3000000000000114 + -48.6000000000000085 + -1303.2000000000000455 + 1166.4000000000000909 + -340.2000000000000455 + 32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -814.5000000000001137 + 729.0000000000001137 + -212.6250000000000000 + 20.2500000000000036 + 543.0000000000000000 + -486.0000000000000568 + 141.7500000000000000 + -13.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 108.5999999999999943 + -97.2000000000000028 + 28.3500000000000014 + -2.7000000000000002 + -72.4000000000000057 + 64.8000000000000114 + -18.8999999999999986 + 1.8000000000000000 + 21.4975431383220581 + -14.6574157761286745 + 3.2979185496289514 + -0.2442902629354779 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -72.8926294149661658 + 43.9722473283860253 + -9.8937556488868559 + 0.7328707888064337 + 48.5950862766441105 + -29.3148315522573526 + 6.5958370992579045 + -0.4885805258709559 + -28.6633908510960751 + 19.5432210348382327 + -4.3972247328386018 + 0.3257203505806372 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 96.7901725532882438 + -58.6296631045147052 + 13.1916741985158090 + -0.9771610517419118 + -64.5267817021921530 + 39.0864420696764654 + -8.7944494656772036 + 0.6514407011612744 + 11.9430795212900307 + -8.1430087645159297 + 1.8321769720160841 + -0.1357168127419322 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -40.3292385638700992 + 24.4290262935477962 + -5.4965309160482541 + 0.4071504382257967 + 26.8861590425800614 + -16.2860175290318594 + 3.6643539440321682 + -0.2714336254838643 + -1.5924106028386709 + 1.0857345019354574 + -0.2442902629354779 + 0.0180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.3772318085160133 + -3.2572035058063733 + 0.7328707888064341 + -0.0542867250967729 + -3.5848212056773412 + 2.1714690038709143 + -0.4885805258709557 + 0.0361911500645152 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.1221451314677389 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -8.7664353944032172 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.8442902629354787 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.1628601752903186 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2885805258709571 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5257203505806380 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0678584063709661 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.7035752191128983 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.1357168127419324 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.0090477875161288 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.6271433625483865 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.4180955750322576 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 33.6000000000000014 + -22.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + -100.8000000000000114 + 67.2000000000000171 + 0.0000000000000000 + 0.0000000000000000 + 75.6000000000000085 + -50.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + -16.8000000000000007 + 11.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + -43.2000000000000028 + 28.8000000000000043 + 0.0000000000000000 + 0.0000000000000000 + 129.6000000000000227 + -86.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + -97.2000000000000171 + 64.8000000000000114 + 0.0000000000000000 + 0.0000000000000000 + 21.6000000000000014 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 18.0000000000000000 + -12.0000000000000018 + 0.0000000000000000 + 0.0000000000000000 + -54.0000000000000071 + 36.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 40.5000000000000000 + -27.0000000000000036 + 0.0000000000000000 + 0.0000000000000000 + -9.0000000000000018 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + -2.4000000000000004 + 1.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + -4.8000000000000007 + 0.0000000000000000 + 0.0000000000000000 + -5.4000000000000004 + 3.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 1.2000000000000002 + -0.8000000000000000 + -109.7999999999999829 + 290.3999999999999773 + -217.7999999999999829 + 48.3999999999999986 + 329.4000000000000341 + -871.2000000000000455 + 653.4000000000000909 + -145.1999999999999886 + -247.0499999999999829 + 653.4000000000000909 + -490.0499999999999545 + 108.9000000000000057 + 54.8999999999999986 + -145.1999999999999886 + 108.9000000000000057 + -24.1999999999999993 + 147.5999999999999943 + -388.8000000000000114 + 291.6000000000000227 + -64.8000000000000114 + -442.8000000000000114 + 1166.4000000000000909 + -874.8000000000000682 + 194.4000000000000341 + 332.0999999999999659 + -874.8000000000000682 + 656.1000000000000227 + -145.8000000000000114 + -73.7999999999999972 + 194.4000000000000341 + -145.8000000000000114 + 32.3999999999999986 + -61.4999999999999929 + 162.0000000000000284 + -121.5000000000000000 + 27.0000000000000000 + 184.5000000000000000 + -486.0000000000000568 + 364.5000000000000000 + -81.0000000000000000 + -138.3750000000000000 + 364.5000000000000568 + -273.3750000000000000 + 60.7500000000000000 + 30.7500000000000000 + -81.0000000000000000 + 60.7500000000000000 + -13.5000000000000000 + 8.1999999999999993 + -21.6000000000000014 + 16.1999999999999993 + -3.6000000000000001 + -24.6000000000000014 + 64.8000000000000114 + -48.6000000000000085 + 10.8000000000000007 + 18.4499999999999993 + -48.6000000000000085 + 36.4500000000000028 + -8.0999999999999996 + -4.0999999999999996 + 10.8000000000000007 + -8.0999999999999996 + 1.7999999999999998 + -13.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 39.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -29.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -54.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 40.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -9.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 22.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -16.8750000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.7500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1947.2000000000000455 + -1742.3999999999998636 + 508.2000000000000455 + -48.3999999999999986 + -5841.6000000000003638 + 5227.2000000000007276 + -1524.5999999999999091 + 145.1999999999999886 + 4381.2000000000007276 + -3920.4000000000000909 + 1143.4500000000000455 + -108.9000000000000199 + -973.5999999999999091 + 871.2000000000000455 + -254.0999999999999943 + 24.2000000000000028 + -2606.4000000000005457 + 2332.8000000000001819 + -680.3999999999999773 + 64.8000000000000114 + 7819.2000000000007276 + -6998.4000000000005457 + 2041.2000000000000455 + -194.4000000000000341 + -5864.4000000000014552 + 5248.8000000000001819 + -1530.9000000000000909 + 145.8000000000000114 + 1303.2000000000000455 + -1166.4000000000000909 + 340.2000000000000455 + -32.4000000000000057 + 1086.0000000000000000 + -972.0000000000001137 + 283.5000000000000000 + -27.0000000000000036 + -3258.0000000000004547 + 2916.0000000000004547 + -850.5000000000000000 + 81.0000000000000142 + 2443.5000000000004547 + -2187.0000000000004547 + 637.8750000000000000 + -60.7500000000000142 + -543.0000000000000000 + 486.0000000000000568 + -141.7500000000000000 + 13.5000000000000000 + -144.8000000000000114 + 129.5999999999999943 + -37.7999999999999972 + 3.6000000000000005 + 434.4000000000000341 + -388.8000000000000114 + 113.4000000000000057 + -10.8000000000000007 + -325.8000000000000114 + 291.6000000000000227 + -85.0500000000000114 + 8.1000000000000014 + 72.4000000000000057 + -64.8000000000000114 + 18.8999999999999986 + -1.8000000000000000 + 11.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000085 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000085 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000085 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000085 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 11.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -33.6000000000000085 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 25.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -5.6000000000000005 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -14.4000000000000021 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 43.2000000000000028 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -32.4000000000000057 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 7.2000000000000011 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 6.0000000000000009 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -18.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.5000000000000018 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.0000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.9000000000000000 + 0.6000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.6000000000000001 + -0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.6749999999999999 + 0.8999999999999997 + -0.6749999999999997 + 0.1499999999999999 + 0.4499999999999999 + -0.5999999999999998 + 0.4499999999999998 + -0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3750000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.6999999999999975 + -5.3999999999999968 + 1.5749999999999993 + -0.1499999999999999 + -3.7999999999999985 + 3.5999999999999988 + -1.0499999999999998 + 0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.3000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.2000000000000002 + -0.8000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -3.6000000000000005 + 2.4000000000000004 + 0.0000000000000000 + 0.0000000000000000 + 2.7000000000000002 + -1.8000000000000003 + 0.0000000000000000 + 0.0000000000000000 + -0.6000000000000001 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.8999999999999998 + -1.1999999999999997 + 0.8999999999999996 + -0.1999999999999999 + -2.6999999999999993 + 3.5999999999999988 + -2.6999999999999988 + 0.5999999999999998 + 2.0249999999999995 + -2.6999999999999988 + 2.0249999999999995 + -0.4499999999999998 + -0.4499999999999999 + 0.5999999999999998 + -0.4499999999999998 + 0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.5000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 1.1250000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2500000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -7.5999999999999961 + 7.1999999999999966 + -2.0999999999999992 + 0.1999999999999999 + 22.7999999999999901 + -21.5999999999999908 + 6.2999999999999972 + -0.5999999999999998 + -17.0999999999999943 + 16.1999999999999922 + -4.7249999999999979 + 0.4499999999999998 + 3.7999999999999985 + -3.5999999999999988 + 1.0499999999999998 + -0.1000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.4000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -1.2000000000000002 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.9000000000000001 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -0.2000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + +# piHH + +6 +0.0 +4.0 +0.0 +4.0 +0.0 +9.0 + + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 3.3727308659999999 + -2.2484872439999997 + 0.0000000000000000 + 0.0000000000000000 + -2.2484872439999997 + 1.4989914959999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.2484872439999997 + 1.4989914959999999 + 0.0000000000000000 + 0.0000000000000000 + 1.4989914959999999 + -0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4969744879999993 + 13.4909234639999980 + -10.1181925979999985 + 2.2484872439999997 + 2.9979829919999998 + -8.9939489759999987 + 6.7454617319999990 + -1.4989914959999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.9979829919999998 + -8.9939489759999987 + 6.7454617319999990 + -1.4989914959999999 + -1.9986553279999999 + 5.9959659839999997 + -4.4969744879999993 + 0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4969744879999993 + 2.9979829919999998 + 0.0000000000000000 + 0.0000000000000000 + 13.4909234639999980 + -8.9939489759999987 + 0.0000000000000000 + 0.0000000000000000 + -10.1181925979999985 + 6.7454617319999990 + 0.0000000000000000 + 0.0000000000000000 + 2.2484872439999997 + -1.4989914959999999 + 0.0000000000000000 + 0.0000000000000000 + 2.9979829919999998 + -1.9986553279999999 + 0.0000000000000000 + 0.0000000000000000 + -8.9939489759999987 + 5.9959659839999997 + 0.0000000000000000 + 0.0000000000000000 + 6.7454617319999990 + -4.4969744879999993 + 0.0000000000000000 + 0.0000000000000000 + -1.4989914959999999 + 0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.9959659839999997 + -17.9878979519999973 + 13.4909234639999980 + -2.9979829919999998 + -17.9878979519999973 + 53.9636938559999919 + -40.4727703919999939 + 8.9939489759999987 + 13.4909234639999980 + -40.4727703919999939 + 30.3545777939999937 + -6.7454617319999990 + -2.9979829919999998 + 8.9939489759999987 + -6.7454617319999990 + 1.4989914959999999 + -3.9973106559999998 + 11.9919319679999994 + -8.9939489759999987 + 1.9986553279999999 + 11.9919319679999994 + -35.9757959039999946 + 26.9818469279999960 + -5.9959659839999997 + -8.9939489759999987 + 26.9818469279999960 + -20.2363851959999970 + 4.4969744879999993 + 1.9986553279999999 + -5.9959659839999997 + 4.4969744879999993 + -0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -4.4969744879999993 + 2.9979829919999998 + 0.0000000000000000 + 0.0000000000000000 + 2.9979829919999998 + -1.9986553279999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.4909234639999980 + -8.9939489759999987 + 0.0000000000000000 + 0.0000000000000000 + -8.9939489759999987 + 5.9959659839999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -10.1181925979999985 + 6.7454617319999990 + 0.0000000000000000 + 0.0000000000000000 + 6.7454617319999990 + -4.4969744879999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 2.2484872439999997 + -1.4989914959999999 + 0.0000000000000000 + 0.0000000000000000 + -1.4989914959999999 + 0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.9959659839999997 + -17.9878979519999973 + 13.4909234639999980 + -2.9979829919999998 + -3.9973106559999998 + 11.9919319679999994 + -8.9939489759999987 + 1.9986553279999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -17.9878979519999973 + 53.9636938559999919 + -40.4727703919999939 + 8.9939489759999987 + 11.9919319679999994 + -35.9757959039999946 + 26.9818469279999960 + -5.9959659839999997 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 13.4909234639999980 + -40.4727703919999939 + 30.3545777939999937 + -6.7454617319999990 + -8.9939489759999987 + 26.9818469279999960 + -20.2363851959999970 + 4.4969744879999993 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + -2.9979829919999998 + 8.9939489759999987 + -6.7454617319999990 + 1.4989914959999999 + 1.9986553279999999 + -5.9959659839999997 + 4.4969744879999993 + -0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 5.9959659839999997 + -3.9973106559999998 + 0.0000000000000000 + 0.0000000000000000 + -17.9878979519999973 + 11.9919319679999994 + 0.0000000000000000 + 0.0000000000000000 + 13.4909234639999980 + -8.9939489759999987 + 0.0000000000000000 + 0.0000000000000000 + -2.9979829919999998 + 1.9986553279999999 + 0.0000000000000000 + 0.0000000000000000 + -17.9878979519999973 + 11.9919319679999994 + 0.0000000000000000 + 0.0000000000000000 + 53.9636938559999919 + -35.9757959039999946 + 0.0000000000000000 + 0.0000000000000000 + -40.4727703919999939 + 26.9818469279999960 + 0.0000000000000000 + 0.0000000000000000 + 8.9939489759999987 + -5.9959659839999997 + 0.0000000000000000 + 0.0000000000000000 + 13.4909234639999980 + -8.9939489759999987 + 0.0000000000000000 + 0.0000000000000000 + -40.4727703919999939 + 26.9818469279999960 + 0.0000000000000000 + 0.0000000000000000 + 30.3545777939999937 + -20.2363851959999970 + 0.0000000000000000 + 0.0000000000000000 + -6.7454617319999990 + 4.4969744879999993 + 0.0000000000000000 + 0.0000000000000000 + -2.9979829919999998 + 1.9986553279999999 + 0.0000000000000000 + 0.0000000000000000 + 8.9939489759999987 + -5.9959659839999997 + 0.0000000000000000 + 0.0000000000000000 + -6.7454617319999990 + 4.4969744879999993 + 0.0000000000000000 + 0.0000000000000000 + 1.4989914959999999 + -0.9993276639999999 + -7.9946213120000005 + 23.9838639359999988 + -17.9878979519999973 + 3.9973106559999998 + 23.9838639359999988 + -71.9515918079999892 + 53.9636938559999919 + -11.9919319679999994 + -17.9878979519999973 + 53.9636938559999919 + -40.4727703919999939 + 8.9939489759999987 + 3.9973106559999998 + -11.9919319679999994 + 8.9939489759999987 + -1.9986553279999999 + 23.9838639359999988 + -71.9515918079999892 + 53.9636938559999919 + -11.9919319679999994 + -71.9515918079999892 + 215.8547754239999108 + -161.8910815680000042 + 35.9757959039999946 + 53.9636938559999919 + -161.8910815679999473 + 121.4183111759999605 + -26.9818469279999960 + -11.9919319679999994 + 35.9757959039999946 + -26.9818469279999960 + 5.9959659839999997 + -17.9878979519999973 + 53.9636938559999919 + -40.4727703919999939 + 8.9939489759999987 + 53.9636938559999919 + -161.8910815679999473 + 121.4183111759999889 + -26.9818469279999960 + -40.4727703919999939 + 121.4183111759999747 + -91.0637333819999810 + 20.2363851959999970 + 8.9939489759999987 + -26.9818469279999960 + 20.2363851959999970 + -4.4969744879999993 + 3.9973106559999998 + -11.9919319679999994 + 8.9939489759999987 + -1.9986553279999999 + -11.9919319679999994 + 35.9757959039999946 + -26.9818469279999960 + 5.9959659839999997 + 8.9939489759999987 + -26.9818469279999960 + 20.2363851959999970 + -4.4969744879999993 + -1.9986553279999999 + 5.9959659839999997 + -4.4969744879999993 + 0.9993276639999999 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + 0.0000000000000000 + +# Tij + +6 +0.0 +4.0 +0.0 +4.0 +0.0 +9.0 + + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.6355000000 + 1.7570000000 + 0.0000000000 + 0.0000000000 + 6.3252000000 + -4.2168000000 + 0.0000000000 + 0.0000000000 + -4.7439000000 + 3.1626000000 + 0.0000000000 + 0.0000000000 + 1.0542000000 + -0.7028000000 + 0.0000000000 + 0.0000000000 + 6.3252000000 + -4.2168000000 + 0.0000000000 + 0.0000000000 + -15.1804800000 + 10.1203200000 + 0.0000000000 + 0.0000000000 + 11.3853600000 + -7.5902400000 + 0.0000000000 + 0.0000000000 + -2.5300800000 + 1.6867200000 + 0.0000000000 + 0.0000000000 + -4.7439000000 + 3.1626000000 + 0.0000000000 + 0.0000000000 + 11.3853600000 + -7.5902400000 + 0.0000000000 + 0.0000000000 + -8.5390200000 + 5.6926800000 + 0.0000000000 + 0.0000000000 + 1.8975600000 + -1.2650400000 + 0.0000000000 + 0.0000000000 + 1.0542000000 + -0.7028000000 + 0.0000000000 + 0.0000000000 + -2.5300800000 + 1.6867200000 + 0.0000000000 + 0.0000000000 + 1.8975600000 + -1.2650400000 + 0.0000000000 + 0.0000000000 + -0.4216800000 + 0.2811200000 + 3.0080000000 + -9.3276000000 + 6.9957000000 + -1.5546000000 + -7.2192000000 + 22.3862400000 + -16.7896800000 + 3.7310400000 + 5.4144000000 + -16.7896800000 + 12.5922600000 + -2.7982800000 + -1.2032000000 + 3.7310400000 + -2.7982800000 + 0.6218400000 + -7.2192000000 + 22.3862400000 + -16.7896800000 + 3.7310400000 + 17.3260800000 + -53.7269760000 + 40.2952320000 + -8.9544960000 + -12.9945600000 + 40.2952320000 + -30.2214240000 + 6.7158720000 + 2.8876800000 + -8.9544960000 + 6.7158720000 + -1.4924160000 + 5.4144000000 + -16.7896800000 + 12.5922600000 + -2.7982800000 + -12.9945600000 + 40.2952320000 + -30.2214240000 + 6.7158720000 + 9.7459200000 + -30.2214240000 + 22.6660680000 + -5.0369040000 + -2.1657600000 + 6.7158720000 + -5.0369040000 + 1.1193120000 + -1.2032000000 + 3.7310400000 + -2.7982800000 + 0.6218400000 + 2.8876800000 + -8.9544960000 + 6.7158720000 + -1.4924160000 + -2.1657600000 + 6.7158720000 + -5.0369040000 + 1.1193120000 + 0.4812800000 + -1.4924160000 + 1.1193120000 + -0.2487360000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1012000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2428800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.5829120000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1821600000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.4371840000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.3278880000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 14.2317000000 + -9.4878000000 + 0.0000000000 + 0.0000000000 + -18.9756000000 + 12.6504000000 + 0.0000000000 + 0.0000000000 + 7.9065000000 + -5.2710000000 + 0.0000000000 + 0.0000000000 + -1.0542000000 + 0.7028000000 + 0.0000000000 + 0.0000000000 + -34.1560800000 + 22.7707200000 + 0.0000000000 + 0.0000000000 + 45.5414400000 + -30.3609600000 + 0.0000000000 + 0.0000000000 + -18.9756000000 + 12.6504000000 + 0.0000000000 + 0.0000000000 + 2.5300800000 + -1.6867200000 + 0.0000000000 + 0.0000000000 + 25.6170600000 + -17.0780400000 + 0.0000000000 + 0.0000000000 + -34.1560800000 + 22.7707200000 + 0.0000000000 + 0.0000000000 + 14.2317000000 + -9.4878000000 + 0.0000000000 + 0.0000000000 + -1.8975600000 + 1.2650400000 + 0.0000000000 + 0.0000000000 + -5.6926800000 + 3.7951200000 + 0.0000000000 + 0.0000000000 + 7.5902400000 + -5.0601600000 + 0.0000000000 + 0.0000000000 + -3.1626000000 + 2.1084000000 + 0.0000000000 + 0.0000000000 + 0.4216800000 + -0.2811200000 + -16.2432000000 + 50.3690400000 + -37.7767800000 + 8.3948400000 + 21.6576000000 + -67.1587200000 + 50.3690400000 + -11.1931200000 + -9.0240000000 + 27.9828000000 + -20.9871000000 + 4.6638000000 + 1.2032000000 + -3.7310400000 + 2.7982800000 + -0.6218400000 + 38.9836800000 + -120.8856960000 + 90.6642720000 + -20.1476160000 + -51.9782400000 + 161.1809280000 + -120.8856960000 + 26.8634880000 + 21.6576000000 + -67.1587200000 + 50.3690400000 + -11.1931200000 + -2.8876800000 + 8.9544960000 + -6.7158720000 + 1.4924160000 + -29.2377600000 + 90.6642720000 + -67.9982040000 + 15.1107120000 + 38.9836800000 + -120.8856960000 + 90.6642720000 + -20.1476160000 + -16.2432000000 + 50.3690400000 + -37.7767800000 + 8.3948400000 + 2.1657600000 + -6.7158720000 + 5.0369040000 + -1.1193120000 + 6.4972800000 + -20.1476160000 + 15.1107120000 + -3.3579360000 + -8.6630400000 + 26.8634880000 + -20.1476160000 + 4.4772480000 + 3.6096000000 + -11.1931200000 + 8.3948400000 + -1.8655200000 + -0.4812800000 + 1.4924160000 + -1.1193120000 + 0.2487360000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 14.2317000000 + -9.4878000000 + 0.0000000000 + 0.0000000000 + -34.1560800000 + 22.7707200000 + 0.0000000000 + 0.0000000000 + 25.6170600000 + -17.0780400000 + 0.0000000000 + 0.0000000000 + -5.6926800000 + 3.7951200000 + 0.0000000000 + 0.0000000000 + -18.9756000000 + 12.6504000000 + 0.0000000000 + 0.0000000000 + 45.5414400000 + -30.3609600000 + 0.0000000000 + 0.0000000000 + -34.1560800000 + 22.7707200000 + 0.0000000000 + 0.0000000000 + 7.5902400000 + -5.0601600000 + 0.0000000000 + 0.0000000000 + 7.9065000000 + -5.2710000000 + 0.0000000000 + 0.0000000000 + -18.9756000000 + 12.6504000000 + 0.0000000000 + 0.0000000000 + 14.2317000000 + -9.4878000000 + 0.0000000000 + 0.0000000000 + -3.1626000000 + 2.1084000000 + 0.0000000000 + 0.0000000000 + -1.0542000000 + 0.7028000000 + 0.0000000000 + 0.0000000000 + 2.5300800000 + -1.6867200000 + 0.0000000000 + 0.0000000000 + -1.8975600000 + 1.2650400000 + 0.0000000000 + 0.0000000000 + 0.4216800000 + -0.2811200000 + -16.2432000000 + 50.3690400000 + -37.7767800000 + 8.3948400000 + 38.9836800000 + -120.8856960000 + 90.6642720000 + -20.1476160000 + -29.2377600000 + 90.6642720000 + -67.9982040000 + 15.1107120000 + 6.4972800000 + -20.1476160000 + 15.1107120000 + -3.3579360000 + 21.6576000000 + -67.1587200000 + 50.3690400000 + -11.1931200000 + -51.9782400000 + 161.1809280000 + -120.8856960000 + 26.8634880000 + 38.9836800000 + -120.8856960000 + 90.6642720000 + -20.1476160000 + -8.6630400000 + 26.8634880000 + -20.1476160000 + 4.4772480000 + -9.0240000000 + 27.9828000000 + -20.9871000000 + 4.6638000000 + 21.6576000000 + -67.1587200000 + 50.3690400000 + -11.1931200000 + -16.2432000000 + 50.3690400000 + -37.7767800000 + 8.3948400000 + 3.6096000000 + -11.1931200000 + 8.3948400000 + -1.8655200000 + 1.2032000000 + -3.7310400000 + 2.7982800000 + -0.6218400000 + -2.8876800000 + 8.9544960000 + -6.7158720000 + 1.4924160000 + 2.1657600000 + -6.7158720000 + 5.0369040000 + -1.1193120000 + -0.4812800000 + 1.4924160000 + -1.1193120000 + 0.2487360000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.9836640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 1.7487360000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.3115520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.3036000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.7286400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.5464800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0404800000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0971520000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0728640000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -76.8511800000 + 51.2341200000 + 0.0000000000 + 0.0000000000 + 102.4682400000 + -68.3121600000 + 0.0000000000 + 0.0000000000 + -42.6951000000 + 28.4634000000 + 0.0000000000 + 0.0000000000 + 5.6926800000 + -3.7951200000 + 0.0000000000 + 0.0000000000 + 102.4682400000 + -68.3121600000 + 0.0000000000 + 0.0000000000 + -136.6243200000 + 91.0828800000 + 0.0000000000 + 0.0000000000 + 56.9268000000 + -37.9512000000 + 0.0000000000 + 0.0000000000 + -7.5902400000 + 5.0601600000 + 0.0000000000 + 0.0000000000 + -42.6951000000 + 28.4634000000 + 0.0000000000 + 0.0000000000 + 56.9268000000 + -37.9512000000 + 0.0000000000 + 0.0000000000 + -23.7195000000 + 15.8130000000 + 0.0000000000 + 0.0000000000 + 3.1626000000 + -2.1084000000 + 0.0000000000 + 0.0000000000 + 5.6926800000 + -3.7951200000 + 0.0000000000 + 0.0000000000 + -7.5902400000 + 5.0601600000 + 0.0000000000 + 0.0000000000 + 3.1626000000 + -2.1084000000 + 0.0000000000 + 0.0000000000 + -0.4216800000 + 0.2811200000 + 87.7132800000 + -271.9928159999 + 203.9946120000 + -45.3321360000 + -116.9510400000 + 362.6570879999 + -271.9928159999 + 60.4428480000 + 48.7296000000 + -151.1071200000 + 113.3303400000 + -25.1845200000 + -6.4972800000 + 20.1476160000 + -15.1107120000 + 3.3579360000 + -116.9510400000 + 362.6570880000 + -271.9928160000 + 60.4428480000 + 155.9347200000 + -483.5427840000 + 362.6570880000 + -80.5904640000 + -64.9728000000 + 201.4761600000 + -151.1071200000 + 33.5793600000 + 8.6630400000 + -26.8634880000 + 20.1476160000 + -4.4772480000 + 48.7296000000 + -151.1071200000 + 113.3303400000 + -25.1845200000 + -64.9728000000 + 201.4761600000 + -151.1071200000 + 33.5793600000 + 27.0720000000 + -83.9484000000 + 62.9613000000 + -13.9914000000 + -3.6096000000 + 11.1931200000 + -8.3948400000 + 1.8655200000 + -6.4972800000 + 20.1476160000 + -15.1107120000 + 3.3579360000 + 8.6630400000 + -26.8634880000 + 20.1476160000 + -4.4772480000 + -3.6096000000 + 11.1931200000 + -8.3948400000 + 1.8655200000 + 0.4812800000 + -1.4924160000 + 1.1193120000 + -0.2487360000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -2.9509920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 3.9346560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -5.2462080000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -1.6394400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 2.1859200000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.9108000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.2185920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.2914560000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.1214400000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + -0.0161920000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 + 0.0000000000 diff --git a/src/MANYBODY/pair_rebo.cpp b/src/MANYBODY/pair_rebo.cpp index 1f31c0b0cd..10d1d83579 100644 --- a/src/MANYBODY/pair_rebo.cpp +++ b/src/MANYBODY/pair_rebo.cpp @@ -30,9 +30,263 @@ void PairREBO::settings(int narg, char **/*arg*/) cutlj = 0.0; ljflag = torflag = 0; + PCCf_2_0 = -0.0276030; +} + +/* ---------------------------------------------------------------------- + initialize spline knot values +------------------------------------------------------------------------- */ + +void PairREBO::spline_init() +{ + int i,j,k; + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + PCCf[i][j] = 0.0; + PCCdfdx[i][j] = 0.0; + PCCdfdy[i][j] = 0.0; + PCHf[i][j] = 0.0; + PCHdfdx[i][j] = 0.0; + PCHdfdy[i][j] = 0.0; + } + } + + PCCf[0][2] = 0.007860700254745; + PCCf[0][3] = 0.016125364564267; + PCCf[1][1] = 0.003026697473481; + PCCf[1][2] = 0.006326248241119; + PCCf[2][0] = 0.; + PCCf[2][1] = 0.003179530830731; + + PCHf[0][1] = 0.2093367328250380; + PCHf[0][2] = -0.064449615432525; + PCHf[0][3] = -0.303927546346162; + PCHf[1][0] = 0.010; + PCHf[1][1] = -0.1251234006287090; + PCHf[1][2] = -0.298905245783; + PCHf[2][0] = -0.1220421462782555; + PCHf[2][1] = -0.3005291724067579; + PCHf[3][0] = -0.307584705066; + + for (int nH = 0; nH < 4; nH++) { + for (int nC = 0; nC < 4; nC++) { + double y[4] = {0}, y1[4] = {0}, y2[4] = {0}; + y[0] = PCCf[nC][nH]; + y[1] = PCCf[nC][nH+1]; + y[2] = PCCf[nC+1][nH]; + y[3] = PCCf[nC+1][nH+1]; + Spbicubic_patch_coeffs(nC, nC+1, nH, nH+1, y, y1, y2, &pCC[nC][nH][0]); + y[0] = PCHf[nC][nH]; + y[1] = PCHf[nC][nH+1]; + y[2] = PCHf[nC+1][nH]; + y[3] = PCHf[nC+1][nH+1]; + Spbicubic_patch_coeffs(nC, nC+1, nH, nH+1, y, y1, y2, &pCH[nC][nH][0]); + } + } + + for (i = 0; i < 5; i++) { + for (j = 0; j < 5; j++) { + for (k = 0; k < 10; k++) { + piCCf[i][j][k] = 0.0; + piCCdfdx[i][j][k] = 0.0; + piCCdfdy[i][j][k] = 0.0; + piCCdfdz[i][j][k] = 0.0; + piCHf[i][j][k] = 0.0; + piCHdfdx[i][j][k] = 0.0; + piCHdfdy[i][j][k] = 0.0; + piCHdfdz[i][j][k] = 0.0; + piHHf[i][j][k] = 0.0; + piHHdfdx[i][j][k] = 0.0; + piHHdfdy[i][j][k] = 0.0; + piHHdfdz[i][j][k] = 0.0; + Tf[i][j][k] = 0.0; + Tdfdx[i][j][k] = 0.0; + Tdfdy[i][j][k] = 0.0; + Tdfdz[i][j][k] = 0.0; + } + } + } + + for (i = 3; i < 10; i++) piCCf[0][0][i] = 0.0049586079; + piCCf[1][0][1] = 0.021693495; + piCCf[0][1][1] = 0.021693495; + for (i = 2; i < 10; i++) piCCf[1][0][i] = 0.0049586079; + for (i = 2; i < 10; i++) piCCf[0][1][i] = 0.0049586079; + piCCf[1][1][1] = 0.05250; + piCCf[1][1][2] = -0.002088750; + for (i = 3; i < 10; i++) piCCf[1][1][i] = -0.00804280; + piCCf[2][0][1] = 0.024698831850; + piCCf[0][2][1] = 0.024698831850; + piCCf[2][0][2] = -0.00597133450; + piCCf[0][2][2] = -0.00597133450; + for (i = 3; i < 10; i++) piCCf[2][0][i] = 0.0049586079; + for (i = 3; i < 10; i++) piCCf[0][2][i] = 0.0049586079; + piCCf[2][1][1] = 0.00482478490; + piCCf[1][2][1] = 0.00482478490; + piCCf[2][1][2] = 0.0150; + piCCf[1][2][2] = 0.0150; + piCCf[2][1][3] = -0.010; + piCCf[1][2][3] = -0.010; + piCCf[2][1][4] = -0.01168893870; + piCCf[1][2][4] = -0.01168893870; + piCCf[2][1][5] = -0.013377877400; + piCCf[1][2][5] = -0.013377877400; + piCCf[2][1][6] = -0.015066816000; + piCCf[1][2][6] = -0.015066816000; + for (i = 7; i < 10; i++) piCCf[2][1][i] = -0.015066816000; + for (i = 7; i < 10; i++) piCCf[1][2][i] = -0.015066816000; + piCCf[2][2][1] = 0.0472247850; + piCCf[2][2][2] = 0.0110; + piCCf[2][2][3] = 0.0198529350; + piCCf[2][2][4] = 0.01654411250; + piCCf[2][2][5] = 0.013235290; + piCCf[2][2][6] = 0.00992646749999 ; + piCCf[2][2][7] = 0.006617644999; + piCCf[2][2][8] = 0.00330882250; + piCCf[3][0][1] = -0.05989946750; + piCCf[0][3][1] = -0.05989946750; + piCCf[3][0][2] = -0.05989946750; + piCCf[0][3][2] = -0.05989946750; + for (i = 3; i < 10; i++) piCCf[3][0][i] = 0.0049586079; + for (i = 3; i < 10; i++) piCCf[0][3][i] = 0.0049586079; + piCCf[3][1][2] = -0.0624183760; + piCCf[1][3][2] = -0.0624183760; + for (i = 3; i < 10; i++) piCCf[3][1][i] = -0.0624183760; + for (i = 3; i < 10; i++) piCCf[1][3][i] = -0.0624183760; + piCCf[3][2][1] = -0.02235469150; + piCCf[2][3][1] = -0.02235469150; + for (i = 2; i < 10; i++) piCCf[3][2][i] = -0.02235469150; + for (i = 2; i < 10; i++) piCCf[2][3][i] = -0.02235469150; + + piCCdfdx[2][1][1] = -0.026250; + piCCdfdx[2][1][5] = -0.0271880; + piCCdfdx[2][1][6] = -0.0271880; + for (i = 7; i < 10; i++) piCCdfdx[2][1][i] = -0.0271880; + piCCdfdx[1][3][2] = 0.0187723882; + for (i = 2; i < 10; i++) piCCdfdx[2][3][i] = 0.031209; + + piCCdfdy[1][2][1] = -0.026250; + piCCdfdy[1][2][5] = -0.0271880; + piCCdfdy[1][2][6] = -0.0271880; + for (i = 7; i < 10; i++) piCCdfdy[1][2][i] = -0.0271880; + piCCdfdy[3][1][2] = 0.0187723882; + for (i = 2; i < 10; i++) piCCdfdy[3][2][i] = 0.031209; + + piCCdfdz[1][1][2] = -0.0302715; + piCCdfdz[2][1][4] = -0.0100220; + piCCdfdz[1][2][4] = -0.0100220; + piCCdfdz[2][1][5] = -0.0100220; + piCCdfdz[1][2][5] = -0.0100220; + for (i = 4; i < 9; i++) piCCdfdz[2][2][i] = -0.0033090; + + // make top end of piCC flat instead of zero + i = 4; + for (j = 0; j < 4; j++){ + for (k = 1; k < 11; k++){ + piCCf[i][j][k] = piCCf[i-1][j][k]; + } + } + for (i = 0; i < 4; i++){ // also enforces some symmetry + for (j = i+1; j < 5; j++){ + for (k = 1; k < 11; k++){ + piCCf[i][j][k] = piCCf[j][i][k]; + } + } + } + for (k = 1; k < 11; k++) piCCf[4][4][k] = piCCf[3][4][k]; + k = 10; + for (i = 0; i < 5; i++){ + for (j = 0; j < 5; j++){ + piCCf[i][j][k] = piCCf[i][j][k-1]; + } + } + + piCHf[1][1][1] = -0.050; + piCHf[1][1][2] = -0.050; + piCHf[1][1][3] = -0.30; + for (i = 4; i < 10; i++) piCHf[1][1][i] = -0.050; + for (i = 5; i < 10; i++) piCHf[2][0][i] = -0.004523893758064; + for (i = 5; i < 10; i++) piCHf[0][2][i] = -0.004523893758064; + piCHf[2][1][2] = -0.250; + piCHf[1][2][2] = -0.250; + piCHf[2][1][3] = -0.250; + piCHf[1][2][3] = -0.250; + piCHf[3][1][1] = -0.10; + piCHf[1][3][1] = -0.10; + piCHf[3][1][2] = -0.125; + piCHf[1][3][2] = -0.125; + piCHf[3][1][3] = -0.125; + piCHf[1][3][3] = -0.125; + for (i = 4; i < 10; i++) piCHf[3][1][i] = -0.10; + for (i = 4; i < 10; i++) piCHf[1][3][i] = -0.10; + + // make top end of piCH flat instead of zero + // also enforces some symmetry + + i = 4; + for (j = 0; j < 4; j++){ + for (k = 1; k < 11; k++){ + piCHf[i][j][k] = piCHf[i-1][j][k]; + } + } + for (i = 0; i < 4; i++){ + for (j = i+1; j < 5; j++){ + for (k = 1; k < 11; k++){ + piCHf[i][j][k] = piCHf[j][i][k]; + } + } + } + for (k = 1; k < 11; k++) piCHf[4][4][k] = piCHf[3][4][k]; + k = 10; + for (i = 0; i < 5; i++){ + for (j = 0; j < 5; j++){ + piCHf[i][j][k] = piCHf[i][j][k-1]; + } + } + + piHHf[1][1][1] = 0.124915958; - // this one parameter for C-C interactions is different in REBO vs AIREBO - // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) + Tf[2][2][1] = -0.035140; + for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480; - PCCf_2_0 = 0.0; + for (int nH = 0; nH < 4; nH++) { + for (int nC = 0; nC < 4; nC++) { + // Note: Spline knot values exist up to "10", but are never used because + // they are clamped down to 9. + for (int nConj = 0; nConj < 9; nConj++) { + double y[8] = {0}, y1[8] = {0}, y2[8] = {0}, y3[8] = {0}; + #define FILL_KNOTS_TRI(dest, src) \ + dest[0] = src[nC+0][nH+0][nConj+0]; \ + dest[1] = src[nC+0][nH+0][nConj+1]; \ + dest[2] = src[nC+0][nH+1][nConj+0]; \ + dest[3] = src[nC+0][nH+1][nConj+1]; \ + dest[4] = src[nC+1][nH+0][nConj+0]; \ + dest[5] = src[nC+1][nH+0][nConj+1]; \ + dest[6] = src[nC+1][nH+1][nConj+0]; \ + dest[7] = src[nC+1][nH+1][nConj+1]; + FILL_KNOTS_TRI(y, piCCf) + FILL_KNOTS_TRI(y1, piCCdfdx) + FILL_KNOTS_TRI(y2, piCCdfdy) + FILL_KNOTS_TRI(y3, piCCdfdz) + Sptricubic_patch_coeffs(nC, nC+1, nH, nH+1, nConj, nConj+1, y, y1, y2, y3, &piCC[nC][nH][nConj][0]); + FILL_KNOTS_TRI(y, piCHf) + FILL_KNOTS_TRI(y1, piCHdfdx) + FILL_KNOTS_TRI(y2, piCHdfdy) + FILL_KNOTS_TRI(y3, piCHdfdz) + Sptricubic_patch_coeffs(nC, nC+1, nH, nH+1, nConj, nConj+1, y, y1, y2, y3, &piCH[nC][nH][nConj][0]); + FILL_KNOTS_TRI(y, piHHf) + FILL_KNOTS_TRI(y1, piHHdfdx) + FILL_KNOTS_TRI(y2, piHHdfdy) + FILL_KNOTS_TRI(y3, piHHdfdz) + Sptricubic_patch_coeffs(nC, nC+1, nH, nH+1, nConj, nConj+1, y, y1, y2, y3, &piHH[nC][nH][nConj][0]); + FILL_KNOTS_TRI(y, Tf) + FILL_KNOTS_TRI(y1, Tdfdx) + FILL_KNOTS_TRI(y2, Tdfdy) + FILL_KNOTS_TRI(y3, Tdfdz) + Sptricubic_patch_coeffs(nC, nC+1, nH, nH+1, nConj, nConj+1, y, y1, y2, y3, &Tijc[nC][nH][nConj][0]); + #undef FILL_KNOTS_TRI + } + } + } } diff --git a/src/MANYBODY/pair_rebo.h b/src/MANYBODY/pair_rebo.h index be1e1f0b55..9c1a12d4de 100644 --- a/src/MANYBODY/pair_rebo.h +++ b/src/MANYBODY/pair_rebo.h @@ -28,6 +28,7 @@ class PairREBO : public PairAIREBO { public: PairREBO(class LAMMPS *); void settings(int, char **); + void spline_init(); }; } -- GitLab From 1235e77199eaffa29257b6ad8483cd7e98bf88b6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 9 Nov 2018 15:18:01 -0500 Subject: [PATCH 0065/1243] implemented recommended change to remove global class member --- src/MANYBODY/pair_airebo.cpp | 7 +------ src/MANYBODY/pair_airebo.h | 1 - src/MANYBODY/pair_rebo.cpp | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index 067eb1634f..f2877647c0 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -168,10 +168,6 @@ void PairAIREBO::settings(int narg, char **arg) sigwid = sigcut - sigmin; } - // this one parameter for C-C interactions is different in AIREBO vs REBO - // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) - - PCCf_2_0 = -0.0276030; } /* ---------------------------------------------------------------------- @@ -4373,8 +4369,7 @@ void PairAIREBO::spline_init() // this one parameter for C-C interactions is different in REBO vs AIREBO // see Favata, Micheletti, Ryu, Pugno, Comp Phys Comm (2016) - PCCf[2][0] = PCCf_2_0; - + PCCf[2][0] = -0.0276030; PCCf[2][1] = 0.00317953083; PCHf[0][1] = 0.209336733; diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index c7c9b07357..579c342f1b 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -84,7 +84,6 @@ class PairAIREBO : public Pair { // spline knot values - double PCCf_2_0; double PCCf[5][5],PCCdfdx[5][5],PCCdfdy[5][5],PCHf[5][5]; double PCHdfdx[5][5],PCHdfdy[5][5]; double piCCf[5][5][11],piCCdfdx[5][5][11]; diff --git a/src/MANYBODY/pair_rebo.cpp b/src/MANYBODY/pair_rebo.cpp index 10d1d83579..5563e1222c 100644 --- a/src/MANYBODY/pair_rebo.cpp +++ b/src/MANYBODY/pair_rebo.cpp @@ -30,7 +30,6 @@ void PairREBO::settings(int narg, char **/*arg*/) cutlj = 0.0; ljflag = torflag = 0; - PCCf_2_0 = -0.0276030; } /* ---------------------------------------------------------------------- -- GitLab From dcffeb546fd297d5e5cc3af5b64fdfb48de9650b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 20 Nov 2018 13:48:49 -0500 Subject: [PATCH 0066/1243] update AIREBO/REBO examples and provide references for rebo and airebo with LJ and TORSION turned off --- examples/airebo/in.airebo-0-0 | 22 +++++ examples/airebo/in.rebo2 | 22 +++++ examples/airebo/log.29Jun18.airebo-0-0.g++.1 | 88 +++++++++++++++++++ examples/airebo/log.29Jun18.airebo-0-0.g++.4 | 88 +++++++++++++++++++ ...ebo-m.g++.1 => log.29Jun18.airebo-m.g++.1} | 24 ++--- ...ebo-m.g++.4 => log.29Jun18.airebo-m.g++.4} | 24 ++--- ....airebo.g++.1 => log.29Jun18.airebo.g++.1} | 24 ++--- ....airebo.g++.4 => log.29Jun18.airebo.g++.4} | 24 ++--- examples/airebo/log.29Jun18.rebo2.g++.1 | 88 +++++++++++++++++++ examples/airebo/log.29Jun18.rebo2.g++.4 | 88 +++++++++++++++++++ 10 files changed, 448 insertions(+), 44 deletions(-) create mode 100644 examples/airebo/in.airebo-0-0 create mode 100644 examples/airebo/in.rebo2 create mode 100644 examples/airebo/log.29Jun18.airebo-0-0.g++.1 create mode 100644 examples/airebo/log.29Jun18.airebo-0-0.g++.4 rename examples/airebo/{log.23Jun17.airebo-m.g++.1 => log.29Jun18.airebo-m.g++.1} (78%) rename examples/airebo/{log.23Jun17.airebo-m.g++.4 => log.29Jun18.airebo-m.g++.4} (78%) rename examples/airebo/{log.23Jun17.airebo.g++.1 => log.29Jun18.airebo.g++.1} (78%) rename examples/airebo/{log.23Jun17.airebo.g++.4 => log.29Jun18.airebo.g++.4} (78%) create mode 100644 examples/airebo/log.29Jun18.rebo2.g++.1 create mode 100644 examples/airebo/log.29Jun18.rebo2.g++.4 diff --git a/examples/airebo/in.airebo-0-0 b/examples/airebo/in.airebo-0-0 new file mode 100644 index 0000000000..edcb1561fb --- /dev/null +++ b/examples/airebo/in.airebo-0-0 @@ -0,0 +1,22 @@ +# AIREBO polyethelene benchmark + +units metal +atom_style atomic + +read_data data.airebo + +replicate 17 16 2 + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style airebo 3.0 0 0 +pair_coeff * * ../../potentials/CH.airebo C H + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 10 +run 100 diff --git a/examples/airebo/in.rebo2 b/examples/airebo/in.rebo2 new file mode 100644 index 0000000000..6834528ffb --- /dev/null +++ b/examples/airebo/in.rebo2 @@ -0,0 +1,22 @@ +# AIREBO polyethelene benchmark + +units metal +atom_style atomic + +read_data data.airebo + +replicate 17 16 2 + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style rebo +pair_coeff * * ../../potentials/CH.rebo C H + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 10 +run 100 diff --git a/examples/airebo/log.29Jun18.airebo-0-0.g++.1 b/examples/airebo/log.29Jun18.airebo-0-0.g++.1 new file mode 100644 index 0000000000..d61c8e8b34 --- /dev/null +++ b/examples/airebo/log.29Jun18.airebo-0-0.g++.1 @@ -0,0 +1,88 @@ +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +# AIREBO polyethelene benchmark + +units metal +atom_style atomic + +read_data data.airebo + orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 60 atoms + +replicate 17 16 2 + orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) + 1 by 1 by 1 MPI processor grid + 32640 atoms + Time spent = 0.00136042 secs + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style airebo 3.0 0 0 +pair_coeff * * ../../potentials/CH.airebo C H +Reading potential file ../../potentials/CH.airebo with DATE: 2011-10-25 + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 10 +run 100 +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.5 + ghost atom cutoff = 6.5 + binsize = 3.25, bins = 22 21 16 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair airebo, perpetual + attributes: full, newton on, ghost + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 34.21 | 34.21 | 34.21 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 300 -138442.83 0 -137177.16 2463.0756 + 10 179.38448 -137931.29 0 -137174.48 15656.689 + 20 206.89283 -138047.05 0 -137174.19 -24047.407 + 30 150.81289 -137807.48 0 -137171.21 -16524.191 + 40 173.24289 -137902.32 0 -137171.42 -5721.7187 + 50 151.80722 -137812.37 0 -137171.91 3489.8954 + 60 199.06038 -138013.7 0 -137173.88 17887.024 + 70 217.84848 -138093.82 0 -137174.73 -12266.16 + 80 202.34667 -138029.28 0 -137175.59 -7623.6635 + 90 194.92367 -137997.12 0 -137174.75 -32277.173 + 100 185.2078 -137954.64 0 -137173.26 -6888.5104 +Loop time of 5.00753 on 1 procs for 100 steps with 32640 atoms + +Performance: 0.863 ns/day, 27.820 hours/ns, 19.970 timesteps/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 3.4898 | 3.4898 | 3.4898 | 0.0 | 69.69 +Neigh | 1.4697 | 1.4697 | 1.4697 | 0.0 | 29.35 +Comm | 0.015885 | 0.015885 | 0.015885 | 0.0 | 0.32 +Output | 0.00096607 | 0.00096607 | 0.00096607 | 0.0 | 0.02 +Modify | 0.021901 | 0.021901 | 0.021901 | 0.0 | 0.44 +Other | | 0.009297 | | | 0.19 + +Nlocal: 32640 ave 32640 max 32640 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 26460 ave 26460 max 26460 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 4.90213e+06 ave 4.90213e+06 max 4.90213e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 4902134 +Ave neighs/atom = 150.188 +Neighbor list builds = 9 +Dangerous builds = 0 +Total wall time: 0:00:05 diff --git a/examples/airebo/log.29Jun18.airebo-0-0.g++.4 b/examples/airebo/log.29Jun18.airebo-0-0.g++.4 new file mode 100644 index 0000000000..72d6fdd211 --- /dev/null +++ b/examples/airebo/log.29Jun18.airebo-0-0.g++.4 @@ -0,0 +1,88 @@ +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +# AIREBO polyethelene benchmark + +units metal +atom_style atomic + +read_data data.airebo + orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) + 1 by 1 by 4 MPI processor grid + reading atoms ... + 60 atoms + +replicate 17 16 2 + orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) + 2 by 2 by 1 MPI processor grid + 32640 atoms + Time spent = 0.000609159 secs + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style airebo 3.0 0 0 +pair_coeff * * ../../potentials/CH.airebo C H +Reading potential file ../../potentials/CH.airebo with DATE: 2011-10-25 + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 10 +run 100 +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.5 + ghost atom cutoff = 6.5 + binsize = 3.25, bins = 22 21 16 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair airebo, perpetual + attributes: full, newton on, ghost + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 11.75 | 11.94 | 12.13 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 300 -138442.83 0 -137177.16 2463.0756 + 10 179.38448 -137931.29 0 -137174.48 15656.689 + 20 206.89283 -138047.05 0 -137174.19 -24047.407 + 30 150.81289 -137807.48 0 -137171.21 -16524.191 + 40 173.24289 -137902.32 0 -137171.42 -5721.7187 + 50 151.80722 -137812.37 0 -137171.91 3489.8954 + 60 199.06038 -138013.7 0 -137173.88 17887.024 + 70 217.84848 -138093.82 0 -137174.73 -12266.16 + 80 202.34667 -138029.28 0 -137175.59 -7623.6635 + 90 194.92367 -137997.12 0 -137174.75 -32277.173 + 100 185.2078 -137954.64 0 -137173.26 -6888.5104 +Loop time of 1.50369 on 4 procs for 100 steps with 32640 atoms + +Performance: 2.873 ns/day, 8.354 hours/ns, 66.503 timesteps/s +98.5% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.92943 | 0.95749 | 0.97327 | 1.8 | 63.68 +Neigh | 0.456 | 0.46115 | 0.46657 | 0.7 | 30.67 +Comm | 0.048775 | 0.068415 | 0.10077 | 8.2 | 4.55 +Output | 0.00044918 | 0.00073665 | 0.0015814 | 0.0 | 0.05 +Modify | 0.0087936 | 0.0089477 | 0.0091038 | 0.1 | 0.60 +Other | | 0.006951 | | | 0.46 + +Nlocal: 8160 ave 8163 max 8157 min +Histogram: 1 1 0 0 0 0 0 0 1 1 +Nghost: 11605.8 ave 11615 max 11593 min +Histogram: 1 0 0 0 0 0 2 0 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 1.22553e+06 ave 1.22734e+06 max 1.22455e+06 min +Histogram: 2 0 0 1 0 0 0 0 0 1 + +Total # of neighbors = 4902134 +Ave neighs/atom = 150.188 +Neighbor list builds = 9 +Dangerous builds = 0 +Total wall time: 0:00:01 diff --git a/examples/airebo/log.23Jun17.airebo-m.g++.1 b/examples/airebo/log.29Jun18.airebo-m.g++.1 similarity index 78% rename from examples/airebo/log.23Jun17.airebo-m.g++.1 rename to examples/airebo/log.29Jun18.airebo-m.g++.1 index 1483fcb4a6..ea587e9380 100644 --- a/examples/airebo/log.23Jun17.airebo-m.g++.1 +++ b/examples/airebo/log.29Jun18.airebo-m.g++.1 @@ -1,4 +1,5 @@ -LAMMPS (23 Jun 2017) +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -15,6 +16,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 1 by 1 by 1 MPI processor grid 32640 atoms + Time spent = 0.00136828 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -55,20 +57,20 @@ Step Temp E_pair E_mol TotEng Press 80 164.28396 -138709.5 0 -138016.4 -1524.7353 90 180.26403 -138776.42 0 -138015.9 -27143.467 100 164.05694 -138706.58 0 -138014.44 5157.5516 -Loop time of 117.672 on 1 procs for 100 steps with 32640 atoms +Loop time of 64.9938 on 1 procs for 100 steps with 32640 atoms -Performance: 0.037 ns/day, 653.734 hours/ns, 0.850 timesteps/s -99.3% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 0.066 ns/day, 361.077 hours/ns, 1.539 timesteps/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 108.31 | 108.31 | 108.31 | 0.0 | 92.04 -Neigh | 9.2199 | 9.2199 | 9.2199 | 0.0 | 7.84 -Comm | 0.052942 | 0.052942 | 0.052942 | 0.0 | 0.04 -Output | 0.0015149 | 0.0015149 | 0.0015149 | 0.0 | 0.00 -Modify | 0.060962 | 0.060962 | 0.060962 | 0.0 | 0.05 -Other | | 0.02656 | | | 0.02 +Pair | 60.289 | 60.289 | 60.289 | 0.0 | 92.76 +Neigh | 4.6445 | 4.6445 | 4.6445 | 0.0 | 7.15 +Comm | 0.025577 | 0.025577 | 0.025577 | 0.0 | 0.04 +Output | 0.00097752 | 0.00097752 | 0.00097752 | 0.0 | 0.00 +Modify | 0.022412 | 0.022412 | 0.022412 | 0.0 | 0.03 +Other | | 0.01114 | | | 0.02 Nlocal: 32640 ave 32640 max 32640 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -83,4 +85,4 @@ Total # of neighbors = 22210922 Ave neighs/atom = 680.482 Neighbor list builds = 8 Dangerous builds = 0 -Total wall time: 0:02:00 +Total wall time: 0:01:06 diff --git a/examples/airebo/log.23Jun17.airebo-m.g++.4 b/examples/airebo/log.29Jun18.airebo-m.g++.4 similarity index 78% rename from examples/airebo/log.23Jun17.airebo-m.g++.4 rename to examples/airebo/log.29Jun18.airebo-m.g++.4 index 3a3d922bcb..d93f6f7c85 100644 --- a/examples/airebo/log.23Jun17.airebo-m.g++.4 +++ b/examples/airebo/log.29Jun18.airebo-m.g++.4 @@ -1,4 +1,5 @@ -LAMMPS (23 Jun 2017) +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -15,6 +16,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 2 by 2 by 1 MPI processor grid 32640 atoms + Time spent = 0.000688076 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -55,20 +57,20 @@ Step Temp E_pair E_mol TotEng Press 80 164.28396 -138709.5 0 -138016.4 -1524.7353 90 180.26403 -138776.42 0 -138015.9 -27143.467 100 164.05694 -138706.58 0 -138014.44 5157.5516 -Loop time of 32.9268 on 4 procs for 100 steps with 32640 atoms +Loop time of 18.0388 on 4 procs for 100 steps with 32640 atoms -Performance: 0.131 ns/day, 182.927 hours/ns, 3.037 timesteps/s -99.4% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 0.239 ns/day, 100.216 hours/ns, 5.544 timesteps/s +99.1% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 28.045 | 28.537 | 29.42 | 10.4 | 86.67 -Neigh | 3.163 | 3.237 | 3.3761 | 4.7 | 9.83 -Comm | 0.09883 | 1.1206 | 1.6862 | 60.4 | 3.40 -Output | 0.00099325 | 0.0011329 | 0.0012462 | 0.3 | 0.00 -Modify | 0.016013 | 0.016726 | 0.017257 | 0.4 | 0.05 -Other | | 0.01459 | | | 0.04 +Pair | 15.983 | 16.085 | 16.285 | 2.9 | 89.17 +Neigh | 1.5975 | 1.6116 | 1.6215 | 0.8 | 8.93 +Comm | 0.11408 | 0.32424 | 0.43065 | 21.7 | 1.80 +Output | 0.00062895 | 0.0012782 | 0.0018394 | 1.2 | 0.01 +Modify | 0.0089653 | 0.0090135 | 0.0090837 | 0.0 | 0.05 +Other | | 0.007664 | | | 0.04 Nlocal: 8160 ave 8167 max 8153 min Histogram: 1 0 1 0 0 0 0 1 0 1 @@ -83,4 +85,4 @@ Total # of neighbors = 22210922 Ave neighs/atom = 680.482 Neighbor list builds = 8 Dangerous builds = 0 -Total wall time: 0:00:33 +Total wall time: 0:00:18 diff --git a/examples/airebo/log.23Jun17.airebo.g++.1 b/examples/airebo/log.29Jun18.airebo.g++.1 similarity index 78% rename from examples/airebo/log.23Jun17.airebo.g++.1 rename to examples/airebo/log.29Jun18.airebo.g++.1 index 0ef895dc28..12ba33cd95 100644 --- a/examples/airebo/log.23Jun17.airebo.g++.1 +++ b/examples/airebo/log.29Jun18.airebo.g++.1 @@ -1,4 +1,5 @@ -LAMMPS (23 Jun 2017) +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -15,6 +16,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 1 by 1 by 1 MPI processor grid 32640 atoms + Time spent = 0.00137973 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -55,20 +57,20 @@ Step Temp E_pair E_mol TotEng Press 80 157.16184 -138695.77 0 -138032.72 19824.698 90 196.15907 -138860.65 0 -138033.07 -7950.8462 100 178.31875 -138784.89 0 -138032.57 30997.671 -Loop time of 110.107 on 1 procs for 100 steps with 32640 atoms +Loop time of 58.178 on 1 procs for 100 steps with 32640 atoms -Performance: 0.039 ns/day, 611.705 hours/ns, 0.908 timesteps/s -99.5% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 0.074 ns/day, 323.211 hours/ns, 1.719 timesteps/s +99.0% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 100.76 | 100.76 | 100.76 | 0.0 | 91.51 -Neigh | 9.1909 | 9.1909 | 9.1909 | 0.0 | 8.35 -Comm | 0.058134 | 0.058134 | 0.058134 | 0.0 | 0.05 -Output | 0.0015941 | 0.0015941 | 0.0015941 | 0.0 | 0.00 -Modify | 0.062212 | 0.062212 | 0.062212 | 0.0 | 0.06 -Other | | 0.03123 | | | 0.03 +Pair | 53.477 | 53.477 | 53.477 | 0.0 | 91.92 +Neigh | 4.6405 | 4.6405 | 4.6405 | 0.0 | 7.98 +Comm | 0.025745 | 0.025745 | 0.025745 | 0.0 | 0.04 +Output | 0.00097823 | 0.00097823 | 0.00097823 | 0.0 | 0.00 +Modify | 0.022715 | 0.022715 | 0.022715 | 0.0 | 0.04 +Other | | 0.01117 | | | 0.02 Nlocal: 32640 ave 32640 max 32640 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -83,4 +85,4 @@ Total # of neighbors = 22217840 Ave neighs/atom = 680.694 Neighbor list builds = 8 Dangerous builds = 0 -Total wall time: 0:01:52 +Total wall time: 0:00:59 diff --git a/examples/airebo/log.23Jun17.airebo.g++.4 b/examples/airebo/log.29Jun18.airebo.g++.4 similarity index 78% rename from examples/airebo/log.23Jun17.airebo.g++.4 rename to examples/airebo/log.29Jun18.airebo.g++.4 index 486b48a004..36794642af 100644 --- a/examples/airebo/log.23Jun17.airebo.g++.4 +++ b/examples/airebo/log.29Jun18.airebo.g++.4 @@ -1,4 +1,5 @@ -LAMMPS (23 Jun 2017) +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -15,6 +16,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 2 by 2 by 1 MPI processor grid 32640 atoms + Time spent = 0.000712872 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -55,20 +57,20 @@ Step Temp E_pair E_mol TotEng Press 80 157.16184 -138695.77 0 -138032.72 19824.698 90 196.15907 -138860.65 0 -138033.07 -7950.8462 100 178.31875 -138784.89 0 -138032.57 30997.671 -Loop time of 30.1916 on 4 procs for 100 steps with 32640 atoms +Loop time of 16.4409 on 4 procs for 100 steps with 32640 atoms -Performance: 0.143 ns/day, 167.731 hours/ns, 3.312 timesteps/s -99.1% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 0.263 ns/day, 91.338 hours/ns, 6.082 timesteps/s +98.4% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 26.083 | 26.31 | 26.795 | 5.5 | 87.14 -Neigh | 3.1781 | 3.2134 | 3.2775 | 2.2 | 10.64 -Comm | 0.086296 | 0.63643 | 0.88995 | 40.2 | 2.11 -Output | 0.00074124 | 0.0010698 | 0.0013616 | 0.7 | 0.00 -Modify | 0.015335 | 0.016373 | 0.017565 | 0.8 | 0.05 -Other | | 0.01457 | | | 0.05 +Pair | 14.212 | 14.384 | 14.487 | 3.0 | 87.49 +Neigh | 1.5943 | 1.615 | 1.6263 | 1.0 | 9.82 +Comm | 0.30944 | 0.42389 | 0.61698 | 19.2 | 2.58 +Output | 0.00065231 | 0.00094843 | 0.0018184 | 0.0 | 0.01 +Modify | 0.0092347 | 0.0093143 | 0.0094111 | 0.1 | 0.06 +Other | | 0.007456 | | | 0.05 Nlocal: 8160 ave 8174 max 8146 min Histogram: 1 0 1 0 0 0 0 1 0 1 @@ -83,4 +85,4 @@ Total # of neighbors = 22217840 Ave neighs/atom = 680.694 Neighbor list builds = 8 Dangerous builds = 0 -Total wall time: 0:00:30 +Total wall time: 0:00:16 diff --git a/examples/airebo/log.29Jun18.rebo2.g++.1 b/examples/airebo/log.29Jun18.rebo2.g++.1 new file mode 100644 index 0000000000..54c87ab474 --- /dev/null +++ b/examples/airebo/log.29Jun18.rebo2.g++.1 @@ -0,0 +1,88 @@ +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +# AIREBO polyethelene benchmark + +units metal +atom_style atomic + +read_data data.airebo + orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 60 atoms + +replicate 17 16 2 + orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) + 1 by 1 by 1 MPI processor grid + 32640 atoms + Time spent = 0.00153542 secs + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style rebo +pair_coeff * * ../../potentials/CH.rebo C H +Reading potential file ../../potentials/CH.rebo with DATE: 2018-7-3 + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 10 +run 100 +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.5 + ghost atom cutoff = 6.5 + binsize = 3.25, bins = 22 21 16 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair rebo, perpetual + attributes: full, newton on, ghost + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 34.21 | 34.21 | 34.21 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 300 -138442.83 0 -137177.16 2463.0748 + 10 179.37985 -137931.27 0 -137174.48 15655.936 + 20 206.87654 -138046.99 0 -137174.19 -24042.627 + 30 150.80122 -137807.43 0 -137171.21 -16524.118 + 40 173.24945 -137902.35 0 -137171.42 -5716.9118 + 50 151.80455 -137812.36 0 -137171.91 3480.4584 + 60 199.08777 -138013.82 0 -137173.88 17881.372 + 70 217.85748 -138093.86 0 -137174.73 -12270.999 + 80 202.37482 -138029.39 0 -137175.59 -7622.732 + 90 194.90628 -137997.05 0 -137174.75 -32267.471 + 100 185.17818 -137954.51 0 -137173.26 -6901.7499 +Loop time of 5.03541 on 1 procs for 100 steps with 32640 atoms + +Performance: 0.858 ns/day, 27.975 hours/ns, 19.859 timesteps/s +99.0% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 3.5083 | 3.5083 | 3.5083 | 0.0 | 69.67 +Neigh | 1.4785 | 1.4785 | 1.4785 | 0.0 | 29.36 +Comm | 0.016176 | 0.016176 | 0.016176 | 0.0 | 0.32 +Output | 0.0009644 | 0.0009644 | 0.0009644 | 0.0 | 0.02 +Modify | 0.02224 | 0.02224 | 0.02224 | 0.0 | 0.44 +Other | | 0.009286 | | | 0.18 + +Nlocal: 32640 ave 32640 max 32640 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 26460 ave 26460 max 26460 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 4.90213e+06 ave 4.90213e+06 max 4.90213e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 4902134 +Ave neighs/atom = 150.188 +Neighbor list builds = 9 +Dangerous builds = 0 +Total wall time: 0:00:05 diff --git a/examples/airebo/log.29Jun18.rebo2.g++.4 b/examples/airebo/log.29Jun18.rebo2.g++.4 new file mode 100644 index 0000000000..b7d63dd2e5 --- /dev/null +++ b/examples/airebo/log.29Jun18.rebo2.g++.4 @@ -0,0 +1,88 @@ +LAMMPS (29 Jun 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +# AIREBO polyethelene benchmark + +units metal +atom_style atomic + +read_data data.airebo + orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) + 1 by 1 by 4 MPI processor grid + reading atoms ... + 60 atoms + +replicate 17 16 2 + orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) + 2 by 2 by 1 MPI processor grid + 32640 atoms + Time spent = 0.00151467 secs + +neighbor 0.5 bin +neigh_modify delay 5 every 1 + +pair_style rebo +pair_coeff * * ../../potentials/CH.rebo C H +Reading potential file ../../potentials/CH.rebo with DATE: 2018-7-3 + +velocity all create 300.0 761341 + +fix 1 all nve +timestep 0.0005 + +thermo 10 +run 100 +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.5 + ghost atom cutoff = 6.5 + binsize = 3.25, bins = 22 21 16 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair rebo, perpetual + attributes: full, newton on, ghost + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 11.75 | 11.94 | 12.13 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 300 -138442.83 0 -137177.16 2463.0748 + 10 179.37985 -137931.27 0 -137174.48 15655.936 + 20 206.87654 -138046.99 0 -137174.19 -24042.627 + 30 150.80122 -137807.43 0 -137171.21 -16524.118 + 40 173.24945 -137902.35 0 -137171.42 -5716.9118 + 50 151.80455 -137812.36 0 -137171.91 3480.4584 + 60 199.08777 -138013.82 0 -137173.88 17881.372 + 70 217.85748 -138093.86 0 -137174.73 -12270.999 + 80 202.37482 -138029.39 0 -137175.59 -7622.732 + 90 194.90628 -137997.05 0 -137174.75 -32267.471 + 100 185.17818 -137954.51 0 -137173.26 -6901.7499 +Loop time of 1.49632 on 4 procs for 100 steps with 32640 atoms + +Performance: 2.887 ns/day, 8.313 hours/ns, 66.831 timesteps/s +98.6% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.93275 | 0.95717 | 0.97367 | 1.6 | 63.97 +Neigh | 0.45634 | 0.46084 | 0.46749 | 0.6 | 30.80 +Comm | 0.038283 | 0.062074 | 0.090508 | 7.6 | 4.15 +Output | 0.00046492 | 0.00072992 | 0.0015128 | 0.0 | 0.05 +Modify | 0.0088651 | 0.0090639 | 0.0093012 | 0.2 | 0.61 +Other | | 0.006436 | | | 0.43 + +Nlocal: 8160 ave 8163 max 8157 min +Histogram: 1 1 0 0 0 0 0 0 1 1 +Nghost: 11605.8 ave 11615 max 11593 min +Histogram: 1 0 0 0 0 0 2 0 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 1.22553e+06 ave 1.22735e+06 max 1.22455e+06 min +Histogram: 2 0 0 1 0 0 0 0 0 1 + +Total # of neighbors = 4902134 +Ave neighs/atom = 150.188 +Neighbor list builds = 9 +Dangerous builds = 0 +Total wall time: 0:00:01 -- GitLab From e51720a2def24ce3194d0cce4c4f020942b70018 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 20 Nov 2018 13:51:12 -0500 Subject: [PATCH 0067/1243] add code to detect inconistent use of AIREBO/REBO potential files --- doc/src/pair_airebo.txt | 17 ++++++++------- src/MANYBODY/pair_airebo.cpp | 35 +++++++++++++++++++++++++----- src/MANYBODY/pair_airebo.h | 6 +++-- src/MANYBODY/pair_airebo_morse.cpp | 4 +++- src/MANYBODY/pair_rebo.cpp | 4 +++- 5 files changed, 49 insertions(+), 17 deletions(-) diff --git a/doc/src/pair_airebo.txt b/doc/src/pair_airebo.txt index c090a39af7..4d5cf4528b 100644 --- a/doc/src/pair_airebo.txt +++ b/doc/src/pair_airebo.txt @@ -36,7 +36,7 @@ pair_style airebo/morse 3.0 pair_coeff * * ../potentials/CH.airebo-m H C :pre pair_style rebo -pair_coeff * * ../potentials/CH.airebo H C :pre +pair_coeff * * ../potentials/CH.rebo H C :pre [Description:] @@ -57,7 +57,8 @@ The {rebo} pair style computes the Reactive Empirical Bond Order (REBO) Potential of "(Brenner)"_#Brenner. Note that this is the so-called 2nd generation REBO from 2002, not the original REBO from 1990. As discussed below, 2nd generation REBO is closely related to the -initial AIREBO; it is just a subset of the potential energy terms. +initial AIREBO; it is just a subset of the potential energy terms +with a few slightly different parameters The AIREBO potential consists of three terms: @@ -113,12 +114,12 @@ various dihedral angle preferences in hydrocarbon configurations. :line Only a single pair_coeff command is used with the {airebo}, {airebo} -or {rebo} style which specifies an AIREBO or AIREBO-M potential file -with parameters for C and H. Note that the {rebo} style in LAMMPS -uses the same AIREBO-formatted potential file. 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: +or {rebo} style which specifies an AIREBO, REBO, or AIREBO-M potential +file with parameters for C and H. Note that as of LAMMPS version +15 November 2018 the {rebo} style in LAMMPS uses its own potential +file (CH.rebo). 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 AIREBO elements to atom types :ul diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index f2877647c0..966a2514d6 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -49,7 +49,8 @@ using namespace MathSpecial; /* ---------------------------------------------------------------------- */ -PairAIREBO::PairAIREBO(LAMMPS *lmp) : Pair(lmp) +PairAIREBO::PairAIREBO(LAMMPS *lmp) + : Pair(lmp), variant(AIREBO) { single_enable = 0; restartinfo = 0; @@ -3368,14 +3369,38 @@ void PairAIREBO::read_file(char *filename) FILE *fp = force->open_potential(filename); if (fp == NULL) { char str[128]; - if (morseflag) - snprintf(str,128,"Cannot open AIREBO-M potential file %s",filename); - else + switch (variant) { + + case AIREBO: snprintf(str,128,"Cannot open AIREBO potential file %s",filename); + break; + + case REBO_2: + snprintf(str,128,"Cannot open REBO2 potential file %s",filename); + break; + + case AIREBO_M: + snprintf(str,128,"Cannot open AIREBO-M potential file %s",filename); + break; + + default: + snprintf(str,128,"Unknown REBO style variant %d",variant); + } error->one(FLERR,str); } - // skip initial comment lines + // skip initial comment line and check for potential file style identifier comment + + fgets(s,MAXLINE,fp); + fgets(s,MAXLINE,fp); + + if (((variant == AIREBO) && (strncmp(s,"# AIREBO ",9) != 0)) + || ((variant == REBO_2) && (strncmp(s,"# REBO2 ",8) != 0)) + || ((variant == AIREBO_M) && (strncmp(s,"# AIREBO-M ",11) != 0))) { + error->one(FLERR,"Potential file does not match AIREBO/REBO style variant"); + } + + // skip remaining comments while (1) { fgets(s,MAXLINE,fp); diff --git a/src/MANYBODY/pair_airebo.h b/src/MANYBODY/pair_airebo.h index 579c342f1b..31c99c4529 100644 --- a/src/MANYBODY/pair_airebo.h +++ b/src/MANYBODY/pair_airebo.h @@ -38,10 +38,12 @@ class PairAIREBO : public Pair { double init_one(int, int); double memory_usage(); - protected: + enum { AIREBO, REBO_2, AIREBO_M }; // for telling class variants apart in shared code + +protected: int *map; // 0 (C), 1 (H), or -1 (NULL) for each type - int me; + int me,variant; int ljflag,torflag; // 0/1 if LJ/Morse,torsion terms included int morseflag; // 1 if Morse instead of LJ for non-bonded diff --git a/src/MANYBODY/pair_airebo_morse.cpp b/src/MANYBODY/pair_airebo_morse.cpp index b501ed0982..a39f7df82e 100644 --- a/src/MANYBODY/pair_airebo_morse.cpp +++ b/src/MANYBODY/pair_airebo_morse.cpp @@ -19,7 +19,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairAIREBOMorse::PairAIREBOMorse(LAMMPS *lmp) : PairAIREBO(lmp) {} +PairAIREBOMorse::PairAIREBOMorse(LAMMPS *lmp) : PairAIREBO(lmp) { + variant = AIREBO_M; +} /* ---------------------------------------------------------------------- global settings diff --git a/src/MANYBODY/pair_rebo.cpp b/src/MANYBODY/pair_rebo.cpp index 5563e1222c..01331c912d 100644 --- a/src/MANYBODY/pair_rebo.cpp +++ b/src/MANYBODY/pair_rebo.cpp @@ -18,7 +18,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairREBO::PairREBO(LAMMPS *lmp) : PairAIREBO(lmp) {} +PairREBO::PairREBO(LAMMPS *lmp) : PairAIREBO(lmp) { + variant = REBO_2; +} /* ---------------------------------------------------------------------- global settings -- GitLab From ab1c3f649832aa37f770dd9c1775050ce4075b7a Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 30 Nov 2018 11:54:48 -0700 Subject: [PATCH 0068/1243] rendevous comm option for special bonds and fix rigid/small --- src/RIGID/fix_rigid_small.cpp | 461 ++++++-------- src/RIGID/fix_rigid_small.h | 26 +- src/comm.cpp | 51 ++ src/comm.h | 4 + src/create_atoms.cpp | 35 +- src/hashlittle.cpp | 333 ++++++++++ src/hashlittle.h | 5 + src/irregular.cpp | 17 +- src/read_data.cpp | 15 + src/read_restart.cpp | 15 + src/replicate.cpp | 8 +- src/special.cpp | 1069 ++++++++++++++++----------------- src/special.h | 27 +- 13 files changed, 1220 insertions(+), 846 deletions(-) create mode 100644 src/hashlittle.cpp create mode 100644 src/hashlittle.h diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index 44e1870e0a..4421d9ae17 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -34,6 +34,7 @@ #include "variable.h" #include "random_mars.h" #include "math_const.h" +#include "hashlittle.h" #include "memory.h" #include "error.h" @@ -70,8 +71,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : xcmimage(NULL), displace(NULL), eflags(NULL), orient(NULL), dorient(NULL), avec_ellipsoid(NULL), avec_line(NULL), avec_tri(NULL), counts(NULL), itensor(NULL), mass_body(NULL), langextra(NULL), random(NULL), - id_dilate(NULL), onemols(NULL), hash(NULL), bbox(NULL), ctr(NULL), - idclose(NULL), rsqclose(NULL) + id_dilate(NULL), onemols(NULL) { int i; @@ -107,18 +107,18 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : // parse args for rigid body specification int *mask = atom->mask; - tagint *bodyid = NULL; + tagint *bodyID = NULL; int nlocal = atom->nlocal; if (narg < 4) error->all(FLERR,"Illegal fix rigid/small command"); if (strcmp(arg[3],"molecule") == 0) { if (atom->molecule_flag == 0) error->all(FLERR,"Fix rigid/small requires atom attribute molecule"); - bodyid = atom->molecule; + bodyID = atom->molecule; } else if (strcmp(arg[3],"custom") == 0) { if (narg < 5) error->all(FLERR,"Illegal fix rigid/small command"); - bodyid = new tagint[nlocal]; + bodyID = new tagint[nlocal]; customflag = 1; // determine whether atom-style variable or atom property is used. @@ -126,9 +126,11 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : int is_double=0; int custom_index = atom->find_custom(arg[4]+2,is_double); if (custom_index == -1) - error->all(FLERR,"Fix rigid/small custom requires previously defined property/atom"); + error->all(FLERR,"Fix rigid/small custom requires " + "previously defined property/atom"); else if (is_double) - error->all(FLERR,"Fix rigid/small custom requires integer-valued property/atom"); + error->all(FLERR,"Fix rigid/small custom requires " + "integer-valued property/atom"); int minval = INT_MAX; int *value = atom->ivector[custom_index]; @@ -139,15 +141,17 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) - bodyid[i] = (tagint)(value[i] - minval + 1); - else bodyid[i] = 0; + bodyID[i] = (tagint)(value[i] - minval + 1); + else bodyID[i] = 0; } else if (strstr(arg[4],"v_") == arg[4]) { int ivariable = input->variable->find(arg[4]+2); if (ivariable < 0) - error->all(FLERR,"Variable name for fix rigid/small custom does not exist"); + error->all(FLERR,"Variable name for fix rigid/small custom " + "does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Fix rigid/small custom variable is no atom-style variable"); + error->all(FLERR,"Fix rigid/small custom variable is not " + "atom-style variable"); double *value = new double[nlocal]; input->variable->compute_atom(ivariable,0,value,1,0); int minval = INT_MAX; @@ -158,8 +162,8 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) - bodyid[i] = (tagint)((tagint)value[i] - minval + 1); - else bodyid[0] = 0; + bodyID[i] = (tagint)((tagint)value[i] - minval + 1); + else bodyID[0] = 0; delete[] value; } else error->all(FLERR,"Unsupported fix rigid custom property"); } else error->all(FLERR,"Illegal fix rigid/small command"); @@ -167,10 +171,11 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : if (atom->map_style == 0) error->all(FLERR,"Fix rigid/small requires an atom map, see atom_modify"); - // maxmol = largest bodyid # + // maxmol = largest bodyID # + maxmol = -1; for (i = 0; i < nlocal; i++) - if (mask[i] & groupbit) maxmol = MAX(maxmol,bodyid[i]); + if (mask[i] & groupbit) maxmol = MAX(maxmol,bodyID[i]); tagint itmp; MPI_Allreduce(&maxmol,&itmp,1,MPI_LMP_TAGINT,MPI_MAX,world); @@ -400,8 +405,19 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : // sets bodytag for owned atoms // body attributes are computed later by setup_bodies() - create_bodies(bodyid); - if (customflag) delete [] bodyid; + double time1 = MPI_Wtime(); + + create_bodies(bodyID); + if (customflag) delete [] bodyID; + + double time2 = MPI_Wtime(); + + if (comm->me == 0) { + if (screen) + fprintf(screen," create_bodies CPU = %g secs\n",time2-time1); + if (logfile) + fprintf(logfile," create_bodies CPU = %g secs\n",time2-time1); + } // set nlocal_body and allocate bodies I own @@ -1514,175 +1530,71 @@ void FixRigidSmall::set_v() set bodytag for all owned atoms ------------------------------------------------------------------------- */ -void FixRigidSmall::create_bodies(tagint *bodyid) +void FixRigidSmall::create_bodies(tagint *bodyID) { - int i,m,n; - double unwrap[3]; - - // error check on image flags of atoms in rigid bodies + int i,m; - imageint *image = atom->image; + // allocate buffer for input to rendezvous comm + // ncount = # of my atoms in bodies + int *mask = atom->mask; int nlocal = atom->nlocal; - int *periodicity = domain->periodicity; - int xbox,ybox,zbox; - - int flag = 0; - for (i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - xbox = (image[i] & IMGMASK) - IMGMAX; - ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; - zbox = (image[i] >> IMG2BITS) - IMGMAX; - if ((xbox && !periodicity[0]) || (ybox && !periodicity[1]) || - (zbox && !periodicity[2])) flag = 1; - } - - int flagall; - MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - if (flagall) error->all(FLERR,"Fix rigid/small atom has non-zero image flag " - "in a non-periodic dimension"); - - // allocate buffer for passing messages around ring of procs - // percount = max number of values to put in buffer for each of ncount - int ncount = 0; for (i = 0; i < nlocal; i++) if (mask[i] & groupbit) ncount++; - int percount = 5; - double *buf; - memory->create(buf,ncount*percount,"rigid/small:buf"); - - // create map hash for storing unique body IDs of my atoms - // key = body ID - // value = index into per-body data structure - // n = # of entries in hash - - hash = new std::map(); - hash->clear(); - - // setup hash - // key = body ID - // value = index into N-length data structure - // n = count of unique bodies my atoms are part of - - n = 0; - for (i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - if (hash->find(bodyid[i]) == hash->end()) (*hash)[bodyid[i]] = n++; - } - - // bbox = bounding box of each rigid body my atoms are part of - - memory->create(bbox,n,6,"rigid/small:bbox"); - - for (i = 0; i < n; i++) { - bbox[i][0] = bbox[i][2] = bbox[i][4] = BIG; - bbox[i][1] = bbox[i][3] = bbox[i][5] = -BIG; - } + int *proclist; + memory->create(proclist,ncount,"rigid/small:proclist"); + InRvous *inbuf = (InRvous *) + memory->smalloc(ncount*sizeof(InRvous),"rigid/small:inbuf"); - // pack my atoms into buffer as body ID, unwrapped coords + // setup buf to pass to rendezvous comm + // one BodyMsg datum for each constituent atom + // datum = me, local index of atom, atomID, bodyID, unwrapped coords + // owning proc for each datum = random hash of bodyID double **x = atom->x; - - m = 0; - for (i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - domain->unmap(x[i],image[i],unwrap); - buf[m++] = bodyid[i]; - buf[m++] = unwrap[0]; - buf[m++] = unwrap[1]; - buf[m++] = unwrap[2]; - } - - // pass buffer around ring of procs - // func = update bbox with atom coords from every proc - // when done, have full bbox for every rigid body my atoms are part of - - comm->ring(m,sizeof(double),buf,1,ring_bbox,NULL,(void *)this); - - // check if any bbox is size 0.0, meaning rigid body is a single particle - - flag = 0; - for (i = 0; i < n; i++) - if (bbox[i][0] == bbox[i][1] && bbox[i][2] == bbox[i][3] && - bbox[i][4] == bbox[i][5]) flag = 1; - MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - if (flagall) - error->all(FLERR,"One or more rigid bodies are a single particle"); - - // ctr = center pt of each rigid body my atoms are part of - - memory->create(ctr,n,6,"rigid/small:bbox"); - - for (i = 0; i < n; i++) { - ctr[i][0] = 0.5 * (bbox[i][0] + bbox[i][1]); - ctr[i][1] = 0.5 * (bbox[i][2] + bbox[i][3]); - ctr[i][2] = 0.5 * (bbox[i][4] + bbox[i][5]); - } - - // idclose = ID of atom in body closest to center pt (smaller ID if tied) - // rsqclose = distance squared from idclose to center pt - - memory->create(idclose,n,"rigid/small:idclose"); - memory->create(rsqclose,n,"rigid/small:rsqclose"); - - for (i = 0; i < n; i++) rsqclose[i] = BIG; - - // pack my atoms into buffer as body ID, atom ID, unwrapped coords - tagint *tag = atom->tag; + imageint *image = atom->image; m = 0; for (i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; - domain->unmap(x[i],image[i],unwrap); - buf[m++] = bodyid[i]; - buf[m++] = ubuf(tag[i]).d; - buf[m++] = unwrap[0]; - buf[m++] = unwrap[1]; - buf[m++] = unwrap[2]; + proclist[m] = hashlittle(&bodyID[i],sizeof(tagint),0) % nprocs; + inbuf[m].me = me; + inbuf[m].ilocal = i; + inbuf[m].atomID = tag[i]; + inbuf[m].bodyID = bodyID[i]; + domain->unmap(x[i],image[i],inbuf[m].x); + m++; } - // pass buffer around ring of procs - // func = update idclose,rsqclose with atom IDs from every proc - // when done, have idclose for every rigid body my atoms are part of - - comm->ring(m,sizeof(double),buf,2,ring_nearest,NULL,(void *)this); + // perform rendezvous operation + // each proc owns random subset of bodies, receives all atoms in the bodies + // func = compute bbox of each body, flag atom closest to geometric center + // when done: each atom has atom ID of owning atom of its body - // set bodytag of all owned atoms, based on idclose - // find max value of rsqclose across all procs - - double rsqmax = 0.0; - for (i = 0; i < nlocal; i++) { - bodytag[i] = 0; - if (!(mask[i] & groupbit)) continue; - m = hash->find(bodyid[i])->second; - bodytag[i] = idclose[m]; - rsqmax = MAX(rsqmax,rsqclose[m]); - } + char *buf; + int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), + rendezvous_body,buf,sizeof(OutRvous), + (void *) this); + OutRvous *outbuf = (OutRvous *) buf; + + memory->destroy(proclist); + memory->sfree(inbuf); - // pack my atoms into buffer as bodytag of owning atom, unwrapped coords + // set bodytag of all owned atoms based on outbuf info for constituent atoms - m = 0; - for (i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - domain->unmap(x[i],image[i],unwrap); - buf[m++] = ubuf(bodytag[i]).d; - buf[m++] = unwrap[0]; - buf[m++] = unwrap[1]; - buf[m++] = unwrap[2]; - } + for (i = 0; i < nlocal; i++) + if (!(mask[i] & groupbit)) bodytag[i] = 0; - // pass buffer around ring of procs - // func = update rsqfar for atoms belonging to bodies I own - // when done, have rsqfar for all atoms in bodies I own + for (m = 0; m < nreturn; m++) + bodytag[outbuf[m].ilocal] = outbuf[m].atomID; - rsqfar = 0.0; - comm->ring(m,sizeof(double),buf,3,ring_farthest,NULL,(void *)this); + memory->sfree(outbuf); - // find maxextent of rsqfar across all procs + // maxextent = max of rsqfar across all procs // if defined, include molecule->maxextent MPI_Allreduce(&rsqfar,&maxextent,1,MPI_DOUBLE,MPI_MAX,world); @@ -1691,125 +1603,151 @@ void FixRigidSmall::create_bodies(tagint *bodyid) for (int i = 0; i < nmol; i++) maxextent = MAX(maxextent,onemols[i]->maxextent); } - - // clean up - - delete hash; - memory->destroy(buf); - memory->destroy(bbox); - memory->destroy(ctr); - memory->destroy(idclose); - memory->destroy(rsqclose); } /* ---------------------------------------------------------------------- - process rigid body atoms from another proc - update bounding box for rigid bodies my atoms are part of + process rigid bodies assigned to me + buf = list of N BodyMsg datums ------------------------------------------------------------------------- */ -void FixRigidSmall::ring_bbox(int n, char *cbuf, void *ptr) +int FixRigidSmall::rendezvous_body(int n, char *inbuf, + int *&proclist, char *&outbuf, + void *ptr) { + int i,j,m; + double delx,dely,delz,rsq; + int *iclose; + tagint *idclose; + double *x,*xown,*rsqclose; + double **bbox,**ctr; + FixRigidSmall *frsptr = (FixRigidSmall *) ptr; - std::map *hash = frsptr->hash; - double **bbox = frsptr->bbox; + Memory *memory = frsptr->memory; + Error *error = frsptr->error; + MPI_Comm world = frsptr->world; + + // setup hash + // ncount = number of bodies assigned to me + // key = body ID + // value = index into Ncount-length data structure + + InRvous *in = (InRvous *) inbuf; + std::map hash; + tagint id; + + int ncount = 0; + for (i = 0; i < n; i++) { + id = in[i].bodyID; + if (hash.find(id) == hash.end()) hash[id] = ncount++; + } - double *buf = (double *) cbuf; - int ndatums = n/4; + // bbox = bounding box of each rigid body - int j,imol; - double *x; + memory->create(bbox,ncount,6,"rigid/small:bbox"); - int m = 0; - for (int i = 0; i < ndatums; i++, m += 4) { - imol = static_cast (buf[m]); - if (hash->find(imol) != hash->end()) { - j = hash->find(imol)->second; - x = &buf[m+1]; - bbox[j][0] = MIN(bbox[j][0],x[0]); - bbox[j][1] = MAX(bbox[j][1],x[0]); - bbox[j][2] = MIN(bbox[j][2],x[1]); - bbox[j][3] = MAX(bbox[j][3],x[1]); - bbox[j][4] = MIN(bbox[j][4],x[2]); - bbox[j][5] = MAX(bbox[j][5],x[2]); - } + for (m = 0; m < ncount; m++) { + bbox[m][0] = bbox[m][2] = bbox[m][4] = BIG; + bbox[m][1] = bbox[m][3] = bbox[m][5] = -BIG; } -} -/* ---------------------------------------------------------------------- - process rigid body atoms from another proc - update nearest atom to body center for rigid bodies my atoms are part of -------------------------------------------------------------------------- */ + for (i = 0; i < n; i++) { + m = hash.find(in[i].bodyID)->second; + x = in[i].x; + bbox[m][0] = MIN(bbox[m][0],x[0]); + bbox[m][1] = MAX(bbox[m][1],x[0]); + bbox[m][2] = MIN(bbox[m][2],x[1]); + bbox[m][3] = MAX(bbox[m][3],x[1]); + bbox[m][4] = MIN(bbox[m][4],x[2]); + bbox[m][5] = MAX(bbox[m][5],x[2]); + } -void FixRigidSmall::ring_nearest(int n, char *cbuf, void *ptr) -{ - FixRigidSmall *frsptr = (FixRigidSmall *) ptr; - std::map *hash = frsptr->hash; - double **ctr = frsptr->ctr; - tagint *idclose = frsptr->idclose; - double *rsqclose = frsptr->rsqclose; + // check if any bbox is size 0.0, meaning rigid body is a single particle + + int flag = 0; + for (m = 0; m < ncount; m++) + if (bbox[m][0] == bbox[m][1] && bbox[m][2] == bbox[m][3] && + bbox[m][4] == bbox[m][5]) flag = 1; + int flagall; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); // sync here? + if (flagall) + error->all(FLERR,"One or more rigid bodies are a single particle"); - double *buf = (double *) cbuf; - int ndatums = n/5; + // ctr = geometric center pt of each rigid body - int j,imol; - tagint tag; - double delx,dely,delz,rsq; - double *x; + memory->create(ctr,ncount,3,"rigid/small:bbox"); - int m = 0; - for (int i = 0; i < ndatums; i++, m += 5) { - imol = static_cast (buf[m]); - if (hash->find(imol) != hash->end()) { - j = hash->find(imol)->second; - tag = (tagint) ubuf(buf[m+1]).i; - x = &buf[m+2]; - delx = x[0] - ctr[j][0]; - dely = x[1] - ctr[j][1]; - delz = x[2] - ctr[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= rsqclose[j]) { - if (rsq == rsqclose[j] && tag > idclose[j]) continue; - idclose[j] = tag; - rsqclose[j] = rsq; - } - } + for (m = 0; m < ncount; m++) { + ctr[m][0] = 0.5 * (bbox[m][0] + bbox[m][1]); + ctr[m][1] = 0.5 * (bbox[m][2] + bbox[m][3]); + ctr[m][2] = 0.5 * (bbox[m][4] + bbox[m][5]); } -} -/* ---------------------------------------------------------------------- - process rigid body atoms from another proc - update rsqfar = distance from owning atom to other atom -------------------------------------------------------------------------- */ + // idclose = atomID closest to center point of each body -void FixRigidSmall::ring_farthest(int n, char *cbuf, void *ptr) -{ - FixRigidSmall *frsptr = (FixRigidSmall *) ptr; - double **x = frsptr->atom->x; - imageint *image = frsptr->atom->image; - int nlocal = frsptr->atom->nlocal; + memory->create(idclose,ncount,"rigid/small:idclose"); + memory->create(iclose,ncount,"rigid/small:iclose"); + memory->create(rsqclose,ncount,"rigid/small:rsqclose"); + for (m = 0; m < ncount; m++) rsqclose[m] = BIG; + + for (i = 0; i < n; i++) { + m = hash.find(in[i].bodyID)->second; + x = in[i].x; + delx = x[0] - ctr[m][0]; + dely = x[1] - ctr[m][1]; + delz = x[2] - ctr[m][2]; + rsq = delx*delx + dely*dely + delz*delz; + if (rsq <= rsqclose[m]) { + if (rsq == rsqclose[m] && in[i].atomID > idclose[m]) continue; + iclose[m] = i; + idclose[m] = in[i].atomID; + rsqclose[m] = rsq; + } + } + + // compute rsqfar for all bodies I own + // set rsqfar back in caller + + double rsqfar = 0.0; + + for (int i = 0; i < n; i++) { + m = hash.find(in[i].bodyID)->second; + xown = in[iclose[m]].x; + x = in[i].x; + delx = x[0] - xown[0]; + dely = x[1] - xown[1]; + delz = x[2] - xown[2]; + rsq = delx*delx + dely*dely + delz*delz; + rsqfar = MAX(rsqfar,rsq); + } - double *buf = (double *) cbuf; - int ndatums = n/4; + frsptr->rsqfar = rsqfar; - int iowner; - tagint tag; - double delx,dely,delz,rsq; - double *xx; - double unwrap[3]; + // pass list of OutRvous datums back to comm->rendezvous - int m = 0; - for (int i = 0; i < ndatums; i++, m += 4) { - tag = (tagint) ubuf(buf[m]).i; - iowner = frsptr->atom->map(tag); - if (iowner < 0 || iowner >= nlocal) continue; - frsptr->domain->unmap(x[iowner],image[iowner],unwrap); - xx = &buf[m+1]; - delx = xx[0] - unwrap[0]; - dely = xx[1] - unwrap[1]; - delz = xx[2] - unwrap[2]; - rsq = delx*delx + dely*dely + delz*delz; - frsptr->rsqfar = MAX(frsptr->rsqfar,rsq); + int nout = n; + memory->create(proclist,nout,"rigid/small:proclist"); + OutRvous *out = (OutRvous *) + memory->smalloc(nout*sizeof(OutRvous),"rigid/small:out"); + + for (int i = 0; i < nout; i++) { + proclist[i] = in[i].me; + out[i].ilocal = in[i].ilocal; + m = hash.find(in[i].bodyID)->second; + out[i].atomID = idclose[m]; } + + outbuf = (char *) out; + + // clean up + // Comm::rendezvous will delete proclist and out (outbuf) + + memory->destroy(bbox); + memory->destroy(ctr); + memory->destroy(idclose); + memory->destroy(iclose); + memory->destroy(rsqclose); + + return nout; } /* ---------------------------------------------------------------------- @@ -2472,9 +2410,9 @@ void FixRigidSmall::readfile(int which, double **array, int *inbody) int nlocal = atom->nlocal; - hash = new std::map(); + std::map hash; for (i = 0; i < nlocal; i++) - if (bodyown[i] >= 0) (*hash)[atom->molecule[i]] = bodyown[i]; + if (bodyown[i] >= 0) hash[atom->molecule[i]] = bodyown[i]; // open file and read header @@ -2533,11 +2471,11 @@ void FixRigidSmall::readfile(int which, double **array, int *inbody) id = ATOTAGINT(values[0]); if (id <= 0 || id > maxmol) error->all(FLERR,"Invalid rigid body ID in fix rigid/small file"); - if (hash->find(id) == hash->end()) { + if (hash.find(id) == hash.end()) { buf = next + 1; continue; } - m = (*hash)[id]; + m = hash[id]; inbody[m] = 1; if (which == 0) { @@ -2576,7 +2514,6 @@ void FixRigidSmall::readfile(int which, double **array, int *inbody) delete [] buffer; delete [] values; - delete hash; } /* ---------------------------------------------------------------------- diff --git a/src/RIGID/fix_rigid_small.h b/src/RIGID/fix_rigid_small.h index 3f6826f9bb..a820efcdea 100644 --- a/src/RIGID/fix_rigid_small.h +++ b/src/RIGID/fix_rigid_small.h @@ -23,7 +23,7 @@ FixStyle(rigid/small,FixRigidSmall) #include "fix.h" // replace this later -#include +//#include namespace LAMMPS_NS { @@ -180,13 +180,21 @@ class FixRigidSmall : public Fix { // class data used by ring communication callbacks - std::map *hash; - double **bbox; - double **ctr; - tagint *idclose; - double *rsqclose; double rsqfar; + struct InRvous { + int me,ilocal; + tagint atomID,bodyID; + double x[3]; + }; + + struct OutRvous { + int ilocal; + tagint atomID; + }; + + // local methods + void image_shift(); void set_xv(); void set_v(); @@ -199,11 +207,9 @@ class FixRigidSmall : public Fix { void grow_body(); void reset_atom2body(); - // callback functions for ring communication + // callback function for rendezvous communication - static void ring_bbox(int, char *, void *); - static void ring_nearest(int, char *, void *); - static void ring_farthest(int, char *, void *); + static int rendezvous_body(int, char *, int *&, char *&, void *); // debug diff --git a/src/comm.cpp b/src/comm.cpp index f355a562fc..5fcfa141d0 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -28,6 +28,7 @@ #include "dump.h" #include "group.h" #include "procmap.h" +#include "irregular.h" #include "accelerator_kokkos.h" #include "memory.h" #include "error.h" @@ -725,6 +726,56 @@ void Comm::ring(int n, int nper, void *inbuf, int messtag, memory->destroy(bufcopy); } +/* ---------------------------------------------------------------------- + rendezvous communication operation +------------------------------------------------------------------------- */ + +int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, + int (*callback)(int, char *, int *&, char *&, void *), + char *&outbuf, int outsize, void *ptr) +{ + // comm data from caller decomposition to rendezvous decomposition + + Irregular *irregular = new Irregular(lmp); + + int n_rvous = irregular->create_data(n,proclist); // add sort + char *inbuf_rvous = (char *) memory->smalloc((bigint) n_rvous*insize, + "rendezvous:inbuf_rvous"); + irregular->exchange_data(inbuf,insize,inbuf_rvous); + + irregular->destroy_data(); + delete irregular; + + // peform rendezvous computation via callback() + // callback() allocates proclist_rvous and outbuf_rvous + + int *proclist_rvous; + char *outbuf_rvous; + + int nout_rvous = + callback(n_rvous,inbuf_rvous,proclist_rvous,outbuf_rvous,ptr); + + memory->sfree(inbuf_rvous); + + // comm data from rendezvous decomposition back to caller + // caller will free outbuf + + irregular = new Irregular(lmp); + + int nout = irregular->create_data(nout_rvous,proclist_rvous); + outbuf = (char *) memory->smalloc((bigint) nout*outsize,"rendezvous:outbuf"); + irregular->exchange_data(outbuf_rvous,outsize,outbuf); + + irregular->destroy_data(); + delete irregular; + memory->destroy(proclist_rvous); + memory->sfree(outbuf_rvous); + + // return number of datums + + return nout; +} + /* ---------------------------------------------------------------------- proc 0 reads Nlines from file into buf and bcasts buf to all procs caller allocates buf to max size needed diff --git a/src/comm.h b/src/comm.h index 2579f9b283..8bb057a0c1 100644 --- a/src/comm.h +++ b/src/comm.h @@ -109,6 +109,10 @@ class Comm : protected Pointers { void ring(int, int, void *, int, void (*)(int, char *, void *), void *, void *, int self = 1); + int rendezvous(int, int *, char *, int, + int (*)(int, char *, int *&, char *&, void *), + char *&, int, void *); + int read_lines_from_file(FILE *, int, int, char *); int read_lines_from_file_universe(FILE *, int, int, char *); diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp index 383c60f1cd..ecbf612f70 100644 --- a/src/create_atoms.cpp +++ b/src/create_atoms.cpp @@ -513,9 +513,6 @@ void CreateAtoms::command(int narg, char **arg) if (domain->triclinic) domain->lamda2x(atom->nlocal); } - MPI_Barrier(world); - double time2 = MPI_Wtime(); - // clean up delete ranmol; @@ -525,30 +522,34 @@ void CreateAtoms::command(int narg, char **arg) delete [] ystr; delete [] zstr; + // for MOLECULE mode: + // create special bond lists for molecular systems, + // but not for atom style template + // only if onemol added bonds but not special info + + if (mode == MOLECULE) { + if (atom->molecular == 1 && onemol->bondflag && !onemol->specialflag) { + Special special(lmp); + special.build(); + + } + } + // print status + MPI_Barrier(world); + double time2 = MPI_Wtime(); + if (comm->me == 0) { if (screen) { fprintf(screen,"Created " BIGINT_FORMAT " atoms\n", atom->natoms-natoms_previous); - fprintf(screen," Time spent = %g secs\n",time2-time1); + fprintf(screen," create_atoms CPU = %g secs\n",time2-time1); } if (logfile) { fprintf(logfile,"Created " BIGINT_FORMAT " atoms\n", atom->natoms-natoms_previous); - fprintf(logfile," Time spent = %g secs\n",time2-time1); - } - } - - // for MOLECULE mode: - // create special bond lists for molecular systems, - // but not for atom style template - // only if onemol added bonds but not special info - - if (mode == MOLECULE) { - if (atom->molecular == 1 && onemol->bondflag && !onemol->specialflag) { - Special special(lmp); - special.build(); + fprintf(logfile," create_atoms CPU = %g secs\n",time2-time1); } } } diff --git a/src/hashlittle.cpp b/src/hashlittle.cpp new file mode 100644 index 0000000000..be930217a1 --- /dev/null +++ b/src/hashlittle.cpp @@ -0,0 +1,333 @@ +// Hash function hashlittle() +// from lookup3.c, by Bob Jenkins, May 2006, Public Domain +// bob_jenkins@burtleburtle.net + +#include "stddef.h" +#include "stdint.h" + +#define HASH_LITTLE_ENDIAN 1 // Intel and AMD are little endian + +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; + +#else /* PURIFY_HATES_HASHLITTLE */ +/* I don't know what it is about Jenkins' hashlittle function, but + * it drives purify insane, even with VALGRIND defined. It makes + * purify unusable!! The code execution doesn't even make sense. + * Below is a (probably) weaker hash function that at least allows + * testing with purify. + */ +#define MAXINT_DIV_PHI 11400714819323198485U + + uint32_t h, rest, *p, bytes, num_bytes; + char *byteptr; + + num_bytes = length; + + /* First hash the uint32_t-sized portions of the key */ + h = 0; + for (p = (uint32_t *)key, bytes=num_bytes; + bytes >= (uint32_t) sizeof(uint32_t); + bytes-=sizeof(uint32_t), p++){ + h = (h^(*p))*MAXINT_DIV_PHI; + } + + /* Then take care of the remaining bytes, if any */ + rest = 0; + for (byteptr = (char *)p; bytes > 0; bytes--, byteptr++){ + rest = (rest<<8) | (*byteptr); + } + + /* If extra bytes, merge the two parts */ + if (rest) + h = (h^rest)*MAXINT_DIV_PHI; + + return h; +#endif /* PURIFY_HATES_HASHLITTLE */ +} diff --git a/src/hashlittle.h b/src/hashlittle.h new file mode 100644 index 0000000000..7b57a35c80 --- /dev/null +++ b/src/hashlittle.h @@ -0,0 +1,5 @@ +// Hash function hashlittle() +// from lookup3.c, by Bob Jenkins, May 2006, Public Domain +// bob_jenkins@burtleburtle.net + +uint32_t hashlittle(const void *key, size_t length, uint32_t); diff --git a/src/irregular.cpp b/src/irregular.cpp index 9c15f135d0..60025249cf 100644 --- a/src/irregular.cpp +++ b/src/irregular.cpp @@ -501,7 +501,8 @@ int compare_standalone(const int i, const int j, void *ptr) void Irregular::exchange_atom(double *sendbuf, int *sizes, double *recvbuf) { - int i,m,n,offset,count; + int i,m,n,count; + bigint offset; // post all receives @@ -739,11 +740,13 @@ int Irregular::create_data(int n, int *proclist, int sortflag) void Irregular::exchange_data(char *sendbuf, int nbytes, char *recvbuf) { - int i,m,n,offset,count; + int i,n,count; + bigint m; // these 2 lines enable send/recv buf to be larger than 2 GB + char *dest; // post all receives, starting after self copies - offset = num_self*nbytes; + bigint offset = num_self*nbytes; for (int irecv = 0; irecv < nrecv_proc; irecv++) { MPI_Irecv(&recvbuf[offset],num_recv[irecv]*nbytes,MPI_CHAR, proc_recv[irecv],0,world,&request[irecv]); @@ -765,18 +768,22 @@ void Irregular::exchange_data(char *sendbuf, int nbytes, char *recvbuf) n = 0; for (int isend = 0; isend < nsend_proc; isend++) { count = num_send[isend]; + dest = buf; for (i = 0; i < count; i++) { m = index_send[n++]; - memcpy(&buf[i*nbytes],&sendbuf[m*nbytes],nbytes); + memcpy(dest,&sendbuf[m*nbytes],nbytes); + dest += nbytes; } MPI_Send(buf,count*nbytes,MPI_CHAR,proc_send[isend],0,world); } // copy datums to self, put at beginning of recvbuf + dest = recvbuf; for (i = 0; i < num_self; i++) { m = index_self[i]; - memcpy(&recvbuf[i*nbytes],&sendbuf[m*nbytes],nbytes); + memcpy(dest,&sendbuf[m*nbytes],nbytes); + dest += nbytes; } // wait on all incoming messages diff --git a/src/read_data.cpp b/src/read_data.cpp index 373ba30151..d7bd298e7b 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -120,6 +120,9 @@ void ReadData::command(int narg, char **arg) { if (narg < 1) error->all(FLERR,"Illegal read_data command"); + MPI_Barrier(world); + double time1 = MPI_Wtime; + // optional args addflag = NONE; @@ -905,6 +908,18 @@ void ReadData::command(int narg, char **arg) force->kspace = saved_kspace; } + + // total time + + MPI_Barrier(world); + double time2 = MPI_Wtime; + + if (comm->me == 0) { + if (screen) + fprintf(screen," read_atoms CPU = %g secs\n",time2-time1); + if (logfile) + fprintf(logfile," read_atoms CPU = %g secs\n",time2-time1); + } } /* ---------------------------------------------------------------------- diff --git a/src/read_restart.cpp b/src/read_restart.cpp index 82028d8316..a338a843d7 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -81,6 +81,9 @@ void ReadRestart::command(int narg, char **arg) if (domain->box_exist) error->all(FLERR,"Cannot read_restart after simulation box is defined"); + MPI_Barrier(world); + double time1 = MPI_Wtime; + MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); @@ -562,6 +565,18 @@ void ReadRestart::command(int narg, char **arg) Special special(lmp); special.build(); } + + // total time + + MPI_Barrier(world); + double time2 = MPI_Wtime; + + if (comm->me == 0) { + if (screen) + fprintf(screen," read_restart CPU = %g secs\n",time2-time1); + if (logfile) + fprintf(logfile," read_restart CPU = %g secs\n",time2-time1); + } } /* ---------------------------------------------------------------------- diff --git a/src/replicate.cpp b/src/replicate.cpp index cdadf1fd1f..3c8f4a8aee 100644 --- a/src/replicate.cpp +++ b/src/replicate.cpp @@ -76,7 +76,7 @@ void Replicate::command(int narg, char **arg) if (atom->nextra_grow || atom->nextra_restart || atom->nextra_store) error->all(FLERR,"Cannot replicate with fixes that store atom quantities"); - // Record wall time for atom replication + // record wall time for atom replication MPI_Barrier(world); double time1 = MPI_Wtime(); @@ -762,15 +762,15 @@ void Replicate::command(int narg, char **arg) special.build(); } - // Wall time + // total time MPI_Barrier(world); double time2 = MPI_Wtime(); if (me == 0) { if (screen) - fprintf(screen," Time spent = %g secs\n",time2-time1); + fprintf(screen," replicate CPU = %g secs\n",time2-time1); if (logfile) - fprintf(logfile," Time spent = %g secs\n",time2-time1); + fprintf(logfile," replicate CPU = %g secs\n",time2-time1); } } diff --git a/src/special.cpp b/src/special.cpp index fccc930353..a18c597765 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -21,9 +21,10 @@ #include "modify.h" #include "fix.h" #include "accelerator_kokkos.h" +#include "hashlittle.h" +#include "atom_masks.h" #include "memory.h" #include "error.h" -#include "atom_masks.h" using namespace LAMMPS_NS; @@ -54,11 +55,12 @@ Special::~Special() void Special::build() { - int i,j,k,size; - int max,maxall,nbuf; - tagint *buf; + int i,j,k,m,n,size,proc; + int max,maxall; + char *buf; MPI_Barrier(world); + double time1 = MPI_Wtime(); int nlocal = atom->nlocal; @@ -87,99 +89,88 @@ void Special::build() // ----------------------------------------------------- // compute nspecial[i][0] = # of 1-2 neighbors of atom i + // create onetwo[i] = list of 1-2 neighbors for atom i // ----------------------------------------------------- - // bond partners stored by atom itself - - for (i = 0; i < nlocal; i++) nspecial[i][0] = num_bond[i]; - - // if newton_bond off, then done - // else only counted 1/2 of all bonds, so count other half - - if (force->newton_bond) { + // ncount = # of my datums to send (newton or newton off) + // include nlocal datums with owner of each atom - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = global tag of 2nd atom in each bond + int newton_bond = force->newton_bond; - nbuf = 0; - for (i = 0; i < nlocal; i++) nbuf += num_bond[i]; - memory->create(buf,nbuf,"special:buf"); + int ncount = 0; + for (i = 0; i < nlocal; i++) ncount += num_bond[i]; + if (newton_bond) ncount *= 2; + ncount += nlocal; - // fill buffer with global tags of bond partners of my atoms + int *proclist; + memory->create(proclist,ncount,"special:proclist"); + InRvous *inbuf = (InRvous *) + memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); - size = 0; - for (i = 0; i < nlocal; i++) - for (j = 0; j < num_bond[i]; j++) - buf[size++] = bond_atom[i][j]; + // setup input buf to rendezvous comm + // one datum for each owned atom: datum = proc, atomID + // one datum for each bond partner: datum = atomID, bond partner ID + // owning proc for each datum = random hash of atomID - // cycle buffer around ring of procs back to self - // when receive buffer, scan tags for atoms I own - // when find one, increment nspecial count for that atom - - comm->ring(size,sizeof(tagint),buf,1,ring_one,NULL,(void *)this); - - memory->destroy(buf); + m = 0; + for (i = 0; i < nlocal; i++) { + proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; + proclist[m] = proc; + inbuf[m].me = me; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = 0; + m++; + + for (j = 0; j < num_bond[i]; j++) { + proclist[m] = proc; + inbuf[m].me = -1; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = bond_atom[i][j]; + m++; + } + if (newton_bond) { + for (j = 0; j < num_bond[i]; j++) { + proclist[m] = hashlittle(&bond_atom[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -1; + inbuf[m].atomID = bond_atom[i][j]; + inbuf[m].partnerID = tag[i]; + m++; + } + } } - // ---------------------------------------------------- - // create onetwo[i] = list of 1-2 neighbors for atom i - // ---------------------------------------------------- + // perform rendezvous operation + // each proc owns random subset of atoms, receives all their bond partners - max = 0; - for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][0]); + int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), + rendezvous_1234, + buf,sizeof(OutRvous),(void *) this); + OutRvous *outbuf = (OutRvous *) buf; - MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + memory->destroy(proclist); + memory->sfree(inbuf); - if (me == 0) { - if (screen) fprintf(screen," %d = max # of 1-2 neighbors\n",maxall); - if (logfile) fprintf(logfile," %d = max # of 1-2 neighbors\n",maxall); - } + // set nspecial[0] and onetwo for all owned atoms based on output info + MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onetwo,nlocal,maxall,"special:onetwo"); - // count = accumulating counter - - memory->create(count,nlocal,"special:count"); - for (i = 0; i < nlocal; i++) count[i] = 0; - - // add bond partners stored by atom to onetwo list - - for (i = 0; i < nlocal; i++) - for (j = 0; j < num_bond[i]; j++) - onetwo[i][count[i]++] = bond_atom[i][j]; + for (i = 0; i < nlocal; i++) nspecial[i][0] = 0; - // if newton_bond off, then done - // else only stored 1/2 of all bonds, so store other half - - if (force->newton_bond) { - - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = 2 global tags in each bond - - nbuf = 0; - for (i = 0; i < nlocal; i++) nbuf += 2*num_bond[i]; - memory->create(buf,nbuf,"special:buf"); - - // fill buffer with global tags of both atoms in bond - - size = 0; - for (i = 0; i < nlocal; i++) - for (j = 0; j < num_bond[i]; j++) { - buf[size++] = tag[i]; - buf[size++] = bond_atom[i][j]; - } + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + onetwo[i][nspecial[i][0]++] = outbuf[m].partnerID; + } - // cycle buffer around ring of procs back to self - // when receive buffer, scan 2nd-atom tags for atoms I own - // when find one, add 1st-atom tag to onetwo list for 2nd atom + memory->sfree(outbuf); - comm->ring(size,sizeof(tagint),buf,2,ring_two,NULL,(void *)this); + // compute and print max # of 1-2 neighbors - memory->destroy(buf); + if (me == 0) { + if (screen) fprintf(screen," %d = max # of 1-2 neighbors\n",maxall); + if (logfile) fprintf(logfile," %d = max # of 1-2 neighbors\n",maxall); } - memory->destroy(count); - // ----------------------------------------------------- // done if special_bond weights for 1-3, 1-4 are set to 1.0 // ----------------------------------------------------- @@ -189,114 +180,83 @@ void Special::build() dedup(); combine(); fix_alteration(); + timer_output(time1); return; } // ----------------------------------------------------- // compute nspecial[i][1] = # of 1-3 neighbors of atom i + // create onethree[i] = list of 1-3 neighbors for atom i // ----------------------------------------------------- - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = 2 scalars + list of 1-2 neighbors - - nbuf = 0; - for (i = 0; i < nlocal; i++) nbuf += 2 + nspecial[i][0]; - memory->create(buf,nbuf,"special:buf"); - - // fill buffer with: - // (1) = counter for 1-3 neighbors, initialized to 0 - // (2) = # of 1-2 neighbors - // (3:N) = list of 1-2 neighbors - - size = 0; - for (i = 0; i < nlocal; i++) { - buf[size++] = 0; - buf[size++] = nspecial[i][0]; - for (j = 0; j < nspecial[i][0]; j++) buf[size++] = onetwo[i][j]; - } + // ncount = # of my datums to send + // include nlocal datums with owner of each atom - // cycle buffer around ring of procs back to self - // when receive buffer, scan list of 1-2 neighbors for atoms I own - // when find one, increment 1-3 count by # of 1-2 neighbors of my atom, - // subtracting one since my list will contain original atom + ncount = nlocal; + for (i = 0; i < nlocal; i++) ncount += nspecial[i][0]*(nspecial[i][0]-1); - comm->ring(size,sizeof(tagint),buf,3,ring_three,buf,(void *)this); + memory->create(proclist,ncount,"special:proclist"); + inbuf = (InRvous *) + memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); - // extract count from buffer that has cycled back to me - // nspecial[i][1] = # of 1-3 neighbors of atom i + // setup input buf to rendezvous comm + // one datum for each owned atom: datum = proc, atomID + // one datum for each bond partner: datum = atomID, bond partner ID + // owning proc for each datum = random hash of atomID - j = 0; + m = 0; for (i = 0; i < nlocal; i++) { - nspecial[i][1] = buf[j]; - j += 2 + nspecial[i][0]; + proclist[m] = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; + inbuf[m].me = me; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = 0; + m++; + + for (j = 0; j < nspecial[i][0]; j++) { + proc = hashlittle(&onetwo[i][j],sizeof(tagint),0) % nprocs; + for (k = 0; k < nspecial[i][0]; k++) { + if (j == k) continue; + proclist[m] = proc; + inbuf[m].me = -1; + inbuf[m].atomID = onetwo[i][j]; + inbuf[m].partnerID = onetwo[i][k]; + m++; + } + } } - memory->destroy(buf); + // perform rendezvous operation + // each proc owns random subset of atoms, receives all their bond partners - // ---------------------------------------------------- - // create onethree[i] = list of 1-3 neighbors for atom i - // ---------------------------------------------------- + nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), + rendezvous_1234, + buf,sizeof(OutRvous),(void *) this); + outbuf = (OutRvous *) buf; - max = 0; - for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][1]); - MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + memory->destroy(proclist); + memory->sfree(inbuf); - if (me == 0) { - if (screen) fprintf(screen," %d = max # of 1-3 neighbors\n",maxall); - if (logfile) fprintf(logfile," %d = max # of 1-3 neighbors\n",maxall); - } + // set nspecial[1] and onethree for all owned atoms based on output info + MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onethree,nlocal,maxall,"special:onethree"); - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = 4 scalars + list of 1-2 neighs + list of 1-3 neighs + for (i = 0; i < nlocal; i++) nspecial[i][1] = 0; - nbuf = 0; - for (i = 0; i < nlocal; i++) nbuf += 4 + nspecial[i][0] + nspecial[i][1]; - memory->create(buf,nbuf,"special:buf"); - - // fill buffer with: - // (1) = global tag of original atom - // (2) = # of 1-2 neighbors - // (3) = # of 1-3 neighbors - // (4) = counter for 1-3 neighbors, initialized to 0 - // (5:N) = list of 1-2 neighbors - // (N+1:2N) space for list of 1-3 neighbors - - size = 0; - for (i = 0; i < nlocal; i++) { - buf[size++] = tag[i]; - buf[size++] = nspecial[i][0]; - buf[size++] = nspecial[i][1]; - buf[size++] = 0; - for (j = 0; j < nspecial[i][0]; j++) buf[size++] = onetwo[i][j]; - size += nspecial[i][1]; + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + onethree[i][nspecial[i][1]++] = outbuf[m].partnerID; } - // cycle buffer around ring of procs back to self - // when receive buffer, scan list of 1-2 neighbors for atoms I own - // when find one, add its neighbors to 1-3 list - // increment the count in buf(i+4) - // exclude the atom whose tag = original - // this process may include duplicates but they will be culled later + memory->destroy(outbuf); - comm->ring(size,sizeof(tagint),buf,4,ring_four,buf,(void *)this); + // compute and print max # of 1-3 neighbors - // fill onethree with buffer values that have been returned to me - // sanity check: accumulated buf[i+3] count should equal - // nspecial[i][1] for each atom - - j = 0; - for (i = 0; i < nlocal; i++) { - if (buf[j+3] != nspecial[i][1]) - 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++]; + if (me == 0) { + if (screen) fprintf(screen," %d = max # of 1-3 neighbors\n",maxall); + if (logfile) fprintf(logfile," %d = max # of 1-3 neighbors\n",maxall); } - memory->destroy(buf); - // done if special_bond weights for 1-4 are set to 1.0 if (force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { @@ -304,117 +264,92 @@ void Special::build() if (force->special_angle) angle_trim(); combine(); fix_alteration(); + timer_output(time1); return; } // ----------------------------------------------------- // compute nspecial[i][2] = # of 1-4 neighbors of atom i + // create onefour[i] = list of 1-4 neighbors for atom i // ----------------------------------------------------- - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = 2 scalars + list of 1-3 neighbors + // ncount = # of my datums to send + // include nlocal datums with owner of each atom - nbuf = 0; - for (i = 0; i < nlocal; i++) nbuf += 2 + nspecial[i][1]; - memory->create(buf,nbuf,"special:buf"); + ncount = nlocal; + for (i = 0; i < nlocal; i++) ncount += nspecial[i][1]*nspecial[i][0]; - // fill buffer with: - // (1) = counter for 1-4 neighbors, initialized to 0 - // (2) = # of 1-3 neighbors - // (3:N) = list of 1-3 neighbors + memory->create(proclist,ncount,"special:proclist"); + inbuf = (InRvous *) + memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); - size = 0; - for (i = 0; i < nlocal; i++) { - buf[size++] = 0; - buf[size++] = nspecial[i][1]; - for (j = 0; j < nspecial[i][1]; j++) buf[size++] = onethree[i][j]; - } + // setup input buf to rendezvous comm + // one datum for each owned atom: datum = proc, atomID + // one datum for each partner: datum = atomID, bond partner ID + // owning proc for each datum = random hash of atomID - // cycle buffer around ring of procs back to self - // when receive buffer, scan list of 1-3 neighbors for atoms I own - // when find one, increment 1-4 count by # of 1-2 neighbors of my atom - // may include duplicates and original atom but they will be culled later - - comm->ring(size,sizeof(tagint),buf,5,ring_five,buf,(void *)this); - - // extract count from buffer that has cycled back to me - // nspecial[i][2] = # of 1-4 neighbors of atom i - - j = 0; + m = 0; for (i = 0; i < nlocal; i++) { - nspecial[i][2] = buf[j]; - j += 2 + nspecial[i][1]; + proclist[m] = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; + inbuf[m].me = me; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = 0; + m++; + + for (j = 0; j < nspecial[i][1]; j++) { + proc = hashlittle(&onethree[i][j],sizeof(tagint),0) % nprocs; + for (k = 0; k < nspecial[i][0]; k++) { + proclist[m] = proc; + inbuf[m].me = -1; + inbuf[m].atomID = onethree[i][j]; + inbuf[m].partnerID = onetwo[i][k]; + m++; + } + } } - memory->destroy(buf); + // perform rendezvous operation + // each proc owns random subset of bodies, receives all atoms in the bodies + // func = compute bbox of each body, flag atom closest to geometric center + // when done: each atom has atom ID of owning atom of its body - // ---------------------------------------------------- - // create onefour[i] = list of 1-4 neighbors for atom i - // ---------------------------------------------------- + nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), + rendezvous_1234, + buf,sizeof(OutRvous),(void *) this); + outbuf = (OutRvous *) buf; - max = 0; - for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][2]); - MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + memory->destroy(proclist); + memory->sfree(inbuf); - if (me == 0) { - if (screen) fprintf(screen," %d = max # of 1-4 neighbors\n",maxall); - if (logfile) fprintf(logfile," %d = max # of 1-4 neighbors\n",maxall); - } + // set nspecial[2] and onefour for all owned atoms based on output info + MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onefour,nlocal,maxall,"special:onefour"); - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = 3 scalars + list of 1-3 neighs + list of 1-4 neighs - - nbuf = 0; - for (i = 0; i < nlocal; i++) - nbuf += 3 + nspecial[i][1] + nspecial[i][2]; - memory->create(buf,nbuf,"special:buf"); - - // fill buffer with: - // (1) = # of 1-3 neighbors - // (2) = # of 1-4 neighbors - // (3) = counter for 1-4 neighbors, initialized to 0 - // (4:N) = list of 1-3 neighbors - // (N+1:2N) space for list of 1-4 neighbors + for (i = 0; i < nlocal; i++) nspecial[i][2] = 0; - size = 0; - for (i = 0; i < nlocal; i++) { - buf[size++] = nspecial[i][1]; - buf[size++] = nspecial[i][2]; - buf[size++] = 0; - for (j = 0; j < nspecial[i][1]; j++) buf[size++] = onethree[i][j]; - size += nspecial[i][2]; + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + onefour[i][nspecial[i][2]++] = outbuf[m].partnerID; } - // cycle buffer around ring of procs back to self - // when receive buffer, scan list of 1-3 neighbors for atoms I own - // when find one, add its neighbors to 1-4 list - // incrementing the count in buf(i+4) - // this process may include duplicates but they will be culled later - - comm->ring(size,sizeof(tagint),buf,6,ring_six,buf,(void *)this); + memory->destroy(outbuf); - // fill onefour with buffer values that have been returned to me - // sanity check: accumulated buf[i+2] count should equal - // nspecial[i][2] for each atom + // compute and print max # of 1-4 neighbors - j = 0; - for (i = 0; i < nlocal; i++) { - if (buf[j+2] != nspecial[i][2]) - 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++]; + if (me == 0) { + if (screen) fprintf(screen," %d = max # of 1-4 neighbors\n",maxall); + if (logfile) fprintf(logfile," %d = max # of 1-4 neighbors\n",maxall); } - memory->destroy(buf); + // finish processing the onetwo, onethree, onefour lists dedup(); if (force->special_angle) angle_trim(); if (force->special_dihedral) dihedral_trim(); combine(); fix_alteration(); + timer_output(time1); } /* ---------------------------------------------------------------------- @@ -663,17 +598,19 @@ void Special::combine() void Special::angle_trim() { - int i,j,m,n; + int i,j,m,n,proc,index; int *num_angle = atom->num_angle; int *num_dihedral = atom->num_dihedral; tagint **angle_atom1 = atom->angle_atom1; + tagint **angle_atom2 = atom->angle_atom2; tagint **angle_atom3 = atom->angle_atom3; tagint **dihedral_atom1 = atom->dihedral_atom1; tagint **dihedral_atom2 = atom->dihedral_atom2; tagint **dihedral_atom3 = atom->dihedral_atom3; tagint **dihedral_atom4 = atom->dihedral_atom4; int **nspecial = atom->nspecial; + tagint *tag = atom->tag; int nlocal = atom->nlocal; // stats on old 1-3 neighbor counts @@ -697,68 +634,125 @@ void Special::angle_trim() if ((num_angle && atom->nangles) || (num_dihedral && atom->ndihedrals)) { - // dflag = flag for 1-3 neighs of all owned atoms - - int maxcount = 0; - for (i = 0; i < nlocal; i++) maxcount = MAX(maxcount,nspecial[i][1]); - memory->create(dflag,nlocal,maxcount,"special::dflag"); + // ncount = # of my datums to send in 3 parts for each owned atom + // proc owner, onethree list, angle end points + // angle end points are from angle list and 1-3 and 2-4 pairs in dihedrals + // latter is only for angles or dihedrlas where I own atom2 + int ncount = nlocal; + for (i = 0; i < nlocal; i++) ncount += nspecial[i][1]; for (i = 0; i < nlocal; i++) { - n = nspecial[i][1]; - for (j = 0; j < n; j++) dflag[i][j] = 0; + for (j = 0; j < num_angle[i]; j++) { + index = atom->map(angle_atom2[i][j]); + if (index >= 0 && index < nlocal) ncount += 2; + } + for (j = 0; j < num_dihedral[i]; j++) { + index = atom->map(dihedral_atom2[i][j]); + if (index >= 0 && index < nlocal) ncount += 4; + } } - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = list of 1,3 atoms in each angle stored by atom - // and list of 1,3 and 2,4 atoms in each dihedral stored by atom + int *proclist; + memory->create(proclist,ncount,"special:proclist"); + InRvous *inbuf = (InRvous *) + memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); - int nbuf = 0; + // setup input buf to rendezvous comm + // one datum for each owned atom: datum = proc, atomID + // sent to owner of atomID + // one datum for each 1-4 partner: datum = atomID, ID + // sent to owner of atomID + // two datums for each dihedral 1-4 endatoms : datum = atomID, ID + // sent to owner of atomID + + m = 0; for (i = 0; i < nlocal; i++) { - if (num_angle && atom->nangles) nbuf += 2*num_angle[i]; - if (num_dihedral && atom->ndihedrals) nbuf += 2*2*num_dihedral[i]; - } - int *buf; - memory->create(buf,nbuf,"special:buf"); + proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; + proclist[m] = proc; + inbuf[m].me = me; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = 0; + m++; + + for (j = 0; j < nspecial[i][1]; j++) { + proclist[m] = proc; + inbuf[m].me = -1; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = onethree[i][j]; + m++; + } - // fill buffer with list of 1,3 atoms in each angle - // and with list of 1,3 and 2,4 atoms in each dihedral + for (j = 0; j < num_angle[i]; j++) { + index = atom->map(angle_atom2[i][j]); + if (index < 0 || index >= nlocal) continue; + + proclist[m] = hashlittle(&angle_atom1[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = angle_atom1[i][j]; + inbuf[m].partnerID = angle_atom3[i][j]; + m++; + + proclist[m] = hashlittle(&angle_atom3[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = angle_atom3[i][j]; + inbuf[m].partnerID = angle_atom1[i][j]; + m++; + } - int size = 0; - if (num_angle && atom->nangles) - for (i = 0; i < nlocal; i++) - for (j = 0; j < num_angle[i]; j++) { - buf[size++] = angle_atom1[i][j]; - buf[size++] = angle_atom3[i][j]; - } + for (j = 0; j < num_dihedral[i]; j++) { + index = atom->map(dihedral_atom2[i][j]); + if (index < 0 || index >= nlocal) continue; + + proclist[m] = hashlittle(&dihedral_atom1[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = dihedral_atom1[i][j]; + inbuf[m].partnerID = dihedral_atom3[i][j]; + m++; + + proclist[m] = hashlittle(&dihedral_atom2[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = dihedral_atom2[i][j]; + inbuf[m].partnerID = dihedral_atom4[i][j]; + m++; + + proclist[m] = hashlittle(&dihedral_atom3[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = dihedral_atom3[i][j]; + inbuf[m].partnerID = dihedral_atom1[i][j]; + m++; + + proclist[m] = hashlittle(&dihedral_atom4[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = dihedral_atom4[i][j]; + inbuf[m].partnerID = dihedral_atom2[i][j]; + m++; + } + } - if (num_dihedral && atom->ndihedrals) - for (i = 0; i < nlocal; i++) - for (j = 0; j < num_dihedral[i]; j++) { - buf[size++] = dihedral_atom1[i][j]; - buf[size++] = dihedral_atom3[i][j]; - buf[size++] = dihedral_atom2[i][j]; - buf[size++] = dihedral_atom4[i][j]; - } + // perform rendezvous operation + // each proc owns random subset of atoms + // func = compute bbox of each body, flag atom closest to geometric center + // when done: each atom has atom ID of owning atom of its body + + char *buf; + int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), + rendezvous_trim, + buf,sizeof(OutRvous),(void *) this); + OutRvous *outbuf = (OutRvous *) buf; - // cycle buffer around ring of procs back to self - // when receive buffer, scan list of 1,3 atoms looking for atoms I own - // when find one, scan its 1-3 neigh list and mark I,J as in an angle + memory->destroy(proclist); + memory->sfree(inbuf); - comm->ring(size,sizeof(tagint),buf,7,ring_seven,NULL,(void *)this); + // reset nspecial[1] and onethree for all owned atoms based on output info - // delete 1-3 neighbors if they are not flagged in dflag + for (i = 0; i < nlocal; i++) nspecial[i][1] = 0; - for (i = 0; i < nlocal; i++) { - m = 0; - for (j = 0; j < nspecial[i][1]; j++) - if (dflag[i][j]) onethree[i][m++] = onethree[i][j]; - nspecial[i][1] = m; + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + onethree[i][nspecial[i][1]++] = outbuf[m].partnerID; } - // clean up - - memory->destroy(dflag); - memory->destroy(buf); + memory->destroy(outbuf); // if no angles or dihedrals are defined, delete all 1-3 neighs @@ -789,12 +783,14 @@ void Special::angle_trim() void Special::dihedral_trim() { - int i,j,m,n; + int i,j,m,n,proc,index; int *num_dihedral = atom->num_dihedral; tagint **dihedral_atom1 = atom->dihedral_atom1; + tagint **dihedral_atom2 = atom->dihedral_atom2; tagint **dihedral_atom4 = atom->dihedral_atom4; int **nspecial = atom->nspecial; + tagint *tag = atom->tag; int nlocal = atom->nlocal; // stats on old 1-4 neighbor counts @@ -813,57 +809,95 @@ void Special::dihedral_trim() " %g = # of 1-4 neighbors before dihedral trim\n",allcount); } - // if dihedrals are defined, flag each 1-4 neigh if it appears in a dihedral + // if dihedrals are defined, rendezvous onefour list with dihedral 1-4 pairs if (num_dihedral && atom->ndihedrals) { - // dflag = flag for 1-4 neighs of all owned atoms - - int maxcount = 0; - for (i = 0; i < nlocal; i++) maxcount = MAX(maxcount,nspecial[i][2]); - memory->create(dflag,nlocal,maxcount,"special::dflag"); + // ncount = # of my datums to send in 3 parts for each owned atom + // onefour list, proc owner, dihedral end points + // latter is only for dihedrals where I own atom2 + int ncount = nlocal; + for (i = 0; i < nlocal; i++) ncount += nspecial[i][2]; for (i = 0; i < nlocal; i++) { - n = nspecial[i][2]; - for (j = 0; j < n; j++) dflag[i][j] = 0; + for (j = 0; j < num_dihedral[i]; j++) { + index = atom->map(dihedral_atom2[i][j]); + if (index >= 0 && index < nlocal) ncount += 2; + } } - // nbufmax = largest buffer needed to hold info from any proc - // info for each atom = list of 1,4 atoms in each dihedral stored by atom + int *proclist; + memory->create(proclist,ncount,"special:proclist"); + InRvous *inbuf = (InRvous *) + memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); - int nbuf = 0; - for (i = 0; i < nlocal; i++) nbuf += 2*num_dihedral[i]; - int *buf; - memory->create(buf,nbuf,"special:buf"); + // setup input buf to rendezvous comm + // one datum for each owned atom: datum = proc, atomID + // sent to owner of atomID + // one datum for each 1-4 partner: datum = atomID, ID + // sent to owner of atomID + // two datums for each dihedral 1-4 endatoms : datum = atomID, ID + // sent to owner of atomID - // fill buffer with list of 1,4 atoms in each dihedral + m = 0; + for (i = 0; i < nlocal; i++) { + proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; + proclist[m] = proc; + inbuf[m].me = me; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = 0; + m++; + + for (j = 0; j < nspecial[i][2]; j++) { + proclist[m] = proc; + inbuf[m].me = -1; + inbuf[m].atomID = tag[i]; + inbuf[m].partnerID = onefour[i][j]; + m++; + } - int size = 0; - for (i = 0; i < nlocal; i++) for (j = 0; j < num_dihedral[i]; j++) { - buf[size++] = dihedral_atom1[i][j]; - buf[size++] = dihedral_atom4[i][j]; + index = atom->map(dihedral_atom2[i][j]); + if (index < 0 || index >= nlocal) continue; + + proclist[m] = hashlittle(&dihedral_atom1[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = dihedral_atom1[i][j]; + inbuf[m].partnerID = dihedral_atom4[i][j]; + m++; + + proclist[m] = hashlittle(&dihedral_atom4[i][j],sizeof(tagint),0) % nprocs; + inbuf[m].me = -2; + inbuf[m].atomID = dihedral_atom4[i][j]; + inbuf[m].partnerID = dihedral_atom1[i][j]; + m++; } + } - // cycle buffer around ring of procs back to self - // when receive buffer, scan list of 1,4 atoms looking for atoms I own - // when find one, scan its 1-4 neigh list and mark I,J as in a dihedral + // perform rendezvous operation + // each proc owns random subset of atoms + // func = compute bbox of each body, flag atom closest to geometric center + // when done: each atom has atom ID of owning atom of its body + + char *buf; + int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), + rendezvous_trim, + buf,sizeof(OutRvous),(void *) this); + OutRvous *outbuf = (OutRvous *) buf; - comm->ring(size,sizeof(tagint),buf,8,ring_eight,NULL,(void *)this); + memory->destroy(proclist); + memory->sfree(inbuf); - // delete 1-4 neighbors if they are not flagged in dflag + // reset nspecial[2] and onefour for all owned atoms based on output info - for (i = 0; i < nlocal; i++) { - m = 0; - for (j = 0; j < nspecial[i][2]; j++) - if (dflag[i][j]) onefour[i][m++] = onefour[i][j]; - nspecial[i][2] = m; - } + for (i = 0; i < nlocal; i++) nspecial[i][2] = 0; - // clean up + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + onefour[i][nspecial[i][2]++] = outbuf[m].partnerID; + } - memory->destroy(dflag); - memory->destroy(buf); + memory->destroy(outbuf); // if no dihedrals are defined, delete all 1-4 neighs @@ -888,262 +922,213 @@ void Special::dihedral_trim() } /* ---------------------------------------------------------------------- - when receive buffer, scan tags for atoms I own - when find one, increment nspecial count for that atom + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N InRvous datums + create outbuf = list of Nout OutRvous datums ------------------------------------------------------------------------- */ -void Special::ring_one(int ndatum, char *cbuf, void *ptr) +int Special::rendezvous_1234(int n, char *inbuf, + int *&proclist, char *&outbuf, + void *ptr) { + int i,j,m; + Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + Memory *memory = sptr->memory; + + // setup hash + // ncount = number of atoms assigned to me + // key = atom ID + // value = index into Ncount-length data structure + + InRvous *in = (InRvous *) inbuf; + std::map hash; + tagint id; + + int ncount = 0; + for (i = 0; i < n; i++) + if (in[i].me >= 0) + hash[in[i].atomID] = ncount++; + + // procowner = caller proc that owns each atom + // atomID = ID of each rendezvous atom I own + + int *procowner,*npartner; + tagint *atomID; + memory->create(procowner,ncount,"special:procowner"); + memory->create(atomID,ncount,"special:atomID"); + memory->create(npartner,ncount,"special:npartner"); + for (m = 0; m < ncount; m++) npartner[m] = 0; + + for (i = 0; i < n; i++) { + m = hash.find(in[i].atomID)->second; + if (in[i].me >= 0) { + procowner[m] = in[i].me; + atomID[m] = in[i].atomID; + } else npartner[m]++; + } - tagint *buf = (tagint *) cbuf; - int m; + int max = 0; + for (m = 0; m < ncount; m++) + max = MAX(max,npartner[m]); + sptr->max_rvous = max; - for (int i = 0; i < ndatum; i++) { - m = atom->map(buf[i]); - if (m >= 0 && m < nlocal) nspecial[m][0]++; + int **partner; + memory->create(partner,ncount,max,"special:partner"); + for (m = 0; m < ncount; m++) npartner[m] = 0; + + for (i = 0; i < n; i++) { + if (in[i].me >= 0) continue; + m = hash.find(in[i].atomID)->second; + partner[m][npartner[m]++] = in[i].partnerID; } -} -/* ---------------------------------------------------------------------- - when receive buffer, scan 2nd-atom tags for atoms I own - when find one, add 1st-atom tag to onetwo list for 2nd atom -------------------------------------------------------------------------- */ + // pass list of OutRvous datums back to comm->rendezvous -void Special::ring_two(int ndatum, char *cbuf, void *ptr) -{ - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int nlocal = atom->nlocal; + int nout = 0; + for (m = 0; m < ncount; m++) nout += npartner[m]; - tagint **onetwo = sptr->onetwo; - int *count = sptr->count; + memory->create(proclist,nout,"special:proclist"); + OutRvous *out = (OutRvous *) + memory->smalloc((bigint) nout*sizeof(OutRvous),"special:out"); - tagint *buf = (tagint *) cbuf; - int m; + nout = 0; + for (m = 0; m < ncount; m++) + for (j = 0; j < npartner[m]; j++) { + proclist[nout] = procowner[m]; + out[nout].atomID = atomID[m]; + out[nout].partnerID = partner[m][j]; + nout++; + } - for (int i = 1; i < ndatum; i += 2) { - m = atom->map(buf[i]); - if (m >= 0 && m < nlocal) onetwo[m][count[m]++] = buf[i-1]; - } -} + outbuf = (char *) out; -/* ---------------------------------------------------------------------- - when receive buffer, scan list of 1-2 neighbors for atoms I own - when find one, increment 1-3 count by # of 1-2 neighbors of my atom, - subtracting one since my list will contain original atom -------------------------------------------------------------------------- */ + // clean up + // Comm::rendezvous will delete proclist and out (outbuf) -void Special::ring_three(int ndatum, char *cbuf, void *ptr) -{ - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + memory->destroy(procowner); + memory->destroy(atomID); + memory->destroy(npartner); + memory->destroy(partner); - tagint *buf = (tagint *) cbuf; - int i,j,m,n,num12; - - i = 0; - while (i < ndatum) { - n = buf[i]; - num12 = buf[i+1]; - for (j = 0; j < num12; j++) { - m = atom->map(buf[i+2+j]); - if (m >= 0 && m < nlocal) - n += nspecial[m][0] - 1; - } - buf[i] = n; - i += 2 + num12; - } + return nout; } /* ---------------------------------------------------------------------- - when receive buffer, scan list of 1-2 neighbors for atoms I own - when find one, add its neighbors to 1-3 list - increment the count in buf(i+4) - exclude the atom whose tag = original - this process may include duplicates but they will be culled later + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N InRvous datums + create outbuf = list of Nout OutRvous datums ------------------------------------------------------------------------- */ -void Special::ring_four(int ndatum, char *cbuf, void *ptr) +int Special::rendezvous_trim(int n, char *inbuf, + int *&proclist, char *&outbuf, + void *ptr) { - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + int i,j,m; - tagint **onetwo = sptr->onetwo; - - tagint *buf = (tagint *) cbuf; - tagint original; - int i,j,k,m,n,num12,num13; - - i = 0; - while (i < ndatum) { - original = buf[i]; - num12 = buf[i+1]; - num13 = buf[i+2]; - n = buf[i+3]; - for (j = 0; j < num12; j++) { - m = atom->map(buf[i+4+j]); - if (m >= 0 && m < nlocal) - for (k = 0; k < nspecial[m][0]; k++) - if (onetwo[m][k] != original) - buf[i+4+num12+(n++)] = onetwo[m][k]; - } - buf[i+3] = n; - i += 4 + num12 + num13; + Special *sptr = (Special *) ptr; + Memory *memory = sptr->memory; + + // setup hash + // ncount = number of atoms assigned to me + // key = atom ID + // value = index into Ncount-length data structure + + InRvous *in = (InRvous *) inbuf; + std::map hash; + tagint id; + + int ncount = 0; + for (i = 0; i < n; i++) + if (in[i].me >= 0) + hash[in[i].atomID] = ncount++; + + // procowner = caller proc that owns each atom + // atomID = ID of each rendezvous atom I own + // npartner = # of 1-3 partners for each atom I own + + int *procowner,*npartner; + tagint *atomID; + memory->create(procowner,ncount,"special:procowner"); + memory->create(atomID,ncount,"special:atomID"); + memory->create(npartner,ncount,"special:npartner"); + for (m = 0; m < ncount; m++) npartner[m] = 0; + + for (i = 0; i < n; i++) { + m = hash.find(in[i].atomID)->second; + if (in[i].me >= 0) { + procowner[m] = in[i].me; + atomID[m] = in[i].atomID; + } else if (in[i].me == -1) npartner[m]++; } -} -/* ---------------------------------------------------------------------- - when receive buffer, scan list of 1-3 neighbors for atoms I own - when find one, increment 1-4 count by # of 1-2 neighbors of my atom - may include duplicates and original atom but they will be culled later -------------------------------------------------------------------------- */ + int max = 0; + for (m = 0; m < ncount; m++) max = MAX(max,npartner[m]); -void Special::ring_five(int ndatum, char *cbuf, void *ptr) -{ - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + // partner = list of 1-3 or 1-4 partners for each atom I own - tagint *buf = (tagint *) cbuf; - int i,j,m,n,num13; + int **partner; + memory->create(partner,ncount,max,"special:partner"); + for (m = 0; m < ncount; m++) npartner[m] = 0; - i = 0; - while (i < ndatum) { - n = buf[i]; - num13 = buf[i+1]; - for (j = 0; j < num13; j++) { - m = atom->map(buf[i+2+j]); - if (m >= 0 && m < nlocal) n += nspecial[m][0]; - } - buf[i] = n; - i += 2 + num13; + for (i = 0; i < n; i++) { + if (in[i].me >= 0 || in[i].me == -2) continue; + m = hash.find(in[i].atomID)->second; + partner[m][npartner[m]++] = in[i].partnerID; } -} -/* ---------------------------------------------------------------------- - when receive buffer, scan list of 1-3 neighbors for atoms I own - when find one, add its neighbors to 1-4 list - incrementing the count in buf(i+4) - this process may include duplicates but they will be culled later -------------------------------------------------------------------------- */ + // flag = 1 if partner is in an actual angle or in a dihedral + + int **flag; + memory->create(flag,ncount,max,"special:flag"); + + for (i = 0; i < ncount; i++) + for (j = 0; j < npartner[i]; j++) + flag[i][j] = 0; + + tagint actual; + for (i = 0; i < n; i++) { + if (in[i].me != -2) continue; + actual = in[i].partnerID; + m = hash.find(in[i].atomID)->second; + for (j = 0; j < npartner[m]; j++) + if (partner[m][j] == actual) { + flag[m][j] = 1; + break; + } + } -void Special::ring_six(int ndatum, char *cbuf, void *ptr) -{ - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + // pass list of OutRvous datums back to comm->rendezvous - tagint **onetwo = sptr->onetwo; - - tagint *buf = (tagint *) cbuf; - int i,j,k,m,n,num13,num14; - - i = 0; - while (i < ndatum) { - num13 = buf[i]; - num14 = buf[i+1]; - n = buf[i+2]; - for (j = 0; j < num13; j++) { - m = atom->map(buf[i+3+j]); - if (m >= 0 && m < nlocal) - for (k = 0; k < nspecial[m][0]; k++) - buf[i+3+num13+(n++)] = onetwo[m][k]; - } - buf[i+2] = n; - i += 3 + num13 + num14; - } -} + int nout = 0; + for (m = 0; m < ncount; m++) nout += npartner[m]; -/* ---------------------------------------------------------------------- - when receive buffer, scan list of 1,3 atoms looking for atoms I own - when find one, scan its 1-3 neigh list and mark I,J as in an angle -------------------------------------------------------------------------- */ + memory->create(proclist,nout,"special:proclist"); + OutRvous *out = (OutRvous *) + memory->smalloc((bigint) nout*sizeof(OutRvous),"special:out"); -void Special::ring_seven(int ndatum, char *cbuf, void *ptr) -{ - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + nout = 0; + for (m = 0; m < ncount; m++) + for (j = 0; j < npartner[m]; j++) { + if (flag[m][j] == 0) continue; + proclist[nout] = procowner[m]; + out[nout].atomID = atomID[m]; + out[nout].partnerID = partner[m][j]; + nout++; + } - tagint **onethree = sptr->onethree; - int **dflag = sptr->dflag; - - tagint *buf = (tagint *) cbuf; - tagint iglobal,jglobal; - int i,m,ilocal,jlocal; - - i = 0; - while (i < ndatum) { - iglobal = buf[i]; - jglobal = buf[i+1]; - ilocal = atom->map(iglobal); - jlocal = atom->map(jglobal); - if (ilocal >= 0 && ilocal < nlocal) - for (m = 0; m < nspecial[ilocal][1]; m++) - if (jglobal == onethree[ilocal][m]) { - dflag[ilocal][m] = 1; - break; - } - if (jlocal >= 0 && jlocal < nlocal) - for (m = 0; m < nspecial[jlocal][1]; m++) - if (iglobal == onethree[jlocal][m]) { - dflag[jlocal][m] = 1; - break; - } - i += 2; - } -} + outbuf = (char *) out; -/* ---------------------------------------------------------------------- - when receive buffer, scan list of 1,4 atoms looking for atoms I own - when find one, scan its 1-4 neigh list and mark I,J as in a dihedral -------------------------------------------------------------------------- */ + // clean up + // Comm::rendezvous will delete proclist and out (outbuf) -void Special::ring_eight(int ndatum, char *cbuf, void *ptr) -{ - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - int **nspecial = atom->nspecial; - int nlocal = atom->nlocal; + memory->destroy(procowner); + memory->destroy(atomID); + memory->destroy(npartner); + memory->destroy(partner); + memory->destroy(flag); - tagint **onefour = sptr->onefour; - int **dflag = sptr->dflag; - - tagint *buf = (tagint *) cbuf; - tagint iglobal,jglobal; - int i,m,ilocal,jlocal; - - i = 0; - while (i < ndatum) { - iglobal = buf[i]; - jglobal = buf[i+1]; - ilocal = atom->map(iglobal); - jlocal = atom->map(jglobal); - if (ilocal >= 0 && ilocal < nlocal) - for (m = 0; m < nspecial[ilocal][2]; m++) - if (jglobal == onefour[ilocal][m]) { - dflag[ilocal][m] = 1; - break; - } - if (jlocal >= 0 && jlocal < nlocal) - for (m = 0; m < nspecial[jlocal][2]; m++) - if (iglobal == onefour[jlocal][m]) { - dflag[jlocal][m] = 1; - break; - } - i += 2; - } + return nout; } /* ---------------------------------------------------------------------- @@ -1159,3 +1144,15 @@ void Special::fix_alteration() modify->fix[ifix]->rebuild_special(); } +/* ---------------------------------------------------------------------- + print timing output +------------------------------------------------------------------------- */ + +void Special::timer_output(double time1) +{ + double t2 = MPI_Wtime(); + if (comm->me == 0) { + if (screen) fprintf(screen," special bonds CPU = %g secs\n",t2-t1); + if (logfile) fprintf(logfile," special bonds CPU = %g secs\n",t2-t1); + } +} diff --git a/src/special.h b/src/special.h index 9f25200336..f7892075ac 100644 --- a/src/special.h +++ b/src/special.h @@ -28,27 +28,30 @@ class Special : protected Pointers { int me,nprocs; tagint **onetwo,**onethree,**onefour; - // data used by ring callback methods + // data used by rendezvous callback methods - int *count; - int **dflag; + int max_rvous; + + struct InRvous { + int me; + tagint atomID,partnerID; + }; + + struct OutRvous { + tagint atomID,partnerID; + }; void dedup(); void angle_trim(); void dihedral_trim(); void combine(); void fix_alteration(); + void timer_output(double); - // callback functions for ring communication + // callback function for rendezvous communication - static void ring_one(int, char *, void *); - static void ring_two(int, char *, void *); - static void ring_three(int, char *, void *); - static void ring_four(int, char *, void *); - static void ring_five(int, char *, void *); - static void ring_six(int, char *, void *); - static void ring_seven(int, char *, void *); - static void ring_eight(int, char *, void *); + static int rendezvous_1234(int, char *, int *&, char *&, void *); + static int rendezvous_trim(int, char *, int *&, char *&, void *); }; } -- GitLab From 2e0d69b005ef26ccf1fdf0bcc671bfd8a61fafea Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 30 Nov 2018 13:06:31 -0700 Subject: [PATCH 0069/1243] replace STL map with atom->map in special, better code comments --- src/RIGID/fix_rigid_small.cpp | 8 ++-- src/comm.cpp | 20 ++++++-- src/read_data.cpp | 8 ++-- src/read_restart.cpp | 4 +- src/special.cpp | 89 +++++++++++++++++++++++++---------- 5 files changed, 92 insertions(+), 37 deletions(-) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index 4421d9ae17..fc51e0aa4f 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -1571,9 +1571,9 @@ void FixRigidSmall::create_bodies(tagint *bodyID) } // perform rendezvous operation - // each proc owns random subset of bodies, receives all atoms in the bodies - // func = compute bbox of each body, flag atom closest to geometric center - // when done: each atom has atom ID of owning atom of its body + // each proc owns random subset of bodies + // receives all atoms in those bodies + // func = compute bbox of each body, find atom closest to geometric center char *buf; int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), @@ -1627,6 +1627,8 @@ int FixRigidSmall::rendezvous_body(int n, char *inbuf, MPI_Comm world = frsptr->world; // setup hash + // use STL map instead of atom->map + // b/c know nothing about body ID values specified by user // ncount = number of bodies assigned to me // key = body ID // value = index into Ncount-length data structure diff --git a/src/comm.cpp b/src/comm.cpp index 5fcfa141d0..6512b21fef 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -728,13 +728,27 @@ void Comm::ring(int n, int nper, void *inbuf, int messtag, /* ---------------------------------------------------------------------- rendezvous communication operation + three stages: + first Irregular converts inbuf from caller decomp to rvous decomp + callback operates on data in rendevous decomp + last Irregular converts outbuf from rvous decomp back to caller decomp + inputs: + n = # of input datums + proclist = proc that owns each input datum in rendezvous decomposition + inbuf = list of input datums + insize = size in bytes of each input datum + callback = caller function to invoke in rendezvous decomposition + outputs: + nout = # of output datums (function return) + outbuf = list of output datums + outsize = size in bytes of each output datum ------------------------------------------------------------------------- */ int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, int (*callback)(int, char *, int *&, char *&, void *), char *&outbuf, int outsize, void *ptr) { - // comm data from caller decomposition to rendezvous decomposition + // comm inbuf from caller decomposition to rendezvous decomposition Irregular *irregular = new Irregular(lmp); @@ -747,7 +761,7 @@ int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, delete irregular; // peform rendezvous computation via callback() - // callback() allocates proclist_rvous and outbuf_rvous + // callback() allocates/populates proclist_rvous and outbuf_rvous int *proclist_rvous; char *outbuf_rvous; @@ -757,7 +771,7 @@ int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, memory->sfree(inbuf_rvous); - // comm data from rendezvous decomposition back to caller + // comm outbuf from rendezvous decomposition back to caller // caller will free outbuf irregular = new Irregular(lmp); diff --git a/src/read_data.cpp b/src/read_data.cpp index d7bd298e7b..cdeda03066 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -121,7 +121,7 @@ void ReadData::command(int narg, char **arg) if (narg < 1) error->all(FLERR,"Illegal read_data command"); MPI_Barrier(world); - double time1 = MPI_Wtime; + double time1 = MPI_Wtime(); // optional args @@ -912,13 +912,13 @@ void ReadData::command(int narg, char **arg) // total time MPI_Barrier(world); - double time2 = MPI_Wtime; + double time2 = MPI_Wtime(); if (comm->me == 0) { if (screen) - fprintf(screen," read_atoms CPU = %g secs\n",time2-time1); + fprintf(screen," read_data CPU = %g secs\n",time2-time1); if (logfile) - fprintf(logfile," read_atoms CPU = %g secs\n",time2-time1); + fprintf(logfile," read_data CPU = %g secs\n",time2-time1); } } diff --git a/src/read_restart.cpp b/src/read_restart.cpp index a338a843d7..b61fb2278f 100644 --- a/src/read_restart.cpp +++ b/src/read_restart.cpp @@ -82,7 +82,7 @@ void ReadRestart::command(int narg, char **arg) error->all(FLERR,"Cannot read_restart after simulation box is defined"); MPI_Barrier(world); - double time1 = MPI_Wtime; + double time1 = MPI_Wtime(); MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); @@ -569,7 +569,7 @@ void ReadRestart::command(int narg, char **arg) // total time MPI_Barrier(world); - double time2 = MPI_Wtime; + double time2 = MPI_Wtime(); if (comm->me == 0) { if (screen) diff --git a/src/special.cpp b/src/special.cpp index a18c597765..6dad30a9a7 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -108,9 +108,11 @@ void Special::build() memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); // setup input buf to rendezvous comm - // one datum for each owned atom: datum = proc, atomID - // one datum for each bond partner: datum = atomID, bond partner ID + // input datums = pairs of bonded atoms // owning proc for each datum = random hash of atomID + // one datum for each owned atom: datum = owning proc, atomID + // one datum for each bond partner: datum = atomID, bond partner ID + // add inverted datum when netwon_bond on m = 0; for (i = 0; i < nlocal; i++) { @@ -140,7 +142,8 @@ void Special::build() } // perform rendezvous operation - // each proc owns random subset of atoms, receives all their bond partners + // each proc owns random subset of atoms + // receives all info to form and return their onetwo lists int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), rendezvous_1234, @@ -151,6 +154,7 @@ void Special::build() memory->sfree(inbuf); // set nspecial[0] and onetwo for all owned atoms based on output info + // output datums = pairs of atoms that are 1-2 neighbors MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onetwo,nlocal,maxall,"special:onetwo"); @@ -200,9 +204,10 @@ void Special::build() memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); // setup input buf to rendezvous comm - // one datum for each owned atom: datum = proc, atomID - // one datum for each bond partner: datum = atomID, bond partner ID + // input datums = all pairs of onetwo atoms (they are 1-3 neighbors) // owning proc for each datum = random hash of atomID + // one datum for each owned atom: datum = owning proc, atomID + // one datum for each onetwo pair: datum = atomID1, atomID2 m = 0; for (i = 0; i < nlocal; i++) { @@ -226,7 +231,8 @@ void Special::build() } // perform rendezvous operation - // each proc owns random subset of atoms, receives all their bond partners + // each proc owns random subset of atoms + // receives all info to form and return their onethree lists nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), rendezvous_1234, @@ -237,6 +243,7 @@ void Special::build() memory->sfree(inbuf); // set nspecial[1] and onethree for all owned atoms based on output info + // output datums = pairs of atoms that are 1-3 neighbors MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onethree,nlocal,maxall,"special:onethree"); @@ -284,9 +291,10 @@ void Special::build() memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); // setup input buf to rendezvous comm - // one datum for each owned atom: datum = proc, atomID - // one datum for each partner: datum = atomID, bond partner ID + // input datums = all pairs of onethree and onetwo atoms (they're 1-4 neighbors) // owning proc for each datum = random hash of atomID + // one datum for each owned atom: datum = owning proc, atomID + // one datum for each onethree/onetwo pair: datum = atomID1, atomID2 m = 0; for (i = 0; i < nlocal; i++) { @@ -309,9 +317,8 @@ void Special::build() } // perform rendezvous operation - // each proc owns random subset of bodies, receives all atoms in the bodies - // func = compute bbox of each body, flag atom closest to geometric center - // when done: each atom has atom ID of owning atom of its body + // each proc owns random subset of atoms + // receives all info to form and return their onefour lists nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), rendezvous_1234, @@ -322,6 +329,7 @@ void Special::build() memory->sfree(inbuf); // set nspecial[2] and onefour for all owned atoms based on output info + // output datums = pairs of atoms that are 1-4 neighbors MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onefour,nlocal,maxall,"special:onefour"); @@ -934,21 +942,28 @@ int Special::rendezvous_1234(int n, char *inbuf, int i,j,m; Special *sptr = (Special *) ptr; + Atom *atom = sptr->atom; Memory *memory = sptr->memory; - // setup hash + // clear atom map so it can be here as a hash table + // faster than an STL map for large atom counts + + atom->map_clear(); + + // initialize hash // ncount = number of atoms assigned to me // key = atom ID // value = index into Ncount-length data structure InRvous *in = (InRvous *) inbuf; - std::map hash; + //std::map hash; tagint id; int ncount = 0; for (i = 0; i < n; i++) if (in[i].me >= 0) - hash[in[i].atomID] = ncount++; + //hash[in[i].atomID] = ncount++; + atom->map_one(in[i].atomID,ncount++); // procowner = caller proc that owns each atom // atomID = ID of each rendezvous atom I own @@ -961,7 +976,8 @@ int Special::rendezvous_1234(int n, char *inbuf, for (m = 0; m < ncount; m++) npartner[m] = 0; for (i = 0; i < n; i++) { - m = hash.find(in[i].atomID)->second; + //m = hash.find(in[i].atomID)->second; + m = atom->map(in[i].atomID); if (in[i].me >= 0) { procowner[m] = in[i].me; atomID[m] = in[i].atomID; @@ -979,7 +995,8 @@ int Special::rendezvous_1234(int n, char *inbuf, for (i = 0; i < n; i++) { if (in[i].me >= 0) continue; - m = hash.find(in[i].atomID)->second; + //m = hash.find(in[i].atomID)->second; + m = atom->map(in[i].atomID); partner[m][npartner[m]++] = in[i].partnerID; } @@ -1011,6 +1028,12 @@ int Special::rendezvous_1234(int n, char *inbuf, memory->destroy(npartner); memory->destroy(partner); + // re-create atom map + + atom->map_init(0); + atom->nghost = 0; + atom->map_set(); + return nout; } @@ -1027,21 +1050,28 @@ int Special::rendezvous_trim(int n, char *inbuf, int i,j,m; Special *sptr = (Special *) ptr; + Atom *atom = sptr->atom; Memory *memory = sptr->memory; - // setup hash + // clear atom map so it can be here as a hash table + // faster than an STL map for large atom counts + + atom->map_clear(); + + // initialize hash // ncount = number of atoms assigned to me // key = atom ID // value = index into Ncount-length data structure InRvous *in = (InRvous *) inbuf; - std::map hash; + //std::map hash; tagint id; int ncount = 0; for (i = 0; i < n; i++) if (in[i].me >= 0) - hash[in[i].atomID] = ncount++; + //hash[in[i].atomID] = ncount++; + atom->map_one(in[i].atomID,ncount++); // procowner = caller proc that owns each atom // atomID = ID of each rendezvous atom I own @@ -1055,7 +1085,8 @@ int Special::rendezvous_trim(int n, char *inbuf, for (m = 0; m < ncount; m++) npartner[m] = 0; for (i = 0; i < n; i++) { - m = hash.find(in[i].atomID)->second; + //m = hash.find(in[i].atomID)->second; + m = atom->map(in[i].atomID); if (in[i].me >= 0) { procowner[m] = in[i].me; atomID[m] = in[i].atomID; @@ -1073,7 +1104,8 @@ int Special::rendezvous_trim(int n, char *inbuf, for (i = 0; i < n; i++) { if (in[i].me >= 0 || in[i].me == -2) continue; - m = hash.find(in[i].atomID)->second; + //m = hash.find(in[i].atomID)->second; + m = atom->map(in[i].atomID); partner[m][npartner[m]++] = in[i].partnerID; } @@ -1090,7 +1122,8 @@ int Special::rendezvous_trim(int n, char *inbuf, for (i = 0; i < n; i++) { if (in[i].me != -2) continue; actual = in[i].partnerID; - m = hash.find(in[i].atomID)->second; + //m = hash.find(in[i].atomID)->second; + m = atom->map(in[i].atomID); for (j = 0; j < npartner[m]; j++) if (partner[m][j] == actual) { flag[m][j] = 1; @@ -1128,6 +1161,12 @@ int Special::rendezvous_trim(int n, char *inbuf, memory->destroy(partner); memory->destroy(flag); + // re-create atom map + + atom->map_init(0); + atom->nghost = 0; + atom->map_set(); + return nout; } @@ -1150,9 +1189,9 @@ void Special::fix_alteration() void Special::timer_output(double time1) { - double t2 = MPI_Wtime(); + double time2 = MPI_Wtime(); if (comm->me == 0) { - if (screen) fprintf(screen," special bonds CPU = %g secs\n",t2-t1); - if (logfile) fprintf(logfile," special bonds CPU = %g secs\n",t2-t1); + if (screen) fprintf(screen," special bonds CPU = %g secs\n",time2-time1); + if (logfile) fprintf(logfile," special bonds CPU = %g secs\n",time2-time1); } } -- GitLab From ece1aff7e9c33b7145973880677e3fbdb3b5e37a Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 7 Dec 2018 15:46:27 -0700 Subject: [PATCH 0070/1243] less comm version of special bonds rendezvous --- src/comm.cpp | 8 +- src/comm.h | 2 +- src/special.cpp | 694 +++++++++++++++++++++++++++++------------------- src/special.h | 24 +- 4 files changed, 446 insertions(+), 282 deletions(-) diff --git a/src/comm.cpp b/src/comm.cpp index 6512b21fef..9bdaf0798a 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -745,7 +745,7 @@ void Comm::ring(int n, int nper, void *inbuf, int messtag, ------------------------------------------------------------------------- */ int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, - int (*callback)(int, char *, int *&, char *&, void *), + int (*callback)(int, char *, int &, int *&, char *&, void *), char *&outbuf, int outsize, void *ptr) { // comm inbuf from caller decomposition to rendezvous decomposition @@ -763,13 +763,15 @@ int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, // peform rendezvous computation via callback() // callback() allocates/populates proclist_rvous and outbuf_rvous + int flag; int *proclist_rvous; char *outbuf_rvous; int nout_rvous = - callback(n_rvous,inbuf_rvous,proclist_rvous,outbuf_rvous,ptr); + callback(n_rvous,inbuf_rvous,flag,proclist_rvous,outbuf_rvous,ptr); - memory->sfree(inbuf_rvous); + if (flag != 1) memory->sfree(inbuf_rvous); // outbuf_rvous = inbuf_vous + if (flag == 0) return 0; // all nout_rvous are 0, no 2nd irregular // comm outbuf from rendezvous decomposition back to caller // caller will free outbuf diff --git a/src/comm.h b/src/comm.h index 8bb057a0c1..a1bac53ac8 100644 --- a/src/comm.h +++ b/src/comm.h @@ -110,7 +110,7 @@ class Comm : protected Pointers { void ring(int, int, void *, int, void (*)(int, char *, void *), void *, void *, int self = 1); int rendezvous(int, int *, char *, int, - int (*)(int, char *, int *&, char *&, void *), + int (*)(int, char *, int &, int *&, char *&, void *), char *&, int, void *); int read_lines_from_file(FILE *, int, int, char *); diff --git a/src/special.cpp b/src/special.cpp index 6dad30a9a7..79d2f77e46 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -55,20 +55,9 @@ Special::~Special() void Special::build() { - int i,j,k,m,n,size,proc; - int max,maxall; - char *buf; - MPI_Barrier(world); double time1 = MPI_Wtime(); - int nlocal = atom->nlocal; - - tagint *tag = atom->tag; - int *num_bond = atom->num_bond; - tagint **bond_atom = atom->bond_atom; - int **nspecial = atom->nspecial; - if (me == 0 && screen) { const double * const special_lj = force->special_lj; const double * const special_coul = force->special_coul; @@ -81,31 +70,166 @@ void Special::build() // initialize nspecial counters to 0 - for (i = 0; i < nlocal; i++) { + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { nspecial[i][0] = 0; nspecial[i][1] = 0; nspecial[i][2] = 0; } - // ----------------------------------------------------- - // compute nspecial[i][0] = # of 1-2 neighbors of atom i + // setup atomIDs and procowner vectors in rendezvous decomposition + + atom_owners(); + + // tally nspecial[i][0] = # of 1-2 neighbors of atom i // create onetwo[i] = list of 1-2 neighbors for atom i - // ----------------------------------------------------- - // ncount = # of my datums to send (newton or newton off) - // include nlocal datums with owner of each atom + if (force->newton_bond) onetwo_build_newton(); + else onetwo_build_newton_off(); + + // print max # of 1-2 neighbors + + if (me == 0) { + if (screen) fprintf(screen," %d = max # of 1-2 neighbors\n",maxall); + if (logfile) fprintf(logfile," %d = max # of 1-2 neighbors\n",maxall); + } + + // done if special_bond weights for 1-3, 1-4 are set to 1.0 + + if (force->special_lj[2] == 1.0 && force->special_coul[2] == 1.0 && + force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { + dedup(); + combine(); + fix_alteration(); + memory->destroy(procowner); + memory->destroy(atomIDs); + timer_output(time1); + return; + } + + // tally nspecial[i][1] = # of 1-3 neighbors of atom i + // create onethree[i] = list of 1-3 neighbors for atom i + + onethree_build(); + + // print max # of 1-3 neighbors + + if (me == 0) { + if (screen) fprintf(screen," %d = max # of 1-3 neighbors\n",maxall); + if (logfile) fprintf(logfile," %d = max # of 1-3 neighbors\n",maxall); + } + + // done if special_bond weights for 1-4 are set to 1.0 + + if (force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { + dedup(); + if (force->special_angle) angle_trim(); + combine(); + fix_alteration(); + memory->destroy(procowner); + memory->destroy(atomIDs); + timer_output(time1); + return; + } + + // tally nspecial[i][2] = # of 1-4 neighbors of atom i + // create onefour[i] = list of 1-4 neighbors for atom i + + onefour_build(); + + // print max # of 1-4 neighbors + + if (me == 0) { + if (screen) fprintf(screen," %d = max # of 1-4 neighbors\n",maxall); + if (logfile) fprintf(logfile," %d = max # of 1-4 neighbors\n",maxall); + } + + // finish processing the onetwo, onethree, onefour lists + + dedup(); + if (force->special_angle) angle_trim(); + if (force->special_dihedral) dihedral_trim(); + combine(); + fix_alteration(); + memory->destroy(procowner); + memory->destroy(atomIDs); + + timer_output(time1); +} + +/* ---------------------------------------------------------------------- + setup atomIDs and procowner +------------------------------------------------------------------------- */ - int newton_bond = force->newton_bond; +void Special::atom_owners() +{ + tagint *tag = atom->tag; + int nlocal = atom->nlocal; + int *proclist; + memory->create(proclist,nlocal,"special:proclist"); + IDRvous *idbuf = (IDRvous *) + memory->smalloc((bigint) nlocal*sizeof(IDRvous),"special:idbuf"); + + // setup input buf to rendezvous comm + // input datums = pairs of bonded atoms + // owning proc for each datum = random hash of atomID + // one datum for each owned atom: datum = owning proc, atomID + // one datum for each bond partner: datum = atomID, bond partner ID + // add inverted datum when netwon_bond on + + for (int i = 0; i < nlocal; i++) { + //proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; + proclist[i] = tag[i] % nprocs; + idbuf[i].me = me; + idbuf[i].atomID = tag[i]; + } + + // perform rendezvous operation + // each proc owns random subset of atoms + // receives all info to form and return their onetwo lists + + char *buf; + comm->rendezvous(nlocal,proclist, + (char *) idbuf,sizeof(PairRvous), + rendezvous_ids,buf,sizeof(PairRvous), + (void *) this); + + memory->destroy(proclist); + memory->sfree(idbuf); +} + +/* ---------------------------------------------------------------------- + onetwo build +------------------------------------------------------------------------- */ + +void Special::onetwo_build_newton() +{ + int i,j,m; + + tagint *tag = atom->tag; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + + // ncount = # of my datums to send + // include nlocal datums with owner of each atom + int ncount = 0; - for (i = 0; i < nlocal; i++) ncount += num_bond[i]; - if (newton_bond) ncount *= 2; - ncount += nlocal; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < num_bond[i]; j++) { + m = atom->map(bond_atom[i][j]); + if (m < 0 || m >= nlocal) ncount++; + } + } int *proclist; memory->create(proclist,ncount,"special:proclist"); - InRvous *inbuf = (InRvous *) - memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); + PairRvous *inbuf = (PairRvous *) + memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // input datums = pairs of bonded atoms @@ -114,94 +238,110 @@ void Special::build() // one datum for each bond partner: datum = atomID, bond partner ID // add inverted datum when netwon_bond on - m = 0; + ncount = 0; for (i = 0; i < nlocal; i++) { - proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; - proclist[m] = proc; - inbuf[m].me = me; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = 0; - m++; - for (j = 0; j < num_bond[i]; j++) { - proclist[m] = proc; - inbuf[m].me = -1; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = bond_atom[i][j]; - m++; - } - if (newton_bond) { - for (j = 0; j < num_bond[i]; j++) { - proclist[m] = hashlittle(&bond_atom[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -1; - inbuf[m].atomID = bond_atom[i][j]; - inbuf[m].partnerID = tag[i]; - m++; - } + m = atom->map(bond_atom[i][j]); + if (m >= 0 && m < nlocal) continue; + proclist[ncount] = bond_atom[i][j] % nprocs; + inbuf[ncount].atomID = bond_atom[i][j]; + inbuf[ncount].partnerID = tag[i]; + ncount++; } } - + // perform rendezvous operation // each proc owns random subset of atoms // receives all info to form and return their onetwo lists - int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), - rendezvous_1234, - buf,sizeof(OutRvous),(void *) this); - OutRvous *outbuf = (OutRvous *) buf; - + char *buf; + int nreturn = comm->rendezvous(ncount,proclist, + (char *) inbuf,sizeof(PairRvous), + rendezvous_1234,buf,sizeof(PairRvous), + (void *) this); + PairRvous *outbuf = (PairRvous *) buf; + memory->destroy(proclist); memory->sfree(inbuf); // set nspecial[0] and onetwo for all owned atoms based on output info // output datums = pairs of atoms that are 1-2 neighbors - MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); - memory->create(onetwo,nlocal,maxall,"special:onetwo"); + for (i = 0; i < nlocal; i++) { + nspecial[i][0] = num_bond[i]; + for (j = 0; j < num_bond[i]; j++) { + m = atom->map(bond_atom[i][j]); + if (m >= 0 && m < nlocal) nspecial[m][0]++; + } + } + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + nspecial[i][0]++; + } + + int max = 0; + for (i = 0; i < nlocal; i++) + max = MAX(max,nspecial[i][0]); + + MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + memory->create(onetwo,nlocal,maxall,"special:onetwo"); + for (i = 0; i < nlocal; i++) nspecial[i][0] = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < num_bond[i]; j++) { + onetwo[i][nspecial[i][0]++] = bond_atom[i][j]; + m = atom->map(bond_atom[i][j]); + if (m >= 0 && m < nlocal) onetwo[m][nspecial[m][0]++] = tag[i]; + } + } + for (m = 0; m < nreturn; m++) { i = atom->map(outbuf[m].atomID); onetwo[i][nspecial[i][0]++] = outbuf[m].partnerID; } - + memory->sfree(outbuf); +} - // compute and print max # of 1-2 neighbors +/* ---------------------------------------------------------------------- + onetwo build with newton_bond flag off + no need for rendezvous comm +------------------------------------------------------------------------- */ - if (me == 0) { - if (screen) fprintf(screen," %d = max # of 1-2 neighbors\n",maxall); - if (logfile) fprintf(logfile," %d = max # of 1-2 neighbors\n",maxall); - } +void Special::onetwo_build_newton_off() +{ +} - // ----------------------------------------------------- - // done if special_bond weights for 1-3, 1-4 are set to 1.0 - // ----------------------------------------------------- +/* ---------------------------------------------------------------------- + onetwo build with newton_bond flag off + no need for rendezvous comm +------------------------------------------------------------------------- */ - if (force->special_lj[2] == 1.0 && force->special_coul[2] == 1.0 && - force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { - dedup(); - combine(); - fix_alteration(); - timer_output(time1); - return; - } +void Special::onethree_build() +{ + int i,j,k,m,proc; - // ----------------------------------------------------- - // compute nspecial[i][1] = # of 1-3 neighbors of atom i - // create onethree[i] = list of 1-3 neighbors for atom i - // ----------------------------------------------------- + tagint *tag = atom->tag; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; // ncount = # of my datums to send // include nlocal datums with owner of each atom - ncount = nlocal; - for (i = 0; i < nlocal; i++) ncount += nspecial[i][0]*(nspecial[i][0]-1); + int ncount = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < nspecial[i][0]; j++) { + m = atom->map(onetwo[i][j]); + if (m < 0 || m >= nlocal) ncount += nspecial[i][0]-1; + } + } + int *proclist; memory->create(proclist,ncount,"special:proclist"); - inbuf = (InRvous *) - memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); + PairRvous *inbuf = (PairRvous *) + memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // input datums = all pairs of onetwo atoms (they are 1-3 neighbors) @@ -209,23 +349,18 @@ void Special::build() // one datum for each owned atom: datum = owning proc, atomID // one datum for each onetwo pair: datum = atomID1, atomID2 - m = 0; + ncount = 0; for (i = 0; i < nlocal; i++) { - proclist[m] = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; - inbuf[m].me = me; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = 0; - m++; - for (j = 0; j < nspecial[i][0]; j++) { - proc = hashlittle(&onetwo[i][j],sizeof(tagint),0) % nprocs; + m = atom->map(onetwo[i][j]); + if (m >= 0 && m < nlocal) continue; + proc = onetwo[i][j] % nprocs; for (k = 0; k < nspecial[i][0]; k++) { if (j == k) continue; - proclist[m] = proc; - inbuf[m].me = -1; - inbuf[m].atomID = onetwo[i][j]; - inbuf[m].partnerID = onetwo[i][k]; - m++; + proclist[ncount] = proc; + inbuf[ncount].atomID = onetwo[i][j]; + inbuf[ncount].partnerID = onetwo[i][k]; + ncount++; } } } @@ -234,10 +369,12 @@ void Special::build() // each proc owns random subset of atoms // receives all info to form and return their onethree lists - nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), - rendezvous_1234, - buf,sizeof(OutRvous),(void *) this); - outbuf = (OutRvous *) buf; + char *buf; + int nreturn = comm->rendezvous(ncount,proclist, + (char *) inbuf,sizeof(PairRvous), + rendezvous_1234,buf,sizeof(PairRvous), + (void *) this); + PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); @@ -245,50 +382,73 @@ void Special::build() // set nspecial[1] and onethree for all owned atoms based on output info // output datums = pairs of atoms that are 1-3 neighbors - MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); + for (i = 0; i < nlocal; i++) { + for (j = 0; j < nspecial[i][0]; j++) { + m = atom->map(onetwo[i][j]); + if (m >= 0 && m < nlocal) nspecial[m][1] += nspecial[i][0]-1; + } + } + + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + nspecial[i][1]++; + } + + int max = 0; + for (i = 0; i < nlocal; i++) + max = MAX(max,nspecial[i][1]); + + MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); memory->create(onethree,nlocal,maxall,"special:onethree"); for (i = 0; i < nlocal; i++) nspecial[i][1] = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < nspecial[i][0]; j++) { + m = atom->map(onetwo[i][j]); + if (m < 0 || m >= nlocal) continue; + for (k = 0; k < nspecial[i][0]; k++) { + if (j == k) continue; + onethree[m][nspecial[m][1]++] = onetwo[i][k]; + } + } + } + for (m = 0; m < nreturn; m++) { i = atom->map(outbuf[m].atomID); onethree[i][nspecial[i][1]++] = outbuf[m].partnerID; } - memory->destroy(outbuf); - - // compute and print max # of 1-3 neighbors - - if (me == 0) { - if (screen) fprintf(screen," %d = max # of 1-3 neighbors\n",maxall); - if (logfile) fprintf(logfile," %d = max # of 1-3 neighbors\n",maxall); - } + memory->sfree(outbuf); +} - // done if special_bond weights for 1-4 are set to 1.0 +/* ---------------------------------------------------------------------- + remove duplicates within each of onetwo, onethree, onefour individually +------------------------------------------------------------------------- */ - if (force->special_lj[3] == 1.0 && force->special_coul[3] == 1.0) { - dedup(); - if (force->special_angle) angle_trim(); - combine(); - fix_alteration(); - timer_output(time1); - return; - } +void Special::onefour_build() +{ + int i,j,k,m,proc; - // ----------------------------------------------------- - // compute nspecial[i][2] = # of 1-4 neighbors of atom i - // create onefour[i] = list of 1-4 neighbors for atom i - // ----------------------------------------------------- + tagint *tag = atom->tag; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; // ncount = # of my datums to send // include nlocal datums with owner of each atom - ncount = nlocal; - for (i = 0; i < nlocal; i++) ncount += nspecial[i][1]*nspecial[i][0]; + int ncount = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < nspecial[i][1]; j++) { + m = atom->map(onethree[i][j]); + if (m < 0 || m >= nlocal) ncount += nspecial[i][0]; + } + } + int *proclist; memory->create(proclist,ncount,"special:proclist"); - inbuf = (InRvous *) - memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); + PairRvous *inbuf = (PairRvous *) + memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // input datums = all pairs of onethree and onetwo atoms (they're 1-4 neighbors) @@ -296,22 +456,17 @@ void Special::build() // one datum for each owned atom: datum = owning proc, atomID // one datum for each onethree/onetwo pair: datum = atomID1, atomID2 - m = 0; + ncount = 0; for (i = 0; i < nlocal; i++) { - proclist[m] = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; - inbuf[m].me = me; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = 0; - m++; - for (j = 0; j < nspecial[i][1]; j++) { - proc = hashlittle(&onethree[i][j],sizeof(tagint),0) % nprocs; + m = atom->map(onethree[i][j]); + if (m >= 0 && m < nlocal) continue; + proc = onethree[i][j] % nprocs; for (k = 0; k < nspecial[i][0]; k++) { - proclist[m] = proc; - inbuf[m].me = -1; - inbuf[m].atomID = onethree[i][j]; - inbuf[m].partnerID = onetwo[i][k]; - m++; + proclist[ncount] = proc; + inbuf[ncount].atomID = onethree[i][j]; + inbuf[ncount].partnerID = onetwo[i][k]; + ncount++; } } } @@ -320,10 +475,12 @@ void Special::build() // each proc owns random subset of atoms // receives all info to form and return their onefour lists - nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), - rendezvous_1234, - buf,sizeof(OutRvous),(void *) this); - outbuf = (OutRvous *) buf; + char *buf; + int nreturn = comm->rendezvous(ncount,proclist, + (char *) inbuf,sizeof(PairRvous), + rendezvous_1234,buf,sizeof(PairRvous), + (void *) this); + PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); @@ -331,33 +488,43 @@ void Special::build() // set nspecial[2] and onefour for all owned atoms based on output info // output datums = pairs of atoms that are 1-4 neighbors - MPI_Allreduce(&max_rvous,&maxall,1,MPI_INT,MPI_MAX,world); - memory->create(onefour,nlocal,maxall,"special:onefour"); - - for (i = 0; i < nlocal; i++) nspecial[i][2] = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < nspecial[i][1]; j++) { + m = atom->map(onethree[i][j]); + if (m >= 0 && m < nlocal) nspecial[m][2] += nspecial[i][0]; + } + } for (m = 0; m < nreturn; m++) { i = atom->map(outbuf[m].atomID); - onefour[i][nspecial[i][2]++] = outbuf[m].partnerID; + nspecial[i][2]++; } + + int max = 0; + for (i = 0; i < nlocal; i++) + max = MAX(max,nspecial[i][2]); + + MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + memory->create(onefour,nlocal,maxall,"special:onefour"); - memory->destroy(outbuf); - - // compute and print max # of 1-4 neighbors + for (i = 0; i < nlocal; i++) nspecial[i][2] = 0; - if (me == 0) { - if (screen) fprintf(screen," %d = max # of 1-4 neighbors\n",maxall); - if (logfile) fprintf(logfile," %d = max # of 1-4 neighbors\n",maxall); + for (i = 0; i < nlocal; i++) { + for (j = 0; j < nspecial[i][1]; j++) { + m = atom->map(onethree[i][j]); + if (m < 0 || m >= nlocal) continue; + for (k = 0; k < nspecial[i][0]; k++) { + onefour[m][nspecial[m][2]++] = onetwo[i][k]; + } + } } - // finish processing the onetwo, onethree, onefour lists + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + onefour[i][nspecial[i][2]++] = outbuf[m].partnerID; + } - dedup(); - if (force->special_angle) angle_trim(); - if (force->special_dihedral) dihedral_trim(); - combine(); - fix_alteration(); - timer_output(time1); + memory->sfree(outbuf); } /* ---------------------------------------------------------------------- @@ -662,8 +829,8 @@ void Special::angle_trim() int *proclist; memory->create(proclist,ncount,"special:proclist"); - InRvous *inbuf = (InRvous *) - memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); + PairRvous *inbuf = (PairRvous *) + memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // one datum for each owned atom: datum = proc, atomID @@ -675,16 +842,9 @@ void Special::angle_trim() m = 0; for (i = 0; i < nlocal; i++) { - proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; - proclist[m] = proc; - inbuf[m].me = me; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = 0; - m++; - for (j = 0; j < nspecial[i][1]; j++) { proclist[m] = proc; - inbuf[m].me = -1; + //inbuf[m].me = -1; inbuf[m].atomID = tag[i]; inbuf[m].partnerID = onethree[i][j]; m++; @@ -695,13 +855,13 @@ void Special::angle_trim() if (index < 0 || index >= nlocal) continue; proclist[m] = hashlittle(&angle_atom1[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = angle_atom1[i][j]; inbuf[m].partnerID = angle_atom3[i][j]; m++; proclist[m] = hashlittle(&angle_atom3[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = angle_atom3[i][j]; inbuf[m].partnerID = angle_atom1[i][j]; m++; @@ -712,25 +872,25 @@ void Special::angle_trim() if (index < 0 || index >= nlocal) continue; proclist[m] = hashlittle(&dihedral_atom1[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = dihedral_atom1[i][j]; inbuf[m].partnerID = dihedral_atom3[i][j]; m++; proclist[m] = hashlittle(&dihedral_atom2[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = dihedral_atom2[i][j]; inbuf[m].partnerID = dihedral_atom4[i][j]; m++; proclist[m] = hashlittle(&dihedral_atom3[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = dihedral_atom3[i][j]; inbuf[m].partnerID = dihedral_atom1[i][j]; m++; proclist[m] = hashlittle(&dihedral_atom4[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = dihedral_atom4[i][j]; inbuf[m].partnerID = dihedral_atom2[i][j]; m++; @@ -743,10 +903,11 @@ void Special::angle_trim() // when done: each atom has atom ID of owning atom of its body char *buf; - int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), - rendezvous_trim, - buf,sizeof(OutRvous),(void *) this); - OutRvous *outbuf = (OutRvous *) buf; + int nreturn = comm->rendezvous(ncount,proclist, + (char *) inbuf,sizeof(PairRvous), + rendezvous_trim,buf,sizeof(PairRvous), + (void *) this); + PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); @@ -836,8 +997,8 @@ void Special::dihedral_trim() int *proclist; memory->create(proclist,ncount,"special:proclist"); - InRvous *inbuf = (InRvous *) - memory->smalloc((bigint) ncount*sizeof(InRvous),"special:inbuf"); + PairRvous *inbuf = (PairRvous *) + memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // one datum for each owned atom: datum = proc, atomID @@ -851,14 +1012,14 @@ void Special::dihedral_trim() for (i = 0; i < nlocal; i++) { proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; proclist[m] = proc; - inbuf[m].me = me; + //inbuf[m].me = me; inbuf[m].atomID = tag[i]; inbuf[m].partnerID = 0; m++; for (j = 0; j < nspecial[i][2]; j++) { proclist[m] = proc; - inbuf[m].me = -1; + //inbuf[m].me = -1; inbuf[m].atomID = tag[i]; inbuf[m].partnerID = onefour[i][j]; m++; @@ -869,13 +1030,13 @@ void Special::dihedral_trim() if (index < 0 || index >= nlocal) continue; proclist[m] = hashlittle(&dihedral_atom1[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = dihedral_atom1[i][j]; inbuf[m].partnerID = dihedral_atom4[i][j]; m++; proclist[m] = hashlittle(&dihedral_atom4[i][j],sizeof(tagint),0) % nprocs; - inbuf[m].me = -2; + //inbuf[m].me = -2; inbuf[m].atomID = dihedral_atom4[i][j]; inbuf[m].partnerID = dihedral_atom1[i][j]; m++; @@ -888,10 +1049,11 @@ void Special::dihedral_trim() // when done: each atom has atom ID of owning atom of its body char *buf; - int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), - rendezvous_trim, - buf,sizeof(OutRvous),(void *) this); - OutRvous *outbuf = (OutRvous *) buf; + int nreturn = comm->rendezvous(ncount,proclist, + (char *) inbuf,sizeof(PairRvous), + rendezvous_trim,buf,sizeof(PairRvous), + (void *) this); + PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); @@ -931,16 +1093,55 @@ void Special::dihedral_trim() /* ---------------------------------------------------------------------- process data for atoms assigned to me in rendezvous decomposition - inbuf = list of N InRvous datums - create outbuf = list of Nout OutRvous datums + inbuf = list of N PairRvous datums + outbuf = empty +------------------------------------------------------------------------- */ + +int Special::rendezvous_ids(int n, char *inbuf, + int &flag, int *&proclist, char *&outbuf, + void *ptr) +{ + Special *sptr = (Special *) ptr; + Memory *memory = sptr->memory; + + int *procowner; + tagint *atomIDs; + + memory->create(procowner,n,"special:procowner"); + memory->create(atomIDs,n,"special:atomIDs"); + // NOTE: when to free these vectors + + IDRvous *in = (IDRvous *) inbuf; + + for (int i = 0; i < n; i++) { + procowner[i] = in[i].me; + atomIDs[i] = in[i].atomID; + } + + // store rendezvous data in Special class + + sptr->ncount = n; + sptr->procowner = procowner; + sptr->atomIDs = atomIDs; + + proclist = NULL; + outbuf = NULL; + + flag = 0; + return 0; +} + + +/* ---------------------------------------------------------------------- + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N PairRvous datums + outbuf = same list of N PairRvous datums, routed to different procs ------------------------------------------------------------------------- */ int Special::rendezvous_1234(int n, char *inbuf, - int *&proclist, char *&outbuf, + int &flag, int *&proclist, char *&outbuf, void *ptr) { - int i,j,m; - Special *sptr = (Special *) ptr; Atom *atom = sptr->atom; Memory *memory = sptr->memory; @@ -950,105 +1151,52 @@ int Special::rendezvous_1234(int n, char *inbuf, atom->map_clear(); - // initialize hash - // ncount = number of atoms assigned to me - // key = atom ID - // value = index into Ncount-length data structure - - InRvous *in = (InRvous *) inbuf; - //std::map hash; - tagint id; + // hash atom IDs stored in rendezvous decomposition - int ncount = 0; - for (i = 0; i < n; i++) - if (in[i].me >= 0) - //hash[in[i].atomID] = ncount++; - atom->map_one(in[i].atomID,ncount++); - - // procowner = caller proc that owns each atom - // atomID = ID of each rendezvous atom I own + int ncount = sptr->ncount; + tagint *atomIDs = sptr->atomIDs; - int *procowner,*npartner; - tagint *atomID; - memory->create(procowner,ncount,"special:procowner"); - memory->create(atomID,ncount,"special:atomID"); - memory->create(npartner,ncount,"special:npartner"); - for (m = 0; m < ncount; m++) npartner[m] = 0; + for (int i = 0; i < ncount; i++) + atom->map_one(atomIDs[i],i); - for (i = 0; i < n; i++) { - //m = hash.find(in[i].atomID)->second; - m = atom->map(in[i].atomID); - if (in[i].me >= 0) { - procowner[m] = in[i].me; - atomID[m] = in[i].atomID; - } else npartner[m]++; - } - - int max = 0; - for (m = 0; m < ncount; m++) - max = MAX(max,npartner[m]); - sptr->max_rvous = max; - - int **partner; - memory->create(partner,ncount,max,"special:partner"); - for (m = 0; m < ncount; m++) npartner[m] = 0; + // proclist = owner of atomID in caller decomposition + + PairRvous *in = (PairRvous *) inbuf; + int *procowner = sptr->procowner; + memory->create(proclist,n,"special:proclist"); - for (i = 0; i < n; i++) { - if (in[i].me >= 0) continue; - //m = hash.find(in[i].atomID)->second; + int m; + for (int i = 0; i < n; i++) { m = atom->map(in[i].atomID); - partner[m][npartner[m]++] = in[i].partnerID; + proclist[i] = procowner[m]; } - // pass list of OutRvous datums back to comm->rendezvous - - int nout = 0; - for (m = 0; m < ncount; m++) nout += npartner[m]; - - memory->create(proclist,nout,"special:proclist"); - OutRvous *out = (OutRvous *) - memory->smalloc((bigint) nout*sizeof(OutRvous),"special:out"); - - nout = 0; - for (m = 0; m < ncount; m++) - for (j = 0; j < npartner[m]; j++) { - proclist[nout] = procowner[m]; - out[nout].atomID = atomID[m]; - out[nout].partnerID = partner[m][j]; - nout++; - } - - outbuf = (char *) out; - - // clean up - // Comm::rendezvous will delete proclist and out (outbuf) - - memory->destroy(procowner); - memory->destroy(atomID); - memory->destroy(npartner); - memory->destroy(partner); - + outbuf = inbuf; + // NOTE: set out = in flag + // re-create atom map atom->map_init(0); atom->nghost = 0; atom->map_set(); - return nout; + flag = 1; + return n; } /* ---------------------------------------------------------------------- process data for atoms assigned to me in rendezvous decomposition - inbuf = list of N InRvous datums - create outbuf = list of Nout OutRvous datums + inbuf = list of N PairRvous datums + create outbuf = list of Nout PairRvous datums ------------------------------------------------------------------------- */ int Special::rendezvous_trim(int n, char *inbuf, - int *&proclist, char *&outbuf, + int &flag, int *&proclist, char *&outbuf, void *ptr) { int i,j,m; + /* Special *sptr = (Special *) ptr; Atom *atom = sptr->atom; Memory *memory = sptr->memory; @@ -1063,7 +1211,7 @@ int Special::rendezvous_trim(int n, char *inbuf, // key = atom ID // value = index into Ncount-length data structure - InRvous *in = (InRvous *) inbuf; + PairRvous *in = (PairRvous *) inbuf; //std::map hash; tagint id; @@ -1131,14 +1279,14 @@ int Special::rendezvous_trim(int n, char *inbuf, } } - // pass list of OutRvous datums back to comm->rendezvous + // pass list of PairRvous datums back to comm->rendezvous int nout = 0; for (m = 0; m < ncount; m++) nout += npartner[m]; memory->create(proclist,nout,"special:proclist"); - OutRvous *out = (OutRvous *) - memory->smalloc((bigint) nout*sizeof(OutRvous),"special:out"); + PairRvous *out = (PairRvous *) + memory->smalloc((bigint) nout*sizeof(PairRvous),"special:out"); nout = 0; for (m = 0; m < ncount; m++) @@ -1167,7 +1315,11 @@ int Special::rendezvous_trim(int n, char *inbuf, atom->nghost = 0; atom->map_set(); - return nout; + */ + + //return nout; + flag = 2; + return 0; } /* ---------------------------------------------------------------------- diff --git a/src/special.h b/src/special.h index f7892075ac..772ba613ac 100644 --- a/src/special.h +++ b/src/special.h @@ -26,21 +26,30 @@ class Special : protected Pointers { private: int me,nprocs; + int maxall; tagint **onetwo,**onethree,**onefour; // data used by rendezvous callback methods - int max_rvous; + int ncount; + tagint *atomIDs; + int *procowner; - struct InRvous { + struct IDRvous { int me; - tagint atomID,partnerID; + tagint atomID; }; - struct OutRvous { + struct PairRvous { tagint atomID,partnerID; }; + void atom_owners(); + void onetwo_build_newton(); + void onetwo_build_newton_off(); + void onethree_build(); + void onefour_build(); + void dedup(); void angle_trim(); void dihedral_trim(); @@ -48,10 +57,11 @@ class Special : protected Pointers { void fix_alteration(); void timer_output(double); - // callback function for rendezvous communication + // callback functions for rendezvous communication - static int rendezvous_1234(int, char *, int *&, char *&, void *); - static int rendezvous_trim(int, char *, int *&, char *&, void *); + static int rendezvous_ids(int, char *, int &, int *&, char *&, void *); + static int rendezvous_1234(int, char *, int &, int *&, char *&, void *); + static int rendezvous_trim(int, char *, int &, int *&, char *&, void *); }; } -- GitLab From 7c3d6dc051976664acf315a321e2846c93d407e2 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 7 Dec 2018 16:43:01 -0700 Subject: [PATCH 0071/1243] propagate rendezvous changes to fix rigid/small --- src/RIGID/fix_rigid_small.cpp | 3 ++- src/RIGID/fix_rigid_small.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index fc51e0aa4f..3da516894c 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -1611,7 +1611,7 @@ void FixRigidSmall::create_bodies(tagint *bodyID) ------------------------------------------------------------------------- */ int FixRigidSmall::rendezvous_body(int n, char *inbuf, - int *&proclist, char *&outbuf, + int &rflag, int *&proclist, char *&outbuf, void *ptr) { int i,j,m; @@ -1749,6 +1749,7 @@ int FixRigidSmall::rendezvous_body(int n, char *inbuf, memory->destroy(iclose); memory->destroy(rsqclose); + rflag = 2; return nout; } diff --git a/src/RIGID/fix_rigid_small.h b/src/RIGID/fix_rigid_small.h index a820efcdea..f6ad1b7206 100644 --- a/src/RIGID/fix_rigid_small.h +++ b/src/RIGID/fix_rigid_small.h @@ -209,7 +209,7 @@ class FixRigidSmall : public Fix { // callback function for rendezvous communication - static int rendezvous_body(int, char *, int *&, char *&, void *); + static int rendezvous_body(int, char *, int &, int *&, char *&, void *); // debug -- GitLab From b068690e1392e0c5d6ff0c7faf2293ceab9a40fc Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 12 Dec 2018 16:21:54 -0600 Subject: [PATCH 0072/1243] Update for kim-api beta.3 release --- cmake/CMakeLists.txt | 6 +- .../log.11Jul2018.kim.lj.newton-off.ubuntu.1 | 68 ----------------- .../log.11Jul2018.kim.lj.newton-off.ubuntu.4 | 74 ------------------- .../log.11Jul2018.kim.lj.newton-on.ubuntu.1 | 68 ----------------- .../log.11Jul2018.kim.lj.newton-on.ubuntu.4 | 74 ------------------- ... log.12Dec2018.in.kim.lj.lmp.newton-off.1} | 37 ++++------ ... log.12Dec2018.in.kim.lj.lmp.newton-off.4} | 39 ++++------ ...> log.12Dec2018.in.kim.lj.lmp.newton-on.1} | 37 ++++------ ...> log.12Dec2018.in.kim.lj.lmp.newton-on.4} | 39 ++++------ .../kim/log.12Dec2018.in.kim.lj.newton-off.1 | 59 +++++++++++++++ .../kim/log.12Dec2018.in.kim.lj.newton-off.4 | 65 ++++++++++++++++ .../kim/log.12Dec2018.in.kim.lj.newton-on.1 | 59 +++++++++++++++ .../kim/log.12Dec2018.in.kim.lj.newton-on.4 | 65 ++++++++++++++++ lib/kim/.gitignore | 3 +- lib/kim/Install.py | 8 +- 15 files changed, 310 insertions(+), 391 deletions(-) delete mode 100644 examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 delete mode 100644 examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 delete mode 100644 examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 delete mode 100644 examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 rename examples/kim/{log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 => log.12Dec2018.in.kim.lj.lmp.newton-off.1} (56%) rename examples/kim/{log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 => log.12Dec2018.in.kim.lj.lmp.newton-off.4} (55%) rename examples/kim/{log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 => log.12Dec2018.in.kim.lj.lmp.newton-on.1} (56%) rename examples/kim/{log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 => log.12Dec2018.in.kim.lj.lmp.newton-on.4} (55%) create mode 100644 examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 create mode 100644 examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 create mode 100644 examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 create mode 100644 examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1e0d207a7e..4abbeb4732 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -590,8 +590,8 @@ if(PKG_KIM) enable_language(Fortran) include(ExternalProject) ExternalProject_Add(kim_build - URL https://s3.openkim.org/kim-api/kim-api-v2.0.0-beta.2.txz - URL_MD5 1fbdbb734059cf0dc9d807e6dd6cc8ea + URL https://s3.openkim.org/kim-api/kim-api-v2-2.0.0-beta.3.txz + URL_MD5 67c103a00e84865848d004837262c76e BINARY_DIR build CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} @@ -601,7 +601,7 @@ if(PKG_KIM) ) ExternalProject_get_property(kim_build INSTALL_DIR) set(KIM-API-V2_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) - set(KIM-API-V2_LIBRARIES ${INSTALL_DIR}/lib/libkim-api-v2.2${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(KIM-API-V2_LDFLAGS ${INSTALL_DIR}/lib/libkim-api-v2.2${CMAKE_SHARED_LIBRARY_SUFFIX}) list(APPEND LAMMPS_DEPS kim_build) else() find_package(KIM-API-V2) diff --git a/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 b/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 deleted file mode 100644 index c8c1919de5..0000000000 --- a/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.1 +++ /dev/null @@ -1,68 +0,0 @@ --------------------------------------------------------------------------- -[[5713,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 1 by 1 MPI processor grid -Created 32000 atoms - Time spent = 0.00256546 secs -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 8.45 - ghost atom cutoff = 8.45 - binsize = 4.225, bins = 21 21 21 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair kim, perpetual - attributes: half, newton off, cut 8.45 - pair build: half/bin/newtoff - stencil: half/bin/3d/newtoff - bin: standard -Setting up Verlet run ... - Unit style : metal - Current step : 0 - Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 21.26 | 21.26 | 21.26 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 6290.8194 0 7118.0584 129712.25 - 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.69522 on 1 procs for 100 steps with 32000 atoms - -Performance: 3.206 ns/day, 7.487 hours/ns, 37.103 timesteps/s -99.8% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 2.3655 | 2.3655 | 2.3655 | 0.0 | 87.77 -Neigh | 0.28659 | 0.28659 | 0.28659 | 0.0 | 10.63 -Comm | 0.0061924 | 0.0061924 | 0.0061924 | 0.0 | 0.23 -Output | 0.00034901 | 0.00034901 | 0.00034901 | 0.0 | 0.01 -Modify | 0.025061 | 0.025061 | 0.025061 | 0.0 | 0.93 -Other | | 0.01157 | | | 0.43 - -Nlocal: 32000 ave 32000 max 32000 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 19911 ave 19911 max 19911 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 2.3705e+06 ave 2.3705e+06 max 2.3705e+06 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 2370499 -Ave neighs/atom = 74.0781 -Neighbor list builds = 3 -Dangerous builds = 0 -Total wall time: 0:00:02 diff --git a/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 b/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 deleted file mode 100644 index c8d5faeb20..0000000000 --- a/examples/kim/log.11Jul2018.kim.lj.newton-off.ubuntu.4 +++ /dev/null @@ -1,74 +0,0 @@ --------------------------------------------------------------------------- -[[5673,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 2 by 2 MPI processor grid -Created 32000 atoms - Time spent = 0.00215514 secs -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 8.45 - ghost atom cutoff = 8.45 - binsize = 4.225, bins = 21 21 21 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair kim, perpetual - attributes: half, newton off, cut 8.45 - pair build: half/bin/newtoff - stencil: half/bin/3d/newtoff - bin: standard -Setting up Verlet run ... - Unit style : metal - Current step : 0 - Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 8.528 | 8.528 | 8.528 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 6290.8194 0 7118.0584 129712.25 - 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 3.06157 on 4 procs for 100 steps with 32000 atoms - -Performance: 2.822 ns/day, 8.504 hours/ns, 32.663 timesteps/s -24.4% CPU use with 4 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 1.9964 | 2.0369 | 2.084 | 2.5 | 66.53 -Neigh | 0.25048 | 0.27467 | 0.29605 | 3.1 | 8.97 -Comm | 0.66611 | 0.71603 | 0.74496 | 3.6 | 23.39 -Output | 0.00048383 | 0.00070085 | 0.00098836 | 0.0 | 0.02 -Modify | 0.0064885 | 0.0065907 | 0.006806 | 0.2 | 0.22 -Other | | 0.02664 | | | 0.87 - -Nlocal: 8000 ave 8018 max 7967 min -Histogram: 1 0 0 0 0 0 1 0 0 2 -Nghost: 9131 ave 9164 max 9113 min -Histogram: 2 0 0 1 0 0 0 0 0 1 -Neighs: 630904 ave 632094 max 628209 min -Histogram: 1 0 0 0 0 0 0 1 0 2 - -Total # of neighbors = 2523614 -Ave neighs/atom = 78.8629 -Neighbor list builds = 3 -Dangerous builds = 0 -Total wall time: 0:00:03 diff --git a/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 b/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 deleted file mode 100644 index 21af1a6299..0000000000 --- a/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.1 +++ /dev/null @@ -1,68 +0,0 @@ --------------------------------------------------------------------------- -[[5690,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 1 by 1 MPI processor grid -Created 32000 atoms - Time spent = 0.00258302 secs -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 8.45 - ghost atom cutoff = 8.45 - binsize = 4.225, bins = 21 21 21 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair kim, perpetual - attributes: half, newton off, cut 8.45 - pair build: half/bin/newtoff - stencil: half/bin/3d/newtoff - bin: standard -Setting up Verlet run ... - Unit style : metal - Current step : 0 - Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 20.87 | 20.87 | 20.87 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 6290.8194 0 7118.0584 129712.25 - 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.7052 on 1 procs for 100 steps with 32000 atoms - -Performance: 3.194 ns/day, 7.514 hours/ns, 36.966 timesteps/s -99.6% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 2.3715 | 2.3715 | 2.3715 | 0.0 | 87.67 -Neigh | 0.28386 | 0.28386 | 0.28386 | 0.0 | 10.49 -Comm | 0.012808 | 0.012808 | 0.012808 | 0.0 | 0.47 -Output | 0.00033716 | 0.00033716 | 0.00033716 | 0.0 | 0.01 -Modify | 0.02349 | 0.02349 | 0.02349 | 0.0 | 0.87 -Other | | 0.01317 | | | 0.49 - -Nlocal: 32000 ave 32000 max 32000 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 19911 ave 19911 max 19911 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 2.3705e+06 ave 2.3705e+06 max 2.3705e+06 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 2370499 -Ave neighs/atom = 74.0781 -Neighbor list builds = 3 -Dangerous builds = 0 -Total wall time: 0:00:02 diff --git a/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 b/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 deleted file mode 100644 index 1214436d4d..0000000000 --- a/examples/kim/log.11Jul2018.kim.lj.newton-on.ubuntu.4 +++ /dev/null @@ -1,74 +0,0 @@ --------------------------------------------------------------------------- -[[5682,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) -Lattice spacing in x,y,z = 4.43 4.43 4.43 -Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) - 1 by 2 by 2 MPI processor grid -Created 32000 atoms - Time spent = 0.00322684 secs -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (../pair_kim.cpp:955) -WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (../pair_kim.cpp:959) -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 8.45 - ghost atom cutoff = 8.45 - binsize = 4.225, bins = 21 21 21 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair kim, perpetual - attributes: half, newton off, cut 8.45 - pair build: half/bin/newtoff - stencil: half/bin/3d/newtoff - bin: standard -Setting up Verlet run ... - Unit style : metal - Current step : 0 - Time step : 0.001 -Per MPI rank memory allocation (min/avg/max) = 8.263 | 8.263 | 8.263 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 200 6290.8194 0 7118.0584 129712.25 - 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 3.1366 on 4 procs for 100 steps with 32000 atoms - -Performance: 2.755 ns/day, 8.713 hours/ns, 31.882 timesteps/s -23.7% CPU use with 4 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 1.3641 | 1.4213 | 1.4783 | 3.5 | 45.31 -Neigh | 0.25408 | 0.27714 | 0.29697 | 3.2 | 8.84 -Comm | 1.3588 | 1.4045 | 1.4806 | 4.0 | 44.78 -Output | 0.00055232 | 0.00072915 | 0.00087484 | 0.0 | 0.02 -Modify | 0.0061178 | 0.0062019 | 0.0062811 | 0.1 | 0.20 -Other | | 0.02673 | | | 0.85 - -Nlocal: 8000 ave 8018 max 7967 min -Histogram: 1 0 0 0 0 0 1 0 0 2 -Nghost: 9131 ave 9164 max 9113 min -Histogram: 2 0 0 1 0 0 0 0 0 1 -Neighs: 630904 ave 632094 max 628209 min -Histogram: 1 0 0 0 0 0 0 1 0 2 - -Total # of neighbors = 2523614 -Ave neighs/atom = 78.8629 -Neighbor list builds = 3 -Dangerous builds = 0 -Total wall time: 0:00:03 diff --git a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.1 similarity index 56% rename from examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 rename to examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.1 index bf5864cb08..0b67cc1ccb 100644 --- a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.1 +++ b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.1 @@ -1,22 +1,11 @@ --------------------------------------------------------------------------- -[[6124,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00263722 secs + Time spent = 0.00307703 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 20.37 | 20.37 | 20.37 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.59913 on 1 procs for 100 steps with 32000 atoms +Loop time of 2.58348 on 1 procs for 100 steps with 32000 atoms -Performance: 3.324 ns/day, 7.220 hours/ns, 38.474 timesteps/s -99.4% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 3.344 ns/day, 7.176 hours/ns, 38.707 timesteps/s +99.9% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.2753 | 2.2753 | 2.2753 | 0.0 | 87.54 -Neigh | 0.28456 | 0.28456 | 0.28456 | 0.0 | 10.95 -Comm | 0.0055908 | 0.0055908 | 0.0055908 | 0.0 | 0.22 -Output | 0.00034594 | 0.00034594 | 0.00034594 | 0.0 | 0.01 -Modify | 0.023011 | 0.023011 | 0.023011 | 0.0 | 0.89 -Other | | 0.01037 | | | 0.40 +Pair | 2.2621 | 2.2621 | 2.2621 | 0.0 | 87.56 +Neigh | 0.28294 | 0.28294 | 0.28294 | 0.0 | 10.95 +Comm | 0.0057185 | 0.0057185 | 0.0057185 | 0.0 | 0.22 +Output | 0.00010109 | 0.00010109 | 0.00010109 | 0.0 | 0.00 +Modify | 0.023396 | 0.023396 | 0.023396 | 0.0 | 0.91 +Other | | 0.009175 | | | 0.36 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.4 similarity index 55% rename from examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 rename to examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.4 index 7f51d447fd..e2ee8e39bb 100644 --- a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-off.ubuntu.4 +++ b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.4 @@ -1,22 +1,11 @@ --------------------------------------------------------------------------- -[[6116,1],1]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00125703 secs + Time spent = 0.000934124 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 8.013 | 8.013 | 8.013 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.99901 on 4 procs for 100 steps with 32000 atoms +Loop time of 0.76167 on 4 procs for 100 steps with 32000 atoms -Performance: 2.881 ns/day, 8.331 hours/ns, 33.344 timesteps/s -24.4% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 11.343 ns/day, 2.116 hours/ns, 131.290 timesteps/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 1.3704 | 1.4012 | 1.439 | 2.3 | 46.72 -Neigh | 0.252 | 0.27028 | 0.28236 | 2.2 | 9.01 -Comm | 0.66355 | 0.73942 | 0.82223 | 6.5 | 24.66 -Output | 0.0037821 | 0.0090774 | 0.016142 | 5.1 | 0.30 -Modify | 0.0058855 | 0.019317 | 0.044855 | 11.4 | 0.64 -Other | | 0.5597 | | | 18.66 +Pair | 0.65549 | 0.6589 | 0.66089 | 0.3 | 86.51 +Neigh | 0.075691 | 0.075959 | 0.07641 | 0.1 | 9.97 +Comm | 0.0073049 | 0.007397 | 0.0074785 | 0.1 | 0.97 +Output | 5.6982e-05 | 0.00014746 | 0.00024986 | 0.0 | 0.02 +Modify | 0.0068338 | 0.0068703 | 0.0068941 | 0.0 | 0.90 +Other | | 0.0124 | | | 1.63 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 @@ -63,4 +52,4 @@ Total # of neighbors = 2523614 Ave neighs/atom = 78.8629 Neighbor list builds = 3 Dangerous builds = 0 -Total wall time: 0:00:03 +Total wall time: 0:00:00 diff --git a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.1 similarity index 56% rename from examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 rename to examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.1 index 7be22a7f60..91731438de 100644 --- a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.1 +++ b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.1 @@ -1,22 +1,11 @@ --------------------------------------------------------------------------- -[[5635,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00226572 secs + Time spent = 0.00311494 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 19.23 | 19.23 | 19.23 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.26274 on 1 procs for 100 steps with 32000 atoms +Loop time of 2.22646 on 1 procs for 100 steps with 32000 atoms -Performance: 3.818 ns/day, 6.285 hours/ns, 44.194 timesteps/s -99.0% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 3.881 ns/day, 6.185 hours/ns, 44.914 timesteps/s +99.9% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.0589 | 2.0589 | 2.0589 | 0.0 | 90.99 -Neigh | 0.15362 | 0.15362 | 0.15362 | 0.0 | 6.79 -Comm | 0.012277 | 0.012277 | 0.012277 | 0.0 | 0.54 -Output | 0.0003387 | 0.0003387 | 0.0003387 | 0.0 | 0.01 -Modify | 0.02416 | 0.02416 | 0.02416 | 0.0 | 1.07 -Other | | 0.01346 | | | 0.59 +Pair | 2.0344 | 2.0344 | 2.0344 | 0.0 | 91.38 +Neigh | 0.14575 | 0.14575 | 0.14575 | 0.0 | 6.55 +Comm | 0.01127 | 0.01127 | 0.01127 | 0.0 | 0.51 +Output | 0.000103 | 0.000103 | 0.000103 | 0.0 | 0.00 +Modify | 0.024057 | 0.024057 | 0.024057 | 0.0 | 1.08 +Other | | 0.01083 | | | 0.49 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.4 similarity index 55% rename from examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 rename to examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.4 index d910afbbc2..92eb8ba8bc 100644 --- a/examples/kim/log.11Jul2018.kim.lj.lmp.newton-on.ubuntu.4 +++ b/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.4 @@ -1,22 +1,11 @@ --------------------------------------------------------------------------- -[[5659,1],0]: A high-performance Open MPI point-to-point messaging module -was unable to find any relevant network interfaces: - -Module: OpenFabrics (openib) - Host: ubuntu-artful - -Another transport will be used instead, although this may result in -lower performance. - -NOTE: You can disable this warning by setting the MCA parameter -btl_base_warn_component_unused to 0. --------------------------------------------------------------------------- -LAMMPS (22 Jun 2018) +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00213171 secs + Time spent = 0.000946045 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -37,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 7.632 | 7.632 | 7.632 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.44628 on 4 procs for 100 steps with 32000 atoms +Loop time of 0.639437 on 4 procs for 100 steps with 32000 atoms -Performance: 3.532 ns/day, 6.795 hours/ns, 40.878 timesteps/s -24.2% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 13.512 ns/day, 1.776 hours/ns, 156.388 timesteps/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.98717 | 1.0434 | 1.1582 | 6.6 | 42.65 -Neigh | 0.10195 | 0.12588 | 0.15258 | 5.2 | 5.15 -Comm | 1.1525 | 1.2449 | 1.3061 | 5.1 | 50.89 -Output | 0.0005828 | 0.00075188 | 0.00087256 | 0.0 | 0.03 -Modify | 0.0057955 | 0.0059132 | 0.006044 | 0.1 | 0.24 -Other | | 0.02542 | | | 1.04 +Pair | 0.55655 | 0.55752 | 0.55833 | 0.1 | 87.19 +Neigh | 0.040557 | 0.040752 | 0.041148 | 0.1 | 6.37 +Comm | 0.024693 | 0.025886 | 0.026853 | 0.5 | 4.05 +Output | 4.6015e-05 | 5.1558e-05 | 6.0081e-05 | 0.0 | 0.01 +Modify | 0.0088108 | 0.0089263 | 0.0090554 | 0.1 | 1.40 +Other | | 0.006306 | | | 0.99 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 @@ -63,4 +52,4 @@ Total # of neighbors = 2126875 Ave neighs/atom = 66.4648 Neighbor list builds = 3 Dangerous builds = 0 -Total wall time: 0:00:02 +Total wall time: 0:00:00 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 b/examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 new file mode 100644 index 0000000000..c25368b917 --- /dev/null +++ b/examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 @@ -0,0 +1,59 @@ +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 1 by 1 MPI processor grid +Created 32000 atoms + Time spent = 0.00450015 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: full, newton off, cut 8.45 + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 28.51 | 28.51 | 28.51 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 3.35585 on 1 procs for 100 steps with 32000 atoms + +Performance: 2.575 ns/day, 9.322 hours/ns, 29.799 timesteps/s +99.2% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.9239 | 2.9239 | 2.9239 | 0.0 | 87.13 +Neigh | 0.38492 | 0.38492 | 0.38492 | 0.0 | 11.47 +Comm | 0.0072038 | 0.0072038 | 0.0072038 | 0.0 | 0.21 +Output | 0.00010204 | 0.00010204 | 0.00010204 | 0.0 | 0.00 +Modify | 0.028316 | 0.028316 | 0.028316 | 0.0 | 0.84 +Other | | 0.01146 | | | 0.34 + +Nlocal: 32000 ave 32000 max 32000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19911 ave 19911 max 19911 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 4.25375e+06 ave 4.25375e+06 max 4.25375e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 4253750 +Ave neighs/atom = 132.93 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 b/examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 new file mode 100644 index 0000000000..c8c52d6e09 --- /dev/null +++ b/examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 @@ -0,0 +1,65 @@ +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.00106215 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: full, newton off, cut 8.45 + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 10.05 | 10.05 | 10.05 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 0.930494 on 4 procs for 100 steps with 32000 atoms + +Performance: 9.285 ns/day, 2.585 hours/ns, 107.470 timesteps/s +99.5% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.80926 | 0.81195 | 0.81464 | 0.3 | 87.26 +Neigh | 0.089949 | 0.092688 | 0.095287 | 0.8 | 9.96 +Comm | 0.007302 | 0.0074284 | 0.0075471 | 0.1 | 0.80 +Output | 0.00012898 | 0.00014371 | 0.00016093 | 0.0 | 0.02 +Modify | 0.011517 | 0.011761 | 0.011959 | 0.2 | 1.26 +Other | | 0.006522 | | | 0.70 + +Nlocal: 8000 ave 8018 max 7967 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Nghost: 9131 ave 9164 max 9113 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 1.06344e+06 ave 1.06594e+06 max 1.05881e+06 min +Histogram: 1 0 0 0 0 0 1 0 0 2 + +Total # of neighbors = 4253750 +Ave neighs/atom = 132.93 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 b/examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 new file mode 100644 index 0000000000..eec26307ac --- /dev/null +++ b/examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 @@ -0,0 +1,59 @@ +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 1 by 1 MPI processor grid +Created 32000 atoms + Time spent = 0.0030508 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: full, newton off, cut 8.45 + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 28.12 | 28.12 | 28.12 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 2.97001 on 1 procs for 100 steps with 32000 atoms + +Performance: 2.909 ns/day, 8.250 hours/ns, 33.670 timesteps/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.5982 | 2.5982 | 2.5982 | 0.0 | 87.48 +Neigh | 0.32516 | 0.32516 | 0.32516 | 0.0 | 10.95 +Comm | 0.012059 | 0.012059 | 0.012059 | 0.0 | 0.41 +Output | 0.000103 | 0.000103 | 0.000103 | 0.0 | 0.00 +Modify | 0.023878 | 0.023878 | 0.023878 | 0.0 | 0.80 +Other | | 0.01058 | | | 0.36 + +Nlocal: 32000 ave 32000 max 32000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19911 ave 19911 max 19911 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 4.25375e+06 ave 4.25375e+06 max 4.25375e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 4253750 +Ave neighs/atom = 132.93 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 b/examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 new file mode 100644 index 0000000000..6c0da32ba4 --- /dev/null +++ b/examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 @@ -0,0 +1,65 @@ +LAMMPS (24 Oct 2018) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +Lattice spacing in x,y,z = 4.43 4.43 4.43 +Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) + 1 by 2 by 2 MPI processor grid +Created 32000 atoms + Time spent = 0.000946999 secs +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) +WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 8.45 + ghost atom cutoff = 8.45 + binsize = 4.225, bins = 21 21 21 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair kim, perpetual + attributes: full, newton off, cut 8.45 + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Setting up Verlet run ... + Unit style : metal + Current step : 0 + Time step : 0.001 +Per MPI rank memory allocation (min/avg/max) = 9.789 | 9.789 | 9.789 Mbytes +Step Temp E_pair E_mol TotEng Press + 0 200 6290.8194 0 7118.0584 129712.25 + 100 95.179725 6718.814 0 7112.496 133346.59 +Loop time of 0.891065 on 4 procs for 100 steps with 32000 atoms + +Performance: 9.696 ns/day, 2.475 hours/ns, 112.225 timesteps/s +99.8% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.75777 | 0.75864 | 0.75996 | 0.1 | 85.14 +Neigh | 0.088332 | 0.088883 | 0.089737 | 0.2 | 9.97 +Comm | 0.027187 | 0.02829 | 0.029602 | 0.6 | 3.17 +Output | 4.9114e-05 | 5.4777e-05 | 6.6042e-05 | 0.0 | 0.01 +Modify | 0.0088358 | 0.0089488 | 0.0091376 | 0.1 | 1.00 +Other | | 0.00625 | | | 0.70 + +Nlocal: 8000 ave 8018 max 7967 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Nghost: 9131 ave 9164 max 9113 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 1.06344e+06 ave 1.06594e+06 max 1.05881e+06 min +Histogram: 1 0 0 0 0 0 1 0 0 2 + +Total # of neighbors = 4253750 +Ave neighs/atom = 132.93 +Neighbor list builds = 3 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/lib/kim/.gitignore b/lib/kim/.gitignore index c1f57fe64c..bfd4b35d87 100644 --- a/lib/kim/.gitignore +++ b/lib/kim/.gitignore @@ -1,3 +1,2 @@ -/Makefile.KIM_DIR -/Makefile.KIM_Config +/kim-prefix.txt /installed-kim-api-* diff --git a/lib/kim/Install.py b/lib/kim/Install.py index 815827b645..b1dcee1a36 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -21,7 +21,7 @@ Syntax from lib dir: python Install.py -b -v version -a kim-name specify one or more options, order does not matter -v = version of KIM API library to use - default = kim-api-v2.0.0-beta.2 (current as of November 2018) + default = kim-api-v2.0.0-beta.3 (current as of December 2018) -b = download and build base KIM API library with example Models this will delete any previous installation in the current folder -n = do NOT download and build base KIM API library. @@ -36,9 +36,9 @@ specify one or more options, order does not matter Examples: make lib-kim args="-b" # install KIM API lib with only example models -make lib-kim args="-a Glue_Ercolessi_Adams_Al__MO_324507536345_002" # Ditto plus one model +make lib-kim args="-a EAM_ErcolessiAdams_1994_Al__MO_324507536345_002" # Ditto plus one model make lib-kim args="-b -a everything" # install KIM API lib with all models -make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_003" # only add one model or model driver +make lib-kim args="-n -a EAM_Dynamo_Ackland_2003_W__MO_141627196590_005" # only add one model or model driver See the list of KIM model drivers here: https://openkim.org/kim-items/model-drivers/alphabetical @@ -109,7 +109,7 @@ nargs = len(args) if nargs == 0: error() thisdir = os.environ['PWD'] -version = "kim-api-v2.0.0-beta.2" +version = "kim-api-v2-2.0.0-beta.3" buildflag = False everythingflag = False -- GitLab From e538fd5c6d9594edc15554f8bded8cd9baa32704 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 12 Dec 2018 17:14:56 -0700 Subject: [PATCH 0073/1243] added rendezvous alg to fix shake --- src/RIGID/fix_rigid_small.cpp | 6 +- src/RIGID/fix_shake.cpp | 787 +++++++++++++++++++++++----------- src/RIGID/fix_shake.h | 43 +- src/special.cpp | 649 ++++++++++++++-------------- src/special.h | 7 +- 5 files changed, 903 insertions(+), 589 deletions(-) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index 3da516894c..e20c64487b 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -414,9 +414,9 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : if (comm->me == 0) { if (screen) - fprintf(screen," create_bodies CPU = %g secs\n",time2-time1); + fprintf(screen," create bodies CPU = %g secs\n",time2-time1); if (logfile) - fprintf(logfile," create_bodies CPU = %g secs\n",time2-time1); + fprintf(logfile," create bodies CPU = %g secs\n",time2-time1); } // set nlocal_body and allocate bodies I own @@ -1749,6 +1749,8 @@ int FixRigidSmall::rendezvous_body(int n, char *inbuf, memory->destroy(iclose); memory->destroy(rsqclose); + // flag = 2: new outbuf + rflag = 2; return nout; } diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index e0d1bf132b..66c92d42c5 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -219,8 +219,19 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) : // identify all SHAKE clusters + double time1 = MPI_Wtime(); + find_clusters(); + double time2 = MPI_Wtime(); + + if (comm->me == 0) { + if (screen) + fprintf(screen," find clusters CPU = %g secs\n",time2-time1); + if (logfile) + fprintf(logfile," find clusters CPU = %g secs\n",time2-time1); + } + // initialize list of SHAKE clusters to constrain maxlist = 0; @@ -707,13 +718,6 @@ void FixShake::find_clusters() int nlocal = atom->nlocal; int angles_allow = atom->avec->angles_allow; - // setup ring of procs - - int next = me + 1; - int prev = me -1; - if (next == nprocs) next = 0; - if (prev < 0) prev = nprocs - 1; - // ----------------------------------------------------- // allocate arrays for self (1d) and bond partners (2d) // max = max # of bond partners for owned atoms = 2nd dim of partner arrays @@ -755,6 +759,10 @@ void FixShake::find_clusters() memory->create(partner_shake,nlocal,max,"shake:partner_shake"); memory->create(partner_nshake,nlocal,max,"shake:partner_nshake"); + // setup atomIDs and procowner vectors in rendezvous decomposition + + atom_owners(); + // ----------------------------------------------------- // set npartner and partner_tag from special arrays // ----------------------------------------------------- @@ -778,86 +786,13 @@ void FixShake::find_clusters() } // ----------------------------------------------------- - // set partner_mask, partner_type, partner_massflag, partner_bondtype - // for bonded partners - // requires communication for off-proc partners + // set partner_mask, partner_type, partner_massflag, + // partner_bondtype for all my bonded partners + // requires rendezvous communication for off-proc partners // ----------------------------------------------------- - // fill in mask, type, massflag, bondtype if own bond partner - // info to store in buf for each off-proc bond = nper = 6 - // 2 atoms IDs in bond, space for mask, type, massflag, bondtype - // nbufmax = largest buffer needed to hold info from any proc - - int nper = 6; - - nbuf = 0; - for (i = 0; i < nlocal; i++) { - for (j = 0; j < npartner[i]; j++) { - partner_mask[i][j] = 0; - partner_type[i][j] = 0; - partner_massflag[i][j] = 0; - partner_bondtype[i][j] = 0; - - m = atom->map(partner_tag[i][j]); - if (m >= 0 && m < nlocal) { - partner_mask[i][j] = mask[m]; - partner_type[i][j] = type[m]; - if (nmass) { - if (rmass) massone = rmass[m]; - else massone = mass[type[m]]; - partner_massflag[i][j] = masscheck(massone); - } - n = bondtype_findset(i,tag[i],partner_tag[i][j],0); - if (n) partner_bondtype[i][j] = n; - else { - n = bondtype_findset(m,tag[i],partner_tag[i][j],0); - if (n) partner_bondtype[i][j] = n; - } - } else nbuf += nper; - } - } - - memory->create(buf,nbuf,"shake:buf"); - - // fill buffer with info - - size = 0; - for (i = 0; i < nlocal; i++) { - for (j = 0; j < npartner[i]; j++) { - m = atom->map(partner_tag[i][j]); - if (m < 0 || m >= nlocal) { - buf[size] = tag[i]; - buf[size+1] = partner_tag[i][j]; - buf[size+2] = 0; - buf[size+3] = 0; - buf[size+4] = 0; - n = bondtype_findset(i,tag[i],partner_tag[i][j],0); - if (n) buf[size+5] = n; - else buf[size+5] = 0; - size += nper; - } - } - } - - // cycle buffer around ring of procs back to self - - comm->ring(size,sizeof(tagint),buf,1,ring_bonds,buf,(void *)this); - - // store partner info returned to me - - m = 0; - while (m < size) { - i = atom->map(buf[m]); - for (j = 0; j < npartner[i]; j++) - if (buf[m+1] == partner_tag[i][j]) break; - partner_mask[i][j] = buf[m+2]; - partner_type[i][j] = buf[m+3]; - partner_massflag[i][j] = buf[m+4]; - partner_bondtype[i][j] = buf[m+5]; - m += nper; - } - - memory->destroy(buf); + partner_info(npartner,partner_tag,partner_mask,partner_type, + partner_massflag,partner_bondtype); // error check for unfilled partner info // if partner_type not set, is an error @@ -868,17 +803,18 @@ void FixShake::find_clusters() // else it's an error flag = 0; + int flag2 = 0; for (i = 0; i < nlocal; i++) for (j = 0; j < npartner[i]; j++) { - if (partner_type[i][j] == 0) flag = 1; + if (partner_type[i][j] == 0) flag++; if (!(mask[i] & groupbit)) continue; if (!(partner_mask[i][j] & groupbit)) continue; - if (partner_bondtype[i][j] == 0) flag = 1; + if (partner_bondtype[i][j] == 0) flag2++; } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) error->all(FLERR,"Did not find fix shake partner info"); - + // ----------------------------------------------------- // identify SHAKEable bonds // set nshake[i] = # of SHAKE bonds attached to atom i @@ -931,56 +867,11 @@ void FixShake::find_clusters() // ----------------------------------------------------- // set partner_nshake for bonded partners - // requires communication for off-proc partners + // requires rendezvous communication for off-proc partners // ----------------------------------------------------- - // fill in partner_nshake if own bond partner - // info to store in buf for each off-proc bond = - // 2 atoms IDs in bond, space for nshake value - // nbufmax = largest buffer needed to hold info from any proc - - nbuf = 0; - for (i = 0; i < nlocal; i++) { - for (j = 0; j < npartner[i]; j++) { - m = atom->map(partner_tag[i][j]); - if (m >= 0 && m < nlocal) partner_nshake[i][j] = nshake[m]; - else nbuf += 3; - } - } - - memory->create(buf,nbuf,"shake:buf"); - - // fill buffer with info - - size = 0; - for (i = 0; i < nlocal; i++) { - for (j = 0; j < npartner[i]; j++) { - m = atom->map(partner_tag[i][j]); - if (m < 0 || m >= nlocal) { - buf[size] = tag[i]; - buf[size+1] = partner_tag[i][j]; - size += 3; - } - } - } - - // cycle buffer around ring of procs back to self - - comm->ring(size,sizeof(tagint),buf,2,ring_nshake,buf,(void *)this); - - // store partner info returned to me - - m = 0; - while (m < size) { - i = atom->map(buf[m]); - for (j = 0; j < npartner[i]; j++) - if (buf[m+1] == partner_tag[i][j]) break; - partner_nshake[i][j] = buf[m+2]; - m += 3; - } - - memory->destroy(buf); - + nshake_info(npartner,partner_tag,partner_nshake); + // ----------------------------------------------------- // error checks // no atom with nshake > 3 @@ -988,7 +879,7 @@ void FixShake::find_clusters() // ----------------------------------------------------- flag = 0; - for (i = 0; i < nlocal; i++) if (nshake[i] > 3) flag = 1; + for (i = 0; i < nlocal; i++) if (nshake[i] > 3) flag++; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) error->all(FLERR,"Shake cluster of more than 4 atoms"); @@ -996,7 +887,7 @@ void FixShake::find_clusters() for (i = 0; i < nlocal; i++) { if (nshake[i] <= 1) continue; for (j = 0; j < npartner[i]; j++) - if (partner_shake[i][j] && partner_nshake[i][j] > 1) flag = 1; + if (partner_shake[i][j] && partner_nshake[i][j] > 1) flag++; } MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) error->all(FLERR,"Shake clusters are connected"); @@ -1067,60 +958,7 @@ void FixShake::find_clusters() // requires communication for off-proc atoms // ----------------------------------------------------- - // fill in shake arrays for each bond partner I own - // info to store in buf for each off-proc bond = - // all values from shake_flag, shake_atom, shake_type - // nbufmax = largest buffer needed to hold info from any proc - - nbuf = 0; - for (i = 0; i < nlocal; i++) { - if (shake_flag[i] == 0) continue; - for (j = 0; j < npartner[i]; j++) { - if (partner_shake[i][j] == 0) continue; - m = atom->map(partner_tag[i][j]); - if (m >= 0 && m < nlocal) { - shake_flag[m] = shake_flag[i]; - shake_atom[m][0] = shake_atom[i][0]; - shake_atom[m][1] = shake_atom[i][1]; - shake_atom[m][2] = shake_atom[i][2]; - shake_atom[m][3] = shake_atom[i][3]; - shake_type[m][0] = shake_type[i][0]; - shake_type[m][1] = shake_type[i][1]; - shake_type[m][2] = shake_type[i][2]; - } else nbuf += 9; - } - } - - memory->create(buf,nbuf,"shake:buf"); - - // fill buffer with info - - size = 0; - for (i = 0; i < nlocal; i++) { - if (shake_flag[i] == 0) continue; - for (j = 0; j < npartner[i]; j++) { - if (partner_shake[i][j] == 0) continue; - m = atom->map(partner_tag[i][j]); - if (m < 0 || m >= nlocal) { - buf[size] = partner_tag[i][j]; - buf[size+1] = shake_flag[i]; - buf[size+2] = shake_atom[i][0]; - buf[size+3] = shake_atom[i][1]; - buf[size+4] = shake_atom[i][2]; - buf[size+5] = shake_atom[i][3]; - buf[size+6] = shake_type[i][0]; - buf[size+7] = shake_type[i][1]; - buf[size+8] = shake_type[i][2]; - size += 9; - } - } - } - - // cycle buffer around ring of procs back to self - - comm->ring(size,sizeof(tagint),buf,3,ring_shake,NULL,(void *)this); - - memory->destroy(buf); + shake_info(npartner,partner_tag,partner_shake); // ----------------------------------------------------- // free local memory @@ -1199,98 +1037,549 @@ void FixShake::find_clusters() } /* ---------------------------------------------------------------------- - when receive buffer, scan bond partner IDs for atoms I own - if I own partner: - fill in mask and type and massflag - search for bond with 1st atom and fill in bondtype + setup atomIDs and procowner ------------------------------------------------------------------------- */ -void FixShake::ring_bonds(int ndatum, char *cbuf, void *ptr) +void FixShake::atom_owners() { - FixShake *fsptr = (FixShake *)ptr; - Atom *atom = fsptr->atom; + tagint *tag = atom->tag; + int nlocal = atom->nlocal; + + int *proclist; + memory->create(proclist,nlocal,"shake:proclist"); + IDRvous *idbuf = (IDRvous *) + memory->smalloc((bigint) nlocal*sizeof(IDRvous),"shake:idbuf"); + + // setup input buf to rendezvous comm + // input datums = pairs of bonded atoms + // owning proc for each datum = random hash of atomID + // one datum for each owned atom: datum = owning proc, atomID + + for (int i = 0; i < nlocal; i++) { + proclist[i] = tag[i] % nprocs; + idbuf[i].me = me; + idbuf[i].atomID = tag[i]; + } + + // perform rendezvous operation + // each proc assigned every 1/Pth atom + + char *buf; + comm->rendezvous(nlocal,proclist, + (char *) idbuf,sizeof(IDRvous), + rendezvous_ids,buf,0,(void *) this); + + memory->destroy(proclist); + memory->sfree(idbuf); +} + +/* ---------------------------------------------------------------------- + setup partner_mask, partner_type, partner_massflag, partner_bondtype +------------------------------------------------------------------------- */ + +void FixShake::partner_info(int *npartner, tagint **partner_tag, + int **partner_mask, int **partner_type, + int **partner_massflag, int **partner_bondtype) +{ + int i,j,m,n; + int nlocal = atom->nlocal; + + // nsend = # of my datums to send + // one datum for every off-processor partner + + int nsend = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < npartner[i]; j++) { + m = atom->map(partner_tag[i][j]); + if (m < 0 || m >= nlocal) nsend++; + } + } + + int *proclist; + memory->create(proclist,nsend,"special:proclist"); + PartnerInfo *inbuf = (PartnerInfo *) + memory->smalloc((bigint) nsend*sizeof(PartnerInfo),"special:inbuf"); + + // set values in 4 partner arrays for all partner atoms I own + // also setup input buf to rendezvous comm + // input datums = pair of bonded atoms where I do not own partner + // owning proc for each datum = partner_tag % nprocs + // datum: atomID = partner_tag (off-proc), partnerID = tag (on-proc) + // 4 values for my owned atom + double *rmass = atom->rmass; double *mass = atom->mass; - int *mask = atom->mask; int *type = atom->type; + int *mask = atom->mask; + tagint *tag = atom->tag; + + double massone; + + nsend = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < npartner[i]; j++) { + partner_mask[i][j] = 0; + partner_type[i][j] = 0; + partner_massflag[i][j] = 0; + partner_bondtype[i][j] = 0; + + m = atom->map(partner_tag[i][j]); + + if (m >= 0 && m < nlocal) { + partner_mask[i][j] = mask[m]; + partner_type[i][j] = type[m]; + if (nmass) { + if (rmass) massone = rmass[m]; + else massone = mass[type[m]]; + partner_massflag[i][j] = masscheck(massone); + } + n = bondtype_findset(i,tag[i],partner_tag[i][j],0); + if (n) partner_bondtype[i][j] = n; + else { + n = bondtype_findset(m,tag[i],partner_tag[i][j],0); + if (n) partner_bondtype[i][j] = n; + } + + } else { + proclist[nsend] = partner_tag[i][j] % nprocs; + inbuf[nsend].atomID = partner_tag[i][j]; + inbuf[nsend].partnerID = tag[i]; + inbuf[nsend].mask = mask[i]; + inbuf[nsend].type = type[i]; + if (nmass) { + if (rmass) massone = rmass[i]; + else massone = mass[type[i]]; + inbuf[nsend].massflag = masscheck(massone); + } else inbuf[nsend].massflag = 0; + + // my atom may own bond, in which case set partner_bondtype + // else receiver of this datum will own the bond and return the value + + n = bondtype_findset(i,tag[i],partner_tag[i][j],0); + if (n) { + partner_bondtype[i][j] = n; + inbuf[nsend].bondtype = n; + } else inbuf[nsend].bondtype = 0; + + nsend++; + } + } + } + + // perform rendezvous operation + // each proc owns random subset of atoms + // receives all data needed to populate un-owned partner 4 values + + char *buf; + int nreturn = comm->rendezvous(nsend,proclist, + (char *) inbuf,sizeof(PartnerInfo), + rendezvous_partners_info,buf,sizeof(PartnerInfo), + (void *) this); + PartnerInfo *outbuf = (PartnerInfo *) buf; + + memory->destroy(proclist); + memory->sfree(inbuf); + + // set partner 4 values for un-onwed partners based on output info + // outbuf.atomID = my owned atom, outbuf.partnerID = partner the info is for + + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + for (j = 0; j < npartner[i]; j++) + if (partner_tag[i][j] == outbuf[m].partnerID) break; + partner_mask[i][j] = outbuf[m].mask; + partner_type[i][j] = outbuf[m].type; + partner_massflag[i][j] = outbuf[m].massflag; + + // only set partner_bondtype if my atom did not set it when setting up rendezvous + // if this proc set it, then sender of this datum set outbuf.bondtype = 0 + + if (partner_bondtype[i][j] == 0) + partner_bondtype[i][j] = outbuf[m].bondtype; + } + + memory->sfree(outbuf); +} + +/* ---------------------------------------------------------------------- + setup partner_nshake +------------------------------------------------------------------------- */ + +void FixShake::nshake_info(int *npartner, tagint **partner_tag, + int **partner_nshake) +{ + int i,j,m,n; int nlocal = atom->nlocal; - int nmass = fsptr->nmass; - tagint *buf = (tagint *) cbuf; - int m,n; - double massone; + // nsend = # of my datums to send + // one datum for every off-processor partner + + int nsend = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < npartner[i]; j++) { + m = atom->map(partner_tag[i][j]); + if (m < 0 || m >= nlocal) nsend++; + } + } - for (int i = 0; i < ndatum; i += 6) { - m = atom->map(buf[i+1]); - if (m >= 0 && m < nlocal) { - buf[i+2] = mask[m]; - buf[i+3] = type[m]; - if (nmass) { - if (rmass) massone = rmass[m]; - else massone = mass[type[m]]; - buf[i+4] = fsptr->masscheck(massone); + int *proclist; + memory->create(proclist,nsend,"special:proclist"); + NShakeInfo *inbuf = (NShakeInfo *) + memory->smalloc((bigint) nsend*sizeof(NShakeInfo),"special:inbuf"); + + // set partner_nshake for all partner atoms I own + // also setup input buf to rendezvous comm + // input datums = pair of bonded atoms where I do not own partner + // owning proc for each datum = partner_tag % nprocs + // datum: atomID = partner_tag (off-proc), partnerID = tag (on-proc) + // nshake value for my owned atom + + tagint *tag = atom->tag; + + nsend = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < npartner[i]; j++) { + partner_nshake[i][j] = 0; + m = atom->map(partner_tag[i][j]); + if (m >= 0 && m < nlocal) { + partner_nshake[i][j] = nshake[m]; + } else { + proclist[nsend] = partner_tag[i][j] % nprocs; + inbuf[nsend].atomID = partner_tag[i][j]; + inbuf[nsend].partnerID = tag[i]; + inbuf[nsend].nshake = nshake[i]; + nsend++; } - if (buf[i+5] == 0) { - n = fsptr->bondtype_findset(m,buf[i],buf[i+1],0); - if (n) buf[i+5] = n; + } + } + + // perform rendezvous operation + // each proc owns random subset of atoms + // receives all data needed to populate un-owned partner nshake + + char *buf; + int nreturn = comm->rendezvous(nsend,proclist, + (char *) inbuf,sizeof(NShakeInfo), + rendezvous_nshake,buf,sizeof(NShakeInfo), + (void *) this); + NShakeInfo *outbuf = (NShakeInfo *) buf; + + memory->destroy(proclist); + memory->sfree(inbuf); + + // set partner nshake for un-onwed partners based on output info + // outbuf.atomID = my owned atom, outbuf.partnerID = partner the info is for + + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + for (j = 0; j < npartner[i]; j++) + if (partner_tag[i][j] == outbuf[m].partnerID) break; + partner_nshake[i][j] = outbuf[m].nshake; + } + + memory->sfree(outbuf); +} + +/* ---------------------------------------------------------------------- + setup shake_flag, shake_atom, shake_type +------------------------------------------------------------------------- */ + +void FixShake::shake_info(int *npartner, tagint **partner_tag, + int **partner_shake) +{ + int i,j,m,n; + int nlocal = atom->nlocal; + + // nsend = # of my datums to send + // one datum for every off-processor partner + + int nsend = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < npartner[i]; j++) { + m = atom->map(partner_tag[i][j]); + if (m < 0 || m >= nlocal) nsend++; + } + } + + int *proclist; + memory->create(proclist,nsend,"special:proclist"); + ShakeInfo *inbuf = (ShakeInfo *) + memory->smalloc((bigint) nsend*sizeof(ShakeInfo),"special:inbuf"); + + // set 3 shake arrays for all partner atoms I own + // also setup input buf to rendezvous comm + // input datums = partner atom where I do not own partner + // owning proc for each datum = partner_tag % nprocs + // datum: atomID = partner_tag (off-proc) + // values in 3 shake arrays + + nsend = 0; + for (i = 0; i < nlocal; i++) { + if (shake_flag[i] == 0) continue; + for (j = 0; j < npartner[i]; j++) { + if (partner_shake[i][j] == 0) continue; + m = atom->map(partner_tag[i][j]); + + if (m >= 0 && m < nlocal) { + shake_flag[m] = shake_flag[i]; + shake_atom[m][0] = shake_atom[i][0]; + shake_atom[m][1] = shake_atom[i][1]; + shake_atom[m][2] = shake_atom[i][2]; + shake_atom[m][3] = shake_atom[i][3]; + shake_type[m][0] = shake_type[i][0]; + shake_type[m][1] = shake_type[i][1]; + shake_type[m][2] = shake_type[i][2]; + + } else { + proclist[nsend] = partner_tag[i][j] % nprocs; + inbuf[nsend].atomID = partner_tag[i][j]; + inbuf[nsend].shake_flag = shake_flag[i]; + inbuf[nsend].shake_atom[0] = shake_atom[i][0]; + inbuf[nsend].shake_atom[1] = shake_atom[i][1]; + inbuf[nsend].shake_atom[2] = shake_atom[i][2]; + inbuf[nsend].shake_atom[3] = shake_atom[i][3]; + inbuf[nsend].shake_type[0] = shake_type[i][0]; + inbuf[nsend].shake_type[1] = shake_type[i][1]; + inbuf[nsend].shake_type[2] = shake_type[i][2]; + nsend++; } } } + + // perform rendezvous operation + // each proc owns random subset of atoms + // receives all data needed to populate un-owned shake info + + char *buf; + int nreturn = comm->rendezvous(nsend,proclist, + (char *) inbuf,sizeof(ShakeInfo), + rendezvous_shake,buf,sizeof(ShakeInfo), + (void *) this); + ShakeInfo *outbuf = (ShakeInfo *) buf; + + memory->destroy(proclist); + memory->sfree(inbuf); + + // set shake info for un-onwed partners based on output info + + for (m = 0; m < nreturn; m++) { + i = atom->map(outbuf[m].atomID); + shake_flag[i] = outbuf[m].shake_flag; + shake_atom[i][0] = outbuf[m].shake_atom[0]; + shake_atom[i][1] = outbuf[m].shake_atom[1]; + shake_atom[i][2] = outbuf[m].shake_atom[2]; + shake_atom[i][3] = outbuf[m].shake_atom[3]; + shake_type[i][0] = outbuf[m].shake_type[0]; + shake_type[i][1] = outbuf[m].shake_type[1]; + shake_type[i][2] = outbuf[m].shake_type[2]; + } + + memory->sfree(outbuf); } /* ---------------------------------------------------------------------- - when receive buffer, scan bond partner IDs for atoms I own - if I own partner, fill in nshake value + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N IDRvous datums + no outbuf ------------------------------------------------------------------------- */ -void FixShake::ring_nshake(int ndatum, char *cbuf, void *ptr) +int FixShake::rendezvous_ids(int n, char *inbuf, + int &flag, int *&proclist, char *&outbuf, + void *ptr) { - FixShake *fsptr = (FixShake *)ptr; + FixShake *fsptr = (FixShake *) ptr; + Memory *memory = fsptr->memory; + + int *procowner; + tagint *atomIDs; + + memory->create(procowner,n,"special:procowner"); + memory->create(atomIDs,n,"special:atomIDs"); + + IDRvous *in = (IDRvous *) inbuf; + + for (int i = 0; i < n; i++) { + procowner[i] = in[i].me; + atomIDs[i] = in[i].atomID; + } + + // store rendezvous data in FixShake class + + fsptr->nrvous = n; + fsptr->procowner = procowner; + fsptr->atomIDs = atomIDs; + + // flag = 0: no 2nd irregular comm needed in comm->rendezvous + + flag = 0; + return 0; +} + +/* ---------------------------------------------------------------------- + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N PairRvous datums + outbuf = same list of N PairRvous datums, routed to different procs +------------------------------------------------------------------------- */ + +int FixShake::rendezvous_partners_info(int n, char *inbuf, + int &flag, int *&proclist, char *&outbuf, + void *ptr) +{ + int i,m; + + FixShake *fsptr = (FixShake *) ptr; Atom *atom = fsptr->atom; - int nlocal = atom->nlocal; + Memory *memory = fsptr->memory; - int *nshake = fsptr->nshake; + // clear atom map so it can be here as a hash table + // faster than an STL map for large atom counts - tagint *buf = (tagint *) cbuf; - int m; + atom->map_clear(); + + // hash atom IDs stored in rendezvous decomposition + + int nrvous = fsptr->nrvous; + tagint *atomIDs = fsptr->atomIDs; + + for (i = 0; i < nrvous; i++) + atom->map_one(atomIDs[i],i); - for (int i = 0; i < ndatum; i += 3) { - m = atom->map(buf[i+1]); - if (m >= 0 && m < nlocal) buf[i+2] = nshake[m]; + // proclist = owner of atomID in caller decomposition + // outbuf = info about owned atomID = 4 values + + PartnerInfo *in = (PartnerInfo *) inbuf; + int *procowner = fsptr->procowner; + memory->create(proclist,n,"shake:proclist"); + + double massone; + int nmass = fsptr->nmass; + + for (i = 0; i < n; i++) { + m = atom->map(in[i].atomID); + proclist[i] = procowner[m]; } + + outbuf = inbuf; + + // re-create atom map + + atom->map_init(0); + atom->nghost = 0; + atom->map_set(); + + // flag = 1: outbuf = inbuf + + flag = 1; + return n; } /* ---------------------------------------------------------------------- - when receive buffer, scan bond partner IDs for atoms I own - if I own partner, fill in nshake value + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N NShakeInfo datums + outbuf = same list of N NShakeInfo datums, routed to different procs ------------------------------------------------------------------------- */ -void FixShake::ring_shake(int ndatum, char *cbuf, void *ptr) +int FixShake::rendezvous_nshake(int n, char *inbuf, + int &flag, int *&proclist, char *&outbuf, + void *ptr) { - FixShake *fsptr = (FixShake *)ptr; + int i,j,m; + + FixShake *fsptr = (FixShake *) ptr; Atom *atom = fsptr->atom; - int nlocal = atom->nlocal; + Memory *memory = fsptr->memory; - int *shake_flag = fsptr->shake_flag; - tagint **shake_atom = fsptr->shake_atom; - int **shake_type = fsptr->shake_type; + // clear atom map so it can be here as a hash table + // faster than an STL map for large atom counts - tagint *buf = (tagint *) cbuf; - int m; + atom->map_clear(); - for (int i = 0; i < ndatum; i += 9) { - m = atom->map(buf[i]); - if (m >= 0 && m < nlocal) { - shake_flag[m] = buf[i+1]; - shake_atom[m][0] = buf[i+2]; - shake_atom[m][1] = buf[i+3]; - shake_atom[m][2] = buf[i+4]; - shake_atom[m][3] = buf[i+5]; - shake_type[m][0] = buf[i+6]; - shake_type[m][1] = buf[i+7]; - shake_type[m][2] = buf[i+8]; - } + // hash atom IDs stored in rendezvous decomposition + + int nrvous = fsptr->nrvous; + tagint *atomIDs = fsptr->atomIDs; + + for (i = 0; i < nrvous; i++) + atom->map_one(atomIDs[i],i); + + // proclist = owner of atomID in caller decomposition + // outbuf = info about owned atomID + + NShakeInfo *in = (NShakeInfo *) inbuf; + int *procowner = fsptr->procowner; + memory->create(proclist,n,"shake:proclist"); + + for (i = 0; i < n; i++) { + m = atom->map(in[i].atomID); + proclist[i] = procowner[m]; + } + + outbuf = inbuf; + + // re-create atom map + + atom->map_init(0); + atom->nghost = 0; + atom->map_set(); + + // flag = 1: outbuf = inbuf + + flag = 1; + return n; +} +/* ---------------------------------------------------------------------- + process data for atoms assigned to me in rendezvous decomposition + inbuf = list of N PairRvous datums + outbuf = same list of N PairRvous datums, routed to different procs +------------------------------------------------------------------------- */ + +int FixShake::rendezvous_shake(int n, char *inbuf, + int &flag, int *&proclist, char *&outbuf, + void *ptr) +{ + int i,j,m; + + FixShake *fsptr = (FixShake *) ptr; + Atom *atom = fsptr->atom; + Memory *memory = fsptr->memory; + + // clear atom map so it can be here as a hash table + // faster than an STL map for large atom counts + + atom->map_clear(); + + // hash atom IDs stored in rendezvous decomposition + + int nrvous = fsptr->nrvous; + tagint *atomIDs = fsptr->atomIDs; + + for (i = 0; i < nrvous; i++) + atom->map_one(atomIDs[i],i); + + // proclist = owner of atomID in caller decomposition + // outbuf = info about owned atomID + + ShakeInfo *in = (ShakeInfo *) inbuf; + int *procowner = fsptr->procowner; + memory->create(proclist,n,"shake:proclist"); + + for (i = 0; i < n; i++) { + m = atom->map(in[i].atomID); + proclist[i] = procowner[m]; } + + outbuf = inbuf; + + // re-create atom map + + atom->map_init(0); + atom->nghost = 0; + atom->map_set(); + + // flag = 1: outbuf = inbuf; + + flag = 1; + return n; } /* ---------------------------------------------------------------------- diff --git a/src/RIGID/fix_shake.h b/src/RIGID/fix_shake.h index d4e7b85ec4..2baea90a4a 100644 --- a/src/RIGID/fix_shake.h +++ b/src/RIGID/fix_shake.h @@ -120,6 +120,11 @@ class FixShake : public Fix { int nmol; void find_clusters(); + void atom_owners(); + void partner_info(int *, tagint **, int **, int **, int **, int **); + void nshake_info(int *, tagint **, int **); + void shake_info(int *, tagint **, int **); + int masscheck(double); void unconstrained_update(); void unconstrained_update_respa(int); @@ -131,12 +136,40 @@ class FixShake : public Fix { int bondtype_findset(int, tagint, tagint, int); int angletype_findset(int, tagint, tagint, int); - // static variable for ring communication callback to access class data - // callback functions for ring communication + // data used by rendezvous callback methods - static void ring_bonds(int, char *, void *); - static void ring_nshake(int, char *, void *); - static void ring_shake(int, char *, void *); + int nrvous; + tagint *atomIDs; + int *procowner; + + struct IDRvous { + int me; + tagint atomID; + }; + + struct PartnerInfo { + tagint atomID,partnerID; + int mask,type,massflag,bondtype; + }; + + struct NShakeInfo { + tagint atomID,partnerID; + int nshake; + }; + + struct ShakeInfo { + tagint atomID; + int shake_flag; + int shake_atom[4]; + int shake_type[3]; + }; + + // callback functions for rendezvous communication + + static int rendezvous_ids(int, char *, int &, int *&, char *&, void *); + static int rendezvous_partners_info(int, char *, int &, int *&, char *&, void *); + static int rendezvous_nshake(int, char *, int &, int *&, char *&, void *); + static int rendezvous_shake(int, char *, int &, int *&, char *&, void *); }; } diff --git a/src/special.cpp b/src/special.cpp index 79d2f77e46..b0d5bc7dca 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -21,7 +21,6 @@ #include "modify.h" #include "fix.h" #include "accelerator_kokkos.h" -#include "hashlittle.h" #include "atom_masks.h" #include "memory.h" #include "error.h" @@ -177,25 +176,20 @@ void Special::atom_owners() // input datums = pairs of bonded atoms // owning proc for each datum = random hash of atomID // one datum for each owned atom: datum = owning proc, atomID - // one datum for each bond partner: datum = atomID, bond partner ID - // add inverted datum when netwon_bond on for (int i = 0; i < nlocal; i++) { - //proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; proclist[i] = tag[i] % nprocs; idbuf[i].me = me; idbuf[i].atomID = tag[i]; } // perform rendezvous operation - // each proc owns random subset of atoms - // receives all info to form and return their onetwo lists + // each proc assigned every 1/Pth atom char *buf; comm->rendezvous(nlocal,proclist, - (char *) idbuf,sizeof(PairRvous), - rendezvous_ids,buf,sizeof(PairRvous), - (void *) this); + (char *) idbuf,sizeof(IDRvous), + rendezvous_ids,buf,0,(void *) this); memory->destroy(proclist); memory->sfree(idbuf); @@ -215,49 +209,45 @@ void Special::onetwo_build_newton() int **nspecial = atom->nspecial; int nlocal = atom->nlocal; - // ncount = # of my datums to send - // include nlocal datums with owner of each atom + // nsend = # of my datums to send - int ncount = 0; + int nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < num_bond[i]; j++) { m = atom->map(bond_atom[i][j]); - if (m < 0 || m >= nlocal) ncount++; + if (m < 0 || m >= nlocal) nsend++; } } int *proclist; - memory->create(proclist,ncount,"special:proclist"); + memory->create(proclist,nsend,"special:proclist"); PairRvous *inbuf = (PairRvous *) - memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); + memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // input datums = pairs of bonded atoms - // owning proc for each datum = random hash of atomID - // one datum for each owned atom: datum = owning proc, atomID - // one datum for each bond partner: datum = atomID, bond partner ID - // add inverted datum when netwon_bond on + // owning proc for each datum = atomID % nprocs + // one datum for each bond partner: bond partner ID, atomID - ncount = 0; + nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < num_bond[i]; j++) { m = atom->map(bond_atom[i][j]); if (m >= 0 && m < nlocal) continue; - proclist[ncount] = bond_atom[i][j] % nprocs; - inbuf[ncount].atomID = bond_atom[i][j]; - inbuf[ncount].partnerID = tag[i]; - ncount++; + proclist[nsend] = bond_atom[i][j] % nprocs; + inbuf[nsend].atomID = bond_atom[i][j]; + inbuf[nsend].partnerID = tag[i]; + nsend++; } } // perform rendezvous operation // each proc owns random subset of atoms - // receives all info to form and return their onetwo lists char *buf; - int nreturn = comm->rendezvous(ncount,proclist, + int nreturn = comm->rendezvous(nsend,proclist, (char *) inbuf,sizeof(PairRvous), - rendezvous_1234,buf,sizeof(PairRvous), + rendezvous_pairs,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; @@ -312,6 +302,28 @@ void Special::onetwo_build_newton() void Special::onetwo_build_newton_off() { + int i,j; + + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **nspecial = atom->nspecial; + int nlocal = atom->nlocal; + + int max = 0; + for (i = 0; i < nlocal; i++) + max = MAX(max,num_bond[i]); + + MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + memory->create(onetwo,nlocal,maxall,"special:onetwo"); + + // nsend = # of my datums to send + // include nlocal datums with owner of each atom + + for (i = 0; i < nlocal; i++) { + nspecial[i][0] = num_bond[i]; + for (j = 0; j < num_bond[i]; j++) + onetwo[i][j] = bond_atom[i][j]; + } } /* ---------------------------------------------------------------------- @@ -327,21 +339,20 @@ void Special::onethree_build() int **nspecial = atom->nspecial; int nlocal = atom->nlocal; - // ncount = # of my datums to send - // include nlocal datums with owner of each atom + // nsend = # of my datums to send - int ncount = 0; + int nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < nspecial[i][0]; j++) { m = atom->map(onetwo[i][j]); - if (m < 0 || m >= nlocal) ncount += nspecial[i][0]-1; + if (m < 0 || m >= nlocal) nsend += nspecial[i][0]-1; } } int *proclist; - memory->create(proclist,ncount,"special:proclist"); + memory->create(proclist,nsend,"special:proclist"); PairRvous *inbuf = (PairRvous *) - memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); + memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // input datums = all pairs of onetwo atoms (they are 1-3 neighbors) @@ -349,7 +360,7 @@ void Special::onethree_build() // one datum for each owned atom: datum = owning proc, atomID // one datum for each onetwo pair: datum = atomID1, atomID2 - ncount = 0; + nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < nspecial[i][0]; j++) { m = atom->map(onetwo[i][j]); @@ -357,10 +368,10 @@ void Special::onethree_build() proc = onetwo[i][j] % nprocs; for (k = 0; k < nspecial[i][0]; k++) { if (j == k) continue; - proclist[ncount] = proc; - inbuf[ncount].atomID = onetwo[i][j]; - inbuf[ncount].partnerID = onetwo[i][k]; - ncount++; + proclist[nsend] = proc; + inbuf[nsend].atomID = onetwo[i][j]; + inbuf[nsend].partnerID = onetwo[i][k]; + nsend++; } } } @@ -370,9 +381,9 @@ void Special::onethree_build() // receives all info to form and return their onethree lists char *buf; - int nreturn = comm->rendezvous(ncount,proclist, + int nreturn = comm->rendezvous(nsend,proclist, (char *) inbuf,sizeof(PairRvous), - rendezvous_1234,buf,sizeof(PairRvous), + rendezvous_pairs,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; @@ -434,21 +445,21 @@ void Special::onefour_build() int **nspecial = atom->nspecial; int nlocal = atom->nlocal; - // ncount = # of my datums to send + // nsend = # of my datums to send // include nlocal datums with owner of each atom - int ncount = 0; + int nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < nspecial[i][1]; j++) { m = atom->map(onethree[i][j]); - if (m < 0 || m >= nlocal) ncount += nspecial[i][0]; + if (m < 0 || m >= nlocal) nsend += nspecial[i][0]; } } int *proclist; - memory->create(proclist,ncount,"special:proclist"); + memory->create(proclist,nsend,"special:proclist"); PairRvous *inbuf = (PairRvous *) - memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); + memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm // input datums = all pairs of onethree and onetwo atoms (they're 1-4 neighbors) @@ -456,17 +467,17 @@ void Special::onefour_build() // one datum for each owned atom: datum = owning proc, atomID // one datum for each onethree/onetwo pair: datum = atomID1, atomID2 - ncount = 0; + nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < nspecial[i][1]; j++) { m = atom->map(onethree[i][j]); if (m >= 0 && m < nlocal) continue; proc = onethree[i][j] % nprocs; for (k = 0; k < nspecial[i][0]; k++) { - proclist[ncount] = proc; - inbuf[ncount].atomID = onethree[i][j]; - inbuf[ncount].partnerID = onetwo[i][k]; - ncount++; + proclist[nsend] = proc; + inbuf[nsend].atomID = onethree[i][j]; + inbuf[nsend].partnerID = onetwo[i][k]; + nsend++; } } } @@ -476,9 +487,9 @@ void Special::onefour_build() // receives all info to form and return their onefour lists char *buf; - int nreturn = comm->rendezvous(ncount,proclist, + int nreturn = comm->rendezvous(nsend,proclist, (char *) inbuf,sizeof(PairRvous), - rendezvous_1234,buf,sizeof(PairRvous), + rendezvous_pairs,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; @@ -773,7 +784,7 @@ void Special::combine() void Special::angle_trim() { - int i,j,m,n,proc,index; + int i,j,k,m;; int *num_angle = atom->num_angle; int *num_dihedral = atom->num_dihedral; @@ -804,96 +815,89 @@ void Special::angle_trim() " %g = # of 1-3 neighbors before angle trim\n",allcount); } - // if angles or dihedrals are defined, - // flag each 1-3 neigh if it appears in an angle or dihedral + // if angles or dihedrals are defined + // rendezvous angle 1-3 and dihedral 1-3,2-4 pairs if ((num_angle && atom->nangles) || (num_dihedral && atom->ndihedrals)) { - // ncount = # of my datums to send in 3 parts for each owned atom - // proc owner, onethree list, angle end points - // angle end points are from angle list and 1-3 and 2-4 pairs in dihedrals - // latter is only for angles or dihedrlas where I own atom2 + // nsend = # of my datums to send + // latter is only for angles or dihedrlas where I own atom2 (newton bond off) - int ncount = nlocal; - for (i = 0; i < nlocal; i++) ncount += nspecial[i][1]; + int nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < num_angle[i]; j++) { - index = atom->map(angle_atom2[i][j]); - if (index >= 0 && index < nlocal) ncount += 2; + if (tag[i] != angle_atom2[i][j]) continue; + m = atom->map(angle_atom1[i][j]); + if (m < 0 || m >= nlocal) nsend++; + m = atom->map(angle_atom3[i][j]); + if (m < 0 || m >= nlocal) nsend++; } for (j = 0; j < num_dihedral[i]; j++) { - index = atom->map(dihedral_atom2[i][j]); - if (index >= 0 && index < nlocal) ncount += 4; + if (tag[i] != dihedral_atom2[i][j]) continue; + m = atom->map(dihedral_atom1[i][j]); + if (m < 0 || m >= nlocal) nsend++; + m = atom->map(dihedral_atom3[i][j]); + if (m < 0 || m >= nlocal) nsend++; + m = atom->map(dihedral_atom4[i][j]); + if (m < 0 || m >= nlocal) nsend++; } } int *proclist; - memory->create(proclist,ncount,"special:proclist"); + memory->create(proclist,nsend,"special:proclist"); PairRvous *inbuf = (PairRvous *) - memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); + memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm - // one datum for each owned atom: datum = proc, atomID - // sent to owner of atomID - // one datum for each 1-4 partner: datum = atomID, ID - // sent to owner of atomID - // two datums for each dihedral 1-4 endatoms : datum = atomID, ID - // sent to owner of atomID - - m = 0; - for (i = 0; i < nlocal; i++) { - for (j = 0; j < nspecial[i][1]; j++) { - proclist[m] = proc; - //inbuf[m].me = -1; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = onethree[i][j]; - m++; - } + nsend = 0; + for (i = 0; i < nlocal; i++) { for (j = 0; j < num_angle[i]; j++) { - index = atom->map(angle_atom2[i][j]); - if (index < 0 || index >= nlocal) continue; - - proclist[m] = hashlittle(&angle_atom1[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = angle_atom1[i][j]; - inbuf[m].partnerID = angle_atom3[i][j]; - m++; - - proclist[m] = hashlittle(&angle_atom3[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = angle_atom3[i][j]; - inbuf[m].partnerID = angle_atom1[i][j]; - m++; + if (tag[i] != angle_atom2[i][j]) continue; + + m = atom->map(angle_atom1[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = angle_atom1[i][j] % nprocs; + inbuf[nsend].atomID = angle_atom1[i][j]; + inbuf[nsend].partnerID = angle_atom3[i][j]; + nsend++; + } + + m = atom->map(angle_atom3[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = angle_atom3[i][j] % nprocs; + inbuf[nsend].atomID = angle_atom3[i][j]; + inbuf[nsend].partnerID = angle_atom1[i][j]; + nsend++; + } } for (j = 0; j < num_dihedral[i]; j++) { - index = atom->map(dihedral_atom2[i][j]); - if (index < 0 || index >= nlocal) continue; - - proclist[m] = hashlittle(&dihedral_atom1[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = dihedral_atom1[i][j]; - inbuf[m].partnerID = dihedral_atom3[i][j]; - m++; - - proclist[m] = hashlittle(&dihedral_atom2[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = dihedral_atom2[i][j]; - inbuf[m].partnerID = dihedral_atom4[i][j]; - m++; - - proclist[m] = hashlittle(&dihedral_atom3[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = dihedral_atom3[i][j]; - inbuf[m].partnerID = dihedral_atom1[i][j]; - m++; - - proclist[m] = hashlittle(&dihedral_atom4[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = dihedral_atom4[i][j]; - inbuf[m].partnerID = dihedral_atom2[i][j]; - m++; + if (tag[i] != dihedral_atom2[i][j]) continue; + + m = atom->map(dihedral_atom1[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = dihedral_atom1[i][j] % nprocs; + inbuf[nsend].atomID = dihedral_atom1[i][j]; + inbuf[nsend].partnerID = dihedral_atom3[i][j]; + nsend++; + } + + m = atom->map(dihedral_atom3[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = dihedral_atom3[i][j] % nprocs; + inbuf[nsend].atomID = dihedral_atom3[i][j]; + inbuf[nsend].partnerID = dihedral_atom1[i][j]; + nsend++; + } + + m = atom->map(dihedral_atom4[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = dihedral_atom4[i][j] % nprocs; + inbuf[nsend].atomID = dihedral_atom4[i][j]; + inbuf[nsend].partnerID = dihedral_atom2[i][j]; + nsend++; + } } } @@ -903,26 +907,112 @@ void Special::angle_trim() // when done: each atom has atom ID of owning atom of its body char *buf; - int nreturn = comm->rendezvous(ncount,proclist, + int nreturn = comm->rendezvous(nsend,proclist, (char *) inbuf,sizeof(PairRvous), - rendezvous_trim,buf,sizeof(PairRvous), + rendezvous_pairs,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); + // flag all onethree atoms to keep + + int max = 0; + for (i = 0; i < nlocal; i++) + max = MAX(max,nspecial[i][1]); + MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + + int **flag; + memory->create(flag,nlocal,maxall,"special:flag"); + + for (i = 0; i < nlocal; i++) + for (j = 0; j < nspecial[i][1]; j++) + flag[i][j] = 0; + // reset nspecial[1] and onethree for all owned atoms based on output info + + for (i = 0; i < nlocal; i++) { + for (j = 0; j < num_angle[i]; j++) { + if (tag[i] != angle_atom2[i][j]) continue; + + m = atom->map(angle_atom1[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][1]; k++) + if (onethree[m][k] == angle_atom3[i][j]) { + flag[m][k] = 1; + break; + } + } + + m = atom->map(angle_atom3[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][1]; k++) + if (onethree[m][k] == angle_atom1[i][j]) { + flag[m][k] = 1; + break; + } + } + } - for (i = 0; i < nlocal; i++) nspecial[i][1] = 0; + for (j = 0; j < num_dihedral[i]; j++) { + if (tag[i] != dihedral_atom2[i][j]) continue; + + m = atom->map(dihedral_atom1[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][1]; k++) + if (onethree[m][k] == dihedral_atom3[i][j]) { + flag[m][k] = 1; + break; + } + } + + m = atom->map(dihedral_atom3[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][1]; k++) + if (onethree[m][k] == dihedral_atom1[i][j]) { + flag[m][k] = 1; + break; + } + } + + m = atom->map(dihedral_atom4[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][1]; k++) + if (onethree[m][k] == dihedral_atom2[i][j]) { + flag[m][k] = 1; + break; + } + } + } + } for (m = 0; m < nreturn; m++) { i = atom->map(outbuf[m].atomID); - onethree[i][nspecial[i][1]++] = outbuf[m].partnerID; + for (k = 0; k < nspecial[i][1]; k++) + if (onethree[i][k] == outbuf[m].partnerID) { + flag[i][k] = 1; + break; + } } - + memory->destroy(outbuf); + // use flag values to compress onefour list for each atom + + for (i = 0; i < nlocal; i++) { + j = 0; + while (j < nspecial[i][1]) { + if (flag[i][j] == 0) { + onethree[i][j] = onethree[i][nspecial[i][1]-1]; + flag[i][j] = flag[i][nspecial[i][1]-1]; + nspecial[i][1]--; + } else j++; + } + } + + memory->destroy(flag); + // if no angles or dihedrals are defined, delete all 1-3 neighs } else { @@ -952,7 +1042,7 @@ void Special::angle_trim() void Special::dihedral_trim() { - int i,j,m,n,proc,index; + int i,j,k,m; int *num_dihedral = atom->num_dihedral; tagint **dihedral_atom1 = atom->dihedral_atom1; @@ -978,68 +1068,51 @@ void Special::dihedral_trim() " %g = # of 1-4 neighbors before dihedral trim\n",allcount); } - // if dihedrals are defined, rendezvous onefour list with dihedral 1-4 pairs + // if dihedrals are defined, rendezvous dihedral 1-4 pairs if (num_dihedral && atom->ndihedrals) { - // ncount = # of my datums to send in 3 parts for each owned atom - // onefour list, proc owner, dihedral end points - // latter is only for dihedrals where I own atom2 + // nsend = # of my datums to send + // latter is only for dihedrals where I own atom2 (newton bond off) - int ncount = nlocal; - for (i = 0; i < nlocal; i++) ncount += nspecial[i][2]; + int nsend = 0; for (i = 0; i < nlocal; i++) { for (j = 0; j < num_dihedral[i]; j++) { - index = atom->map(dihedral_atom2[i][j]); - if (index >= 0 && index < nlocal) ncount += 2; + if (tag[i] != dihedral_atom2[i][j]) continue; + m = atom->map(dihedral_atom1[i][j]); + if (m < 0 || m >= nlocal) nsend++; + m = atom->map(dihedral_atom4[i][j]); + if (m < 0 || m >= nlocal) nsend++; } } int *proclist; - memory->create(proclist,ncount,"special:proclist"); + memory->create(proclist,nsend,"special:proclist"); PairRvous *inbuf = (PairRvous *) - memory->smalloc((bigint) ncount*sizeof(PairRvous),"special:inbuf"); - + memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); + // setup input buf to rendezvous comm - // one datum for each owned atom: datum = proc, atomID - // sent to owner of atomID - // one datum for each 1-4 partner: datum = atomID, ID - // sent to owner of atomID - // two datums for each dihedral 1-4 endatoms : datum = atomID, ID - // sent to owner of atomID - - m = 0; - for (i = 0; i < nlocal; i++) { - proc = hashlittle(&tag[i],sizeof(tagint),0) % nprocs; - proclist[m] = proc; - //inbuf[m].me = me; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = 0; - m++; - - for (j = 0; j < nspecial[i][2]; j++) { - proclist[m] = proc; - //inbuf[m].me = -1; - inbuf[m].atomID = tag[i]; - inbuf[m].partnerID = onefour[i][j]; - m++; - } + nsend = 0; + for (i = 0; i < nlocal; i++) { for (j = 0; j < num_dihedral[i]; j++) { - index = atom->map(dihedral_atom2[i][j]); - if (index < 0 || index >= nlocal) continue; - - proclist[m] = hashlittle(&dihedral_atom1[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = dihedral_atom1[i][j]; - inbuf[m].partnerID = dihedral_atom4[i][j]; - m++; - - proclist[m] = hashlittle(&dihedral_atom4[i][j],sizeof(tagint),0) % nprocs; - //inbuf[m].me = -2; - inbuf[m].atomID = dihedral_atom4[i][j]; - inbuf[m].partnerID = dihedral_atom1[i][j]; - m++; + if (tag[i] != dihedral_atom2[i][j]) continue; + + m = atom->map(dihedral_atom1[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = dihedral_atom1[i][j] % nprocs; + inbuf[nsend].atomID = dihedral_atom1[i][j]; + inbuf[nsend].partnerID = dihedral_atom4[i][j]; + nsend++; + } + + m = atom->map(dihedral_atom4[i][j]); + if (m < 0 || m >= nlocal) { + proclist[nsend] = dihedral_atom4[i][j] % nprocs; + inbuf[nsend].atomID = dihedral_atom4[i][j]; + inbuf[nsend].partnerID = dihedral_atom1[i][j]; + nsend++; + } } } @@ -1049,26 +1122,81 @@ void Special::dihedral_trim() // when done: each atom has atom ID of owning atom of its body char *buf; - int nreturn = comm->rendezvous(ncount,proclist, + int nreturn = comm->rendezvous(nsend,proclist, (char *) inbuf,sizeof(PairRvous), - rendezvous_trim,buf,sizeof(PairRvous), + rendezvous_pairs,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); + // flag all onefour atoms to keep + + int max = 0; + for (i = 0; i < nlocal; i++) + max = MAX(max,nspecial[i][2]); + MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world); + + int **flag; + memory->create(flag,nlocal,maxall,"special:flag"); + + for (i = 0; i < nlocal; i++) + for (j = 0; j < nspecial[i][2]; j++) + flag[i][j] = 0; + // reset nspecial[2] and onefour for all owned atoms based on output info - for (i = 0; i < nlocal; i++) nspecial[i][2] = 0; + for (i = 0; i < nlocal; i++) { + for (j = 0; j < num_dihedral[i]; j++) { + if (tag[i] != dihedral_atom2[i][j]) continue; + + m = atom->map(dihedral_atom1[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][2]; k++) + if (onefour[m][k] == dihedral_atom4[i][j]) { + flag[m][k] = 1; + break; + } + } + + m = atom->map(dihedral_atom4[i][j]); + if (m >= 0 && m < nlocal) { + for (k = 0; k < nspecial[m][2]; k++) + if (onefour[m][k] == dihedral_atom1[i][j]) { + flag[m][k] = 1; + break; + } + } + } + } for (m = 0; m < nreturn; m++) { i = atom->map(outbuf[m].atomID); - onefour[i][nspecial[i][2]++] = outbuf[m].partnerID; + for (k = 0; k < nspecial[i][2]; k++) + if (onefour[i][k] == outbuf[m].partnerID) { + flag[i][k] = 1; + break; + } } memory->destroy(outbuf); + // use flag values to compress onefour list for each atom + + for (i = 0; i < nlocal; i++) { + j = 0; + while (j < nspecial[i][2]) { + if (flag[i][j] == 0) { + onefour[i][j] = onefour[i][nspecial[i][2]-1]; + flag[i][j] = flag[i][nspecial[i][2]-1]; + nspecial[i][2]--; + } else j++; + } + } + + memory->destroy(flag); + // if no dihedrals are defined, delete all 1-4 neighs } else { @@ -1093,8 +1221,8 @@ void Special::dihedral_trim() /* ---------------------------------------------------------------------- process data for atoms assigned to me in rendezvous decomposition - inbuf = list of N PairRvous datums - outbuf = empty + inbuf = list of N IDRvous datums + no outbuf ------------------------------------------------------------------------- */ int Special::rendezvous_ids(int n, char *inbuf, @@ -1109,7 +1237,6 @@ int Special::rendezvous_ids(int n, char *inbuf, memory->create(procowner,n,"special:procowner"); memory->create(atomIDs,n,"special:atomIDs"); - // NOTE: when to free these vectors IDRvous *in = (IDRvous *) inbuf; @@ -1120,13 +1247,12 @@ int Special::rendezvous_ids(int n, char *inbuf, // store rendezvous data in Special class - sptr->ncount = n; + sptr->nrvous = n; sptr->procowner = procowner; sptr->atomIDs = atomIDs; - proclist = NULL; - outbuf = NULL; - + // flag = 0: no 2nd irregular comm needed in comm->rendezvous + flag = 0; return 0; } @@ -1138,7 +1264,7 @@ int Special::rendezvous_ids(int n, char *inbuf, outbuf = same list of N PairRvous datums, routed to different procs ------------------------------------------------------------------------- */ -int Special::rendezvous_1234(int n, char *inbuf, +int Special::rendezvous_pairs(int n, char *inbuf, int &flag, int *&proclist, char *&outbuf, void *ptr) { @@ -1153,10 +1279,10 @@ int Special::rendezvous_1234(int n, char *inbuf, // hash atom IDs stored in rendezvous decomposition - int ncount = sptr->ncount; + int nrvous = sptr->nrvous; tagint *atomIDs = sptr->atomIDs; - for (int i = 0; i < ncount; i++) + for (int i = 0; i < nrvous; i++) atom->map_one(atomIDs[i],i); // proclist = owner of atomID in caller decomposition @@ -1172,7 +1298,6 @@ int Special::rendezvous_1234(int n, char *inbuf, } outbuf = inbuf; - // NOTE: set out = in flag // re-create atom map @@ -1180,148 +1305,12 @@ int Special::rendezvous_1234(int n, char *inbuf, atom->nghost = 0; atom->map_set(); + // flag = 1: outbuf = inbuf + flag = 1; return n; } -/* ---------------------------------------------------------------------- - process data for atoms assigned to me in rendezvous decomposition - inbuf = list of N PairRvous datums - create outbuf = list of Nout PairRvous datums -------------------------------------------------------------------------- */ - -int Special::rendezvous_trim(int n, char *inbuf, - int &flag, int *&proclist, char *&outbuf, - void *ptr) -{ - int i,j,m; - - /* - Special *sptr = (Special *) ptr; - Atom *atom = sptr->atom; - Memory *memory = sptr->memory; - - // clear atom map so it can be here as a hash table - // faster than an STL map for large atom counts - - atom->map_clear(); - - // initialize hash - // ncount = number of atoms assigned to me - // key = atom ID - // value = index into Ncount-length data structure - - PairRvous *in = (PairRvous *) inbuf; - //std::map hash; - tagint id; - - int ncount = 0; - for (i = 0; i < n; i++) - if (in[i].me >= 0) - //hash[in[i].atomID] = ncount++; - atom->map_one(in[i].atomID,ncount++); - - // procowner = caller proc that owns each atom - // atomID = ID of each rendezvous atom I own - // npartner = # of 1-3 partners for each atom I own - - int *procowner,*npartner; - tagint *atomID; - memory->create(procowner,ncount,"special:procowner"); - memory->create(atomID,ncount,"special:atomID"); - memory->create(npartner,ncount,"special:npartner"); - for (m = 0; m < ncount; m++) npartner[m] = 0; - - for (i = 0; i < n; i++) { - //m = hash.find(in[i].atomID)->second; - m = atom->map(in[i].atomID); - if (in[i].me >= 0) { - procowner[m] = in[i].me; - atomID[m] = in[i].atomID; - } else if (in[i].me == -1) npartner[m]++; - } - - int max = 0; - for (m = 0; m < ncount; m++) max = MAX(max,npartner[m]); - - // partner = list of 1-3 or 1-4 partners for each atom I own - - int **partner; - memory->create(partner,ncount,max,"special:partner"); - for (m = 0; m < ncount; m++) npartner[m] = 0; - - for (i = 0; i < n; i++) { - if (in[i].me >= 0 || in[i].me == -2) continue; - //m = hash.find(in[i].atomID)->second; - m = atom->map(in[i].atomID); - partner[m][npartner[m]++] = in[i].partnerID; - } - - // flag = 1 if partner is in an actual angle or in a dihedral - - int **flag; - memory->create(flag,ncount,max,"special:flag"); - - for (i = 0; i < ncount; i++) - for (j = 0; j < npartner[i]; j++) - flag[i][j] = 0; - - tagint actual; - for (i = 0; i < n; i++) { - if (in[i].me != -2) continue; - actual = in[i].partnerID; - //m = hash.find(in[i].atomID)->second; - m = atom->map(in[i].atomID); - for (j = 0; j < npartner[m]; j++) - if (partner[m][j] == actual) { - flag[m][j] = 1; - break; - } - } - - // pass list of PairRvous datums back to comm->rendezvous - - int nout = 0; - for (m = 0; m < ncount; m++) nout += npartner[m]; - - memory->create(proclist,nout,"special:proclist"); - PairRvous *out = (PairRvous *) - memory->smalloc((bigint) nout*sizeof(PairRvous),"special:out"); - - nout = 0; - for (m = 0; m < ncount; m++) - for (j = 0; j < npartner[m]; j++) { - if (flag[m][j] == 0) continue; - proclist[nout] = procowner[m]; - out[nout].atomID = atomID[m]; - out[nout].partnerID = partner[m][j]; - nout++; - } - - outbuf = (char *) out; - - // clean up - // Comm::rendezvous will delete proclist and out (outbuf) - - memory->destroy(procowner); - memory->destroy(atomID); - memory->destroy(npartner); - memory->destroy(partner); - memory->destroy(flag); - - // re-create atom map - - atom->map_init(0); - atom->nghost = 0; - atom->map_set(); - - */ - - //return nout; - flag = 2; - return 0; -} - /* ---------------------------------------------------------------------- allow fixes to alter special list currently, only fix drude does this diff --git a/src/special.h b/src/special.h index 772ba613ac..d02a8522f6 100644 --- a/src/special.h +++ b/src/special.h @@ -31,7 +31,7 @@ class Special : protected Pointers { // data used by rendezvous callback methods - int ncount; + int nrvous; tagint *atomIDs; int *procowner; @@ -44,6 +44,8 @@ class Special : protected Pointers { tagint atomID,partnerID; }; + // private methods + void atom_owners(); void onetwo_build_newton(); void onetwo_build_newton_off(); @@ -60,8 +62,7 @@ class Special : protected Pointers { // callback functions for rendezvous communication static int rendezvous_ids(int, char *, int &, int *&, char *&, void *); - static int rendezvous_1234(int, char *, int &, int *&, char *&, void *); - static int rendezvous_trim(int, char *, int &, int *&, char *&, void *); + static int rendezvous_pairs(int, char *, int &, int *&, char *&, void *); }; } -- GitLab From 540026ca00d4b637e54a3d3892cdf9979a86688b Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Sun, 16 Dec 2018 15:53:51 -0600 Subject: [PATCH 0074/1243] Update CMakeLists.txt to avoid merge conflicts --- cmake/CMakeLists.txt | 203 +++++++++++++++++++++++++++++++++---------- 1 file changed, 159 insertions(+), 44 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4abbeb4732..1936b50a56 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -11,6 +11,10 @@ get_filename_component(LAMMPS_LIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib get_filename_component(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib ABSOLUTE) get_filename_component(LAMMPS_DOC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../doc ABSOLUTE) +# by default, install into $HOME/.local (not /usr/local), so that no root access (and sudo!!) is needed +if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "default install path" FORCE ) +endif() # To avoid conflicts with the conventional Makefile build system, we build everything here file(GLOB LIB_SOURCES ${LAMMPS_SOURCE_DIR}/[^.]*.cpp) @@ -75,6 +79,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) #release comes with -O3 by default set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS) +string(TOUPPER "${CMAKE_BUILD_TYPE}" BTYPE) # check for files auto-generated by make-based buildsystem # this is fast, so check for it all the time @@ -171,8 +176,9 @@ set(DEFAULT_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS DIPOLE GRANULAR USER-BOCS USER-CGDNA USER-MESO USER-CGSDK USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP USER-H5MD USER-LB USER-MANIFOLD USER-MEAMC USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF - USER-PHONON USER-PTM USER-QTB USER-REAXC USER-SCAFACOS USER-SMD USER-SMTBQ - USER-SPH USER-TALLY USER-UEF USER-VTK USER-QUIP USER-QMMM) + USER-PHONON USER-PLUMED USER-PTM USER-QTB USER-REAXC USER-SCAFACOS + USER-SDPD USER-SMD USER-SMTBQ USER-SPH USER-TALLY USER-UEF USER-VTK + USER-QUIP USER-QMMM) set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU) set(OTHER_PACKAGES CORESHELL QEQ) foreach(PKG ${DEFAULT_PACKAGES}) @@ -215,7 +221,7 @@ else() endif() -set(LAMMPS_SIZES "smallbig" CACHE STRING "LAMMPS size limit") +set(LAMMPS_SIZES "smallbig" CACHE STRING "LAMMPS integer sizes (smallsmall: all 32-bit, smallbig: 64-bit #atoms #timesteps, bigbig: also 64-bit imageint, 64-bit atom ids)") set(LAMMPS_SIZES_VALUES smallbig bigbig smallsmall) set_property(CACHE LAMMPS_SIZES PROPERTY STRINGS ${LAMMPS_SIZES_VALUES}) validate_option(LAMMPS_SIZES LAMMPS_SIZES_VALUES) @@ -303,7 +309,7 @@ pkg_depends(USER-SCAFACOS MPI) find_package(OpenMP QUIET) option(BUILD_OMP "Build with OpenMP support" ${OpenMP_FOUND}) -if(BUILD_OMP OR PKG_USER-OMP OR PKG_KOKKOS OR PKG_USER-INTEL) +if(BUILD_OMP OR PKG_KOKKOS OR PKG_USER-INTEL) find_package(OpenMP REQUIRED) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") @@ -421,16 +427,30 @@ if(WITH_FFMPEG) add_definitions(-DLAMMPS_FFMPEG) endif() +if(BUILD_SHARED_LIBS) + set(CONFIGURE_REQUEST_PIC "--with-pic") + set(CMAKE_REQUEST_PIC "-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}") + set(CUDA_REQUEST_PIC "-Xcompiler ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") +else() + set(CONFIGURE_REQUEST_PIC) + set(CMAKE_REQUEST_PIC) + set(CUDA_REQUEST_PIC) +endif() + + if(PKG_VORONOI) - option(DOWNLOAD_VORO "Download voro++ (instead of using the system's one)" OFF) + option(DOWNLOAD_VORO "Download and compile the Voro++ library instead of using an already installed one" OFF) if(DOWNLOAD_VORO) + message(STATUS "Voro++ download requested - we will build our own") include(ExternalProject) if(BUILD_SHARED_LIBS) - set(VORO_BUILD_OPTIONS "CFLAGS=-fPIC") + set(VORO_BUILD_CFLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS} ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTYPE}}") else() - set(VORO_BUILD_OPTIONS) + set(VORO_BUILD_CFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BTYPE}}") endif() + string(APPEND VORO_BUILD_CFLAGS ${CMAKE_CXX_FLAGS}) + set(VORO_BUILD_OPTIONS CXX=${CMAKE_CXX_COMPILER} CFLAGS=${VORO_BUILD_CFLAGS}) ExternalProject_Add(voro_build URL http://math.lbl.gov/voro++/download/dir/voro++-0.4.6.tar.gz @@ -444,7 +464,7 @@ if(PKG_VORONOI) else() find_package(VORO) if(NOT VORO_FOUND) - message(FATAL_ERROR "VORO not found, help CMake to find it by setting VORO_LIBRARY and VORO_INCLUDE_DIR, or set DOWNLOAD_VORO=ON to download it") + message(FATAL_ERROR "Voro++ library not found. Help CMake to find it by setting VORO_LIBRARY and VORO_INCLUDE_DIR, or set DOWNLOAD_VORO=ON to download it") endif() endif() include_directories(${VORO_INCLUDE_DIRS}) @@ -452,26 +472,26 @@ if(PKG_VORONOI) endif() if(PKG_LATTE) - option(DOWNLOAD_LATTE "Download latte (instead of using the system's one)" OFF) + option(DOWNLOAD_LATTE "Download the LATTE library instead of using an already installed one" OFF) if(DOWNLOAD_LATTE) if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR message(FATAL_ERROR "For downlading LATTE you need at least cmake-3.7") endif() - message(STATUS "LATTE not found - we will build our own") + message(STATUS "LATTE download requested - we will build our own") include(ExternalProject) ExternalProject_Add(latte_build URL https://github.com/lanl/LATTE/archive/v1.2.1.tar.gz URL_MD5 85ac414fdada2d04619c8f936344df14 SOURCE_SUBDIR cmake - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} - ) + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= ${CMAKE_REQUEST_PIC} + ) ExternalProject_get_property(latte_build INSTALL_DIR) set(LATTE_LIBRARIES ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/liblatte.a) list(APPEND LAMMPS_DEPS latte_build) else() find_package(LATTE) if(NOT LATTE_FOUND) - message(FATAL_ERROR "LATTE not found, help CMake to find it by setting LATTE_LIBRARY, or set DOWNLOAD_LATTE=ON to download it") + message(FATAL_ERROR "LATTE library not found, help CMake to find it by setting LATTE_LIBRARY, or set DOWNLOAD_LATTE=ON to download it") endif() endif() list(APPEND LAMMPS_LINK_LIBS ${LATTE_LIBRARIES} ${LAPACK_LIBRARIES}) @@ -479,24 +499,22 @@ endif() if(PKG_USER-SCAFACOS) find_package(GSL REQUIRED) - option(DOWNLOAD_SCAFACOS "Download ScaFaCoS (instead of using the system's one)" OFF) + option(DOWNLOAD_SCAFACOS "Download ScaFaCoS library instead of using an already installed one" OFF) if(DOWNLOAD_SCAFACOS) + message(STATUS "ScaFaCoS download requested - we will build our own") include(ExternalProject) ExternalProject_Add(scafacos_build URL https://github.com/scafacos/scafacos/releases/download/v1.0.1/scafacos-1.0.1.tar.gz URL_MD5 bd46d74e3296bd8a444d731bb10c1738 - CONFIGURE_COMMAND /configure --prefix= - --disable-doc + CONFIGURE_COMMAND /configure --prefix= --disable-doc --enable-fcs-solvers=fmm,p2nfft,direct,ewald,p3m - --with-internal-fftw - --with-internal-pfft - --with-internal-pnfft - $<$:--with-pic> + --with-internal-fftw --with-internal-pfft + --with-internal-pnfft ${CONFIGURE_REQUEST_PIC} FC=${CMAKE_MPI_Fortran_COMPILER} CXX=${CMAKE_MPI_CXX_COMPILER} CC=${CMAKE_MPI_C_COMPILER} F77= - ) + ) ExternalProject_get_property(scafacos_build INSTALL_DIR) set(SCAFACOS_BUILD_DIR ${INSTALL_DIR}) set(SCAFACOS_INCLUDE_DIRS ${SCAFACOS_BUILD_DIR}/include) @@ -528,6 +546,54 @@ if(PKG_USER-SCAFACOS) include_directories(${SCAFACOS_INCLUDE_DIRS}) endif() +if(PKG_USER-PLUMED) + find_package(GSL REQUIRED) + set(PLUMED_MODE "static" CACHE STRING "Linkage mode for Plumed2 library") + set(PLUMED_MODE_VALUES static shared runtime) + set_property(CACHE PLUMED_MODE PROPERTY STRINGS ${PLUMED_MODE_VALUES}) + validate_option(PLUMED_MODE PLUMED_MODE_VALUES) + string(TOUPPER ${PLUMED_MODE} PLUMED_MODE) + + option(DOWNLOAD_PLUMED "Download Plumed package instead of using an already installed one" OFF) + if(DOWNLOAD_PLUMED) + message(STATUS "PLUMED download requested - we will build our own") + include(ExternalProject) + ExternalProject_Add(plumed_build + URL https://github.com/plumed/plumed2/releases/download/v2.4.3/plumed-src-2.4.3.tgz + URL_MD5 b1be7c48971627febc11c61b70767fc5 + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND /configure --prefix= ${CONFIGURE_REQUEST_PIC}) + ExternalProject_get_property(plumed_build INSTALL_DIR) + set(PLUMED_INSTALL_DIR ${INSTALL_DIR}) + list(APPEND LAMMPS_DEPS plumed_build) + if(PLUMED_MODE STREQUAL "STATIC") + add_definitions(-D__PLUMED_WRAPPER_CXX=1) + list(APPEND LAMMPS_LINK_LIBS ${PLUMED_INSTALL_DIR}/lib/plumed/obj/kernel.o + "${PLUMED_INSTALL_DIR}/lib/plumed/obj/PlumedStatic.o" ${GSL_LIBRARIES} ${CMAKE_DL_LIBS}) + elseif(PLUMED_MODE STREQUAL "SHARED") + list(APPEND LAMMPS_LINK_LIBS ${PLUMED_INSTALL_DIR}/lib/libplumed.so ${CMAKE_DL_LIBS}) + elseif(PLUMED_MODE STREQUAL "RUNTIME") + add_definitions(-D__PLUMED_HAS_DLOPEN=1 -D__PLUMED_DEFAULT_KERNEL=${PLUMED_INSTALL_DIR}/lib/libplumedKernel.so) + list(APPEND LAMMPS_LINK_LIBS ${PLUMED_INSTALL_DIR}/lib/libplumedWrapper.a -rdynamic ${CMAKE_DL_LIBS}) + endif() + set(PLUMED_INCLUDE_DIRS "${PLUMED_INSTALL_DIR}/include") + else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(PLUMED plumed REQUIRED) + if(PLUMED_MODE STREQUAL "STATIC") + add_definitions(-D__PLUMED_WRAPPER_CXX=1) + include(${PLUMED_LIBDIR}/plumed/src/lib/Plumed.cmake.static) + elseif(PLUMED_MODE STREQUAL "SHARED") + include(${PLUMED_LIBDIR}/plumed/src/lib/Plumed.cmake.shared) + elseif(PLUMED_MODE STREQUAL "RUNTIME") + add_definitions(-D__PLUMED_HAS_DLOPEN=1 -D__PLUMED_DEFAULT_KERNEL=${PLUMED_LIBDIR}/libplumedKernel.so) + include(${PLUMED_LIBDIR}/plumed/src/lib/Plumed.cmake.runtime) + endif() + list(APPEND LAMMPS_LINK_LIBS ${PLUMED_LOAD}) + endif() + include_directories(${PLUMED_INCLUDE_DIRS}) +endif() + if(PKG_USER-MOLFILE) add_library(molfile INTERFACE) target_include_directories(molfile INTERFACE ${LAMMPS_LIB_SOURCE_DIR}/molfile) @@ -543,8 +609,9 @@ if(PKG_USER-NETCDF) endif() if(PKG_USER-SMD) - option(DOWNLOAD_EIGEN3 "Download Eigen3 (instead of using the system's one)" OFF) + option(DOWNLOAD_EIGEN3 "Download Eigen3 instead of using an already installed one)" OFF) if(DOWNLOAD_EIGEN3) + message(STATUS "Eigen3 download requested - we will build our own") include(ExternalProject) ExternalProject_Add(Eigen3_build URL http://bitbucket.org/eigen/eigen/get/3.3.4.tar.gz @@ -584,8 +651,9 @@ if(PKG_USER-VTK) endif() if(PKG_KIM) - option(DOWNLOAD_KIM "Download kim-api (instead of using the system's one)" OFF) + option(DOWNLOAD_KIM "Download KIM-API v2 from OpenKIM instead of using an already installed one" OFF) if(DOWNLOAD_KIM) + message(STATUS "KIM-API v2 download requested - we will build our own") enable_language(C) enable_language(Fortran) include(ExternalProject) @@ -606,7 +674,7 @@ if(PKG_KIM) else() find_package(KIM-API-V2) if(NOT KIM-API-V2_FOUND) - message(FATAL_ERROR "KIM not found, help CMake to find it by setting PKG_CONFIG_PATH, or set DOWNLOAD_KIM=ON to download it") + message(FATAL_ERROR "KIM-API v2 not found, help CMake to find it by setting PKG_CONFIG_PATH, or set DOWNLOAD_KIM=ON to download it") endif() endif() list(APPEND LAMMPS_LINK_LIBS "${KIM-API-V2_LDFLAGS}") @@ -619,12 +687,7 @@ if(PKG_MESSAGE) ${LAMMPS_LIB_SOURCE_DIR}/message/cslib/[^.]*.c ${LAMMPS_LIB_SOURCE_DIR}/message/cslib/[^.]*.cpp) - if(BUILD_SHARED_LIBS) - add_library(cslib SHARED ${cslib_SOURCES}) - else() - add_library(cslib STATIC ${cslib_SOURCES}) - endif() - + add_library(cslib STATIC ${cslib_SOURCES}) if(BUILD_MPI) target_compile_definitions(cslib PRIVATE -DMPI_YES) set_target_properties(cslib PROPERTIES OUTPUT_NAME "csmpi") @@ -649,10 +712,10 @@ endif() if(PKG_MSCG) find_package(GSL REQUIRED) - option(DOWNLOAD_MSCG "Download latte (instead of using the system's one)" OFF) + option(DOWNLOAD_MSCG "Download MSCG library instead of using an already installed one)" OFF) if(DOWNLOAD_MSCG) if (CMAKE_VERSION VERSION_LESS "3.7") # due to SOURCE_SUBDIR - message(FATAL_ERROR "For downlading LATTE you need at least cmake-3.7") + message(FATAL_ERROR "For downlading MSCG you need at least cmake-3.7") endif() include(ExternalProject) if(NOT LAPACK_FOUND) @@ -662,7 +725,7 @@ if(PKG_MSCG) URL https://github.com/uchicago-voth/MSCG-release/archive/1.7.3.1.tar.gz URL_MD5 8c45e269ee13f60b303edd7823866a91 SOURCE_SUBDIR src/CMake - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} ${EXTRA_MSCG_OPTS} + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX= ${CMAKE_REQUEST_PIC} ${EXTRA_MSCG_OPTS} BUILD_COMMAND make mscg INSTALL_COMMAND "" ) ExternalProject_get_property(mscg_build BINARY_DIR) @@ -710,7 +773,7 @@ set(MATH_LIBRARIES "m" CACHE STRING "math library") mark_as_advanced( MATH_LIBRARIES ) include(CheckLibraryExists) if (CMAKE_VERSION VERSION_LESS "3.4") - enable_language(C) # check_library_exists isn't supported without a c compiler before v3.4 + enable_language(C) # check_library_exists isn't supported without a C compiler before v3.4 endif() # RB: disabled this check because it breaks with KOKKOS CUDA enabled #foreach(FUNC sin cos) @@ -748,6 +811,13 @@ foreach(PKG ${DEFAULT_PACKAGES}) endif() endforeach() +# packages that need defines set +foreach(PKG MPIIO) + if(PKG_${PKG}) + add_definitions(-DLMP_${PKG}) + endif() +endforeach() + # dedicated check for entire contents of accelerator packages foreach(PKG ${ACCEL_PACKAGES}) set(${PKG}_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/${PKG}) @@ -776,7 +846,7 @@ foreach(SIMPLE_LIB REAX MEAM POEMS USER-ATC USER-AWPMD USER-COLVARS USER-H5MD if(PKG_LIB STREQUAL awpmd) target_include_directories(awpmd PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/awpmd/systems/interact ${LAMMPS_LIB_SOURCE_DIR}/awpmd/ivutils/include) elseif(PKG_LIB STREQUAL h5md) - target_include_directories(h5md PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/h5md/include) + target_include_directories(h5md PUBLIC ${LAMMPS_LIB_SOURCE_DIR}/h5md/include ${HDF5_INCLUDE_DIRS}) elseif(PKG_LIB STREQUAL colvars) target_compile_options(colvars PRIVATE -DLEPTON) target_include_directories(colvars PRIVATE ${LAMMPS_LIB_SOURCE_DIR}/colvars/lepton/include) @@ -792,6 +862,9 @@ if(PKG_USER-AWPMD) endif() if(PKG_USER-ATC) + if(LAMMPS_SIZES STREQUAL BIGBIG) + message(FATAL_ERROR "The USER-ATC Package is not compatible with -DLAMMPS_BIGBIG") + endif() target_link_libraries(atc ${LAPACK_LIBRARIES}) endif() @@ -799,6 +872,7 @@ if(PKG_USER-H5MD) find_package(HDF5 REQUIRED) target_link_libraries(h5md ${HDF5_LIBRARIES}) target_include_directories(h5md PRIVATE ${HDF5_INCLUDE_DIRS}) + include_directories(${HDF5_INCLUDE_DIRS}) endif() @@ -884,6 +958,20 @@ if(PKG_USER-OMP) include_directories(${USER-OMP_SOURCES_DIR}) endif() +# Fix rigid/meso requires RIGID to be installed +if(PKG_USER-SDPD) + set(USER-SDPD_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/USER-SDPD) + + get_property(hlist GLOBAL PROPERTY FIX) + if(NOT PKG_RIGID) + list(REMOVE_ITEM hlist ${USER-SDPD_SOURCES_DIR}/fix_rigid_meso.h) + list(REMOVE_ITEM LIB_SOURCES ${USER-SDPD_SOURCES_DIR}/fix_rigid_meso.cpp) + endif() + set_property(GLOBAL PROPERTY FIX "${hlist}") + + include_directories(${USER-SDPD_SOURCES_DIR}) +endif() + if(PKG_KOKKOS) set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos) set(LAMMPS_LIB_KOKKOS_BIN_DIR ${LAMMPS_LIB_BINARY_DIR}/kokkos) @@ -961,7 +1049,7 @@ if(PKG_USER-INTEL) endif() if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16) - message(FATAL_ERROR "USER-INTEL is needed at least 2016 intel compiler, found ${CMAKE_CXX_COMPILER_VERSION}") + message(FATAL_ERROR "USER-INTEL needs at least a 2016 intel compiler, found ${CMAKE_CXX_COMPILER_VERSION}") endif() if(NOT BUILD_OMP) @@ -1061,11 +1149,11 @@ if(PKG_GPU) find_package(CUDA REQUIRED) find_program(BIN2C bin2c) if(NOT BIN2C) - message(FATAL_ERROR "Couldn't find bin2c, use -DBIN2C helping cmake to find it.") + message(FATAL_ERROR "Could not find bin2c, use -DBIN2C=/path/to/bin2c to help cmake finding it.") endif() option(CUDPP_OPT "Enable CUDPP_OPT" ON) - set(GPU_ARCH "sm_30" CACHE STRING "LAMMPS GPU CUDA SM architecture (e.g. sm_60)") + set(GPU_ARCH "sm_30" CACHE STRING "LAMMPS GPU CUDA SM primary architecture (e.g. sm_60)") file(GLOB GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/[^.]*.cu ${CMAKE_CURRENT_SOURCE_DIR}/gpu/[^.]*.cu) list(REMOVE_ITEM GPU_LIB_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/lal_pppm.cu) @@ -1078,11 +1166,39 @@ if(PKG_GPU) file(GLOB GPU_LIB_CUDPP_CU ${LAMMPS_LIB_SOURCE_DIR}/gpu/cudpp_mini/[^.]*.cu) endif() - cuda_compile_cubin(GPU_GEN_OBJS ${GPU_LIB_CU} OPTIONS - -DUNIX -O3 -Xptxas -v --use_fast_math -DNV_KERNEL -DUCL_CUDADR -arch=${GPU_ARCH} -D_${GPU_PREC_SETTING}) + # build arch/gencode commands for nvcc based on CUDA toolkit version and use choice + # --arch translates directly instead of JIT, so this should be for the preferred or most common architecture + set(GPU_CUDA_GENCODE "-arch=${GPU_ARCH} ") + # Fermi (GPU Arch 2.x) is supported by CUDA 3.2 to CUDA 8.0 + if((CUDA_VERSION VERSION_GREATER "3.1") AND (CUDA_VERSION VERSION_LESS "9.0")) + string(APPEND GPU_CUDA_GENCODE "-gencode arch=compute_20,code=[sm_20,compute_20] ") + endif() + # Kepler (GPU Arch 3.x) is supported by CUDA 5 and later + if(CUDA_VERSION VERSION_GREATER "4.9") + string(APPEND GPU_CUDA_GENCODE "-gencode arch=compute_30,code=[sm_30,compute_30] -gencode arch=compute_35,code=[sm_35,compute_35] ") + endif() + # Maxwell (GPU Arch 5.x) is supported by CUDA 6 and later + if(CUDA_VERSION VERSION_GREATER "5.9") + string(APPEND GPU_CUDA_GENCODE "-gencode arch=compute_50,code=[sm_50,compute_50] -gencode arch=compute_52,code=[sm_52,compute_52] ") + endif() + # Pascal (GPU Arch 6.x) is supported by CUDA 8 and later + if(CUDA_VERSION VERSION_GREATER "7.9") + string(APPEND GPU_CUDA_GENCODE "-gencode arch=compute_60,code=[sm_60,compute_60] -gencode arch=compute_61,code=[sm_61,compute_61] ") + endif() + # Volta (GPU Arch 7.0) is supported by CUDA 9 and later + if(CUDA_VERSION VERSION_GREATER "8.9") + string(APPEND GPU_CUDA_GENCODE "-gencode arch=compute_70,code=[sm_70,compute_70] ") + endif() + # Turing (GPU Arch 7.5) is supported by CUDA 10 and later + if(CUDA_VERSION VERSION_GREATER "9.9") + string(APPEND GPU_CUDA_GENCODE "-gencode arch=compute_75,code=[sm_75,compute_75] ") + endif() + + cuda_compile_fatbin(GPU_GEN_OBJS ${GPU_LIB_CU} OPTIONS + -DUNIX -O3 --use_fast_math -Wno-deprecated-gpu-targets -DNV_KERNEL -DUCL_CUDADR ${GPU_CUDA_GENCODE} -D_${GPU_PREC_SETTING}) - cuda_compile(GPU_OBJS ${GPU_LIB_CUDPP_CU} OPTIONS $<$:-Xcompiler=-fPIC> - -DUNIX -O3 -Xptxas -v --use_fast_math -DUCL_CUDADR -arch=${GPU_ARCH} -D_${GPU_PREC_SETTING}) + cuda_compile(GPU_OBJS ${GPU_LIB_CUDPP_CU} OPTIONS ${CUDA_REQUEST_PIC} + -DUNIX -O3 --use_fast_math -Wno-deprecated-gpu-targets -DUCL_CUDADR ${GPU_CUDA_GENCODE} -D_${GPU_PREC_SETTING}) foreach(CU_OBJ ${GPU_GEN_OBJS}) get_filename_component(CU_NAME ${CU_OBJ} NAME_WE) @@ -1351,7 +1467,6 @@ foreach(PKG ${DEFAULT_PACKAGES} ${ACCEL_PACKAGES} ${OTHER_PACKAGES}) endif() endforeach() -string(TOUPPER "${CMAKE_BUILD_TYPE}" BTYPE) get_directory_property(CPPFLAGS DIRECTORY ${CMAKE_SOURCE_DIR} COMPILE_DEFINITIONS) include(FeatureSummary) feature_summary(DESCRIPTION "The following packages have been found:" WHAT PACKAGES_FOUND) @@ -1382,7 +1497,7 @@ endif() if(CMAKE_EXE_LINKER_FLAGS) message(STATUS "Linker flags: Executable ${CMAKE_EXE_LINKER_FLAGS}") - endif() +endif() if(BUILD_SHARED_LIBS) message(STATUS "Shared libraries ${CMAKE_SHARED_LINKER_FLAGS}") else() -- GitLab From 67782d71a8126512ced150224b96aea3cea67817 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Tue, 18 Dec 2018 21:23:04 -0700 Subject: [PATCH 0075/1243] Granular pair style files added --- src/GRANULAR/pair_gran_dmt_rolling2.cpp | 719 ++++++++++ src/GRANULAR/pair_gran_hooke_history.cpp | 3 +- src/GRANULAR/pair_gran_hooke_history.h | 2 +- .../pair_gran_hooke_history_multi.cpp | 915 +++++++++++++ src/GRANULAR/pair_gran_hooke_history_multi.h | 109 ++ src/GRANULAR/pair_gran_jkr_rolling_multi.cpp | 1181 ++++++++++++++++ src/GRANULAR/pair_gran_jkr_rolling_multi.h | 87 ++ src/GRANULAR/pair_granular.cpp | 1187 +++++++++++++++++ src/GRANULAR/pair_granular.h | 89 ++ 9 files changed, 4289 insertions(+), 3 deletions(-) create mode 100644 src/GRANULAR/pair_gran_dmt_rolling2.cpp create mode 100644 src/GRANULAR/pair_gran_hooke_history_multi.cpp create mode 100644 src/GRANULAR/pair_gran_hooke_history_multi.h create mode 100644 src/GRANULAR/pair_gran_jkr_rolling_multi.cpp create mode 100644 src/GRANULAR/pair_gran_jkr_rolling_multi.h create mode 100644 src/GRANULAR/pair_granular.cpp create mode 100644 src/GRANULAR/pair_granular.h diff --git a/src/GRANULAR/pair_gran_dmt_rolling2.cpp b/src/GRANULAR/pair_gran_dmt_rolling2.cpp new file mode 100644 index 0000000000..5c1211cbc5 --- /dev/null +++ b/src/GRANULAR/pair_gran_dmt_rolling2.cpp @@ -0,0 +1,719 @@ +/* ---------------------------------------------------------------------- + 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: Leo Silbert (SNL), Gary Grest (SNL) + ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_gran_dmt_rolling.h" +#include "atom.h" +#include "update.h" +#include "force.h" +#include "fix.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "comm.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define TWOTHIRDS 0.6666666666666666 +#define EPSILON 1e-10 + +enum {TSUJI, BRILLIANTOV}; +enum {INDEP, BRILLROLL}; + +/* ---------------------------------------------------------------------- */ + +PairGranDMTRolling::PairGranDMTRolling(LAMMPS *lmp) : + PairGranHookeHistory(lmp, 7), + E_one(0), G_one(0), pois(0), muS_one(0), cor(0), alpha_one(0), + Ecoh_one(0), kR_one(0), muR_one(0), etaR_one(0) +{ + int ntypes = atom->ntypes; + memory->create(E,ntypes+1,ntypes+1,"pair:E"); + memory->create(G,ntypes+1,ntypes+1,"pair:G"); + memory->create(alpha,ntypes+1,ntypes+1,"pair:alpha"); + memory->create(gamman,ntypes+1,ntypes+1,"pair:gamman"); + memory->create(muS,ntypes+1,ntypes+1,"pair:muS"); + memory->create(Ecoh,ntypes+1,ntypes+1,"pair:Ecoh"); + memory->create(kR,ntypes+1,ntypes+1,"pair:kR"); + memory->create(muR,ntypes+1,ntypes+1,"pair:muR"); + memory->create(etaR,ntypes+1,ntypes+1,"pair:etaR"); +} + +/* ---------------------------------------------------------------------- */ +PairGranDMTRolling::~PairGranDMTRolling() +{ + delete [] E_one; + delete [] G_one; + delete [] pois; + delete [] muS_one; + delete [] cor; + delete [] alpha_one; + delete [] Ecoh_one; + delete [] kR_one; + delete [] muR_one; + delete [] etaR_one; + //TODO: Make all this work with standard pair coeff type commands. + //Also these should not be in the destructor. + memory->destroy(E); + memory->destroy(G); + memory->destroy(alpha); + memory->destroy(gamman); + memory->destroy(muS); + memory->destroy(Ecoh); + memory->destroy(kR); + memory->destroy(muR); + memory->destroy(etaR); +} +/* ---------------------------------------------------------------------- */ + +void PairGranDMTRolling::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum; + int itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + double Fhz, Fdamp, Fdmt, Fne, Fntot, Fscrit, Frcrit; + double overlap; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + double signtwist, magtwist, magtortwist, Mtcrit; + double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; + double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int shearupdate = 1; + if (update->setupflag) shearupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + 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 *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = list->listhistory->firstneigh; + firstshear = list->listhistory->firstdouble; + + // loop over neighbors of my atoms + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + 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]; + + for (jj = 0; jj < jnum; jj++) { + j = jlist[jj]; + jtype = type[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]; + radsum = radi + radj; + + if (rsq >= radsum*radsum){ + // unset non-touching neighbors + touch[jj] = 0; + shear = &allshear[nsheardim*jj]; + for (int k = 0; k < nsheardim; k++) + shear[k] = 0.0; + } else { + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/(radi+radj); + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + //**************************************** + //Normal force = Hertzian contact + DMT + damping + //**************************************** + overlap = radsum - r; + a = sqrt(R*overlap); + kn = 4.0/3.0*E[itype][jtype]*a; + Fhz = kn*overlap; + + //Damping (based on Tsuji et al) + if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + //DMT + Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; + + Fne = Fhz + Fdmt; + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including shear history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting + //delta/2, i.e. instead of radi, use distance to center of contact point? + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + touch[jj] = 1; + shear = &allshear[nsheardim*jj]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // Rotate and update shear displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (shearupdate) { + rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shear[0] -= rsht*nx; + shear[1] -= rsht*ny; + shear[2] -= rsht*nz; + //Also rescale to preserve magnitude + shear[0] *= scalefac; + shear[1] *= scalefac; + shear[2] *= scalefac; + } + //Update shear history + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + + // tangential forces = shear + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = muS[itype][jtype] * fabs(Fne); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + //**************************************** + // Rolling force, including shear history effects + //**************************************** + + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // Rolling displacement + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); + rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; + + if (shearupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + shear[3] -= rolldotn*nx; + shear[4] -= rolldotn*ny; + shear[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + shear[3] *= scalefac; + shear[4] *= scalefac; + shear[5] *= scalefac; + } + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + } + + k_R = kR[itype][jtype]; + if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; + else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); + fr1 = -k_R*shear[3] - eta_R*vrl1; + fr2 = -k_R*shear[4] - eta_R*vrl2; + fr3 = -k_R*shear[5] - eta_R*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = muR[itype][jtype] * fabs(Fne); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + + + //**************************************** + // Twisting torque, including shear history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + shear[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit){ + shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + + if (force->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; + + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + +/* ---------------------------------------------------------------------- + global settings + ------------------------------------------------------------------------- */ + +void PairGranDMTRolling::settings(int narg, char **arg) +{ + if (narg < 6) error->all(FLERR,"Illegal pair_style command"); + + int ntypes = atom->ntypes; + + if (narg < 8*ntypes) error->all(FLERR,"Illegal pair_style command"); + + E_one = new double[ntypes+1]; + G_one = new double[ntypes+1]; + pois = new double[ntypes+1]; + muS_one = new double[ntypes+1]; + cor = new double[ntypes+1]; + alpha_one = new double[ntypes+1]; + Ecoh_one = new double[ntypes+1]; + kR_one = new double[ntypes+1]; + muR_one = new double[ntypes+1]; + etaR_one = new double[ntypes+1]; + + for (int i=0; i < ntypes;i++){ + E_one[i+1] = force->numeric(FLERR, arg[i]); + G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); + muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); + cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); + Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); + kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); + muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); + etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); + } + + //Defaults + normaldamp = TSUJI; + rollingdamp = INDEP; + + int iarg = 8*ntypes; + while (iarg < narg){ + if (strcmp(arg[iarg],"normaldamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else if (strcmp(arg[iarg],"rollingdamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else{ + iarg +=1; + } + } + + //Derived from inputs + for (int i=1; i <= ntypes; i++){ + pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; + alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; + for (int j=i; j <= ntypes; j++){ + E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); + G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); + if (normaldamp == TSUJI){ + alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); + } + else if (normaldamp == BRILLIANTOV){ + gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); + } + muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); + Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); + kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); + etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); + muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); + } + } +} + +/* ---------------------------------------------------------------------- */ + +double PairGranDMTRolling::single(int i, int j, int itype, int jtype, + double rsq, + double factor_coul, double factor_lj, + double &fforce) +{ + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double overlap, a; + double mi,mj,meff,damp,kn,kt; + double Fhz,Fdamp,Fdmt,Fne,Fntot,Fscrit; + double eta_N,eta_T; + double vtr1,vtr2,vtr3,vrel; + double fs1,fs2,fs3,fs; + double shrmag; + + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + + if (rsq >= radsum*radsum) { + fforce = 0.0; + svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + return 0.0; + } + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/radsum; + + // relative translational velocity + + double **v = atom->v; + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + + vnnr = vr1*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + + // normal force = Hertzian contact + normal velocity damping + overlap = radsum - r; + a = sqrt(R*overlap); + kn = 4.0/3.0*E[itype][jtype]*a; + Fhz = kn*overlap; + + //Damping (based on Tsuji et al) + + eta_N=alpha[itype][jtype]*sqrt(meff*kn); + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + //DMT + Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; + + Fne = Fhz + Fdmt; + Fntot = Fne + Fdamp; + + // relative velocities + + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + // neighprev = index of found neigh on previous call + // search entire jnum list of neighbors of I for neighbor J + // start from neighprev, since will typically be next neighbor + // reset neighprev to 0 as necessary + + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allshear = list->listhistory->firstdouble[i]; + + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + + double *shear = &allshear[nsheardim*neighprev]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // tangential forces = shear + tangential velocity damping + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; + fs1 = -kt*shear[0] - eta_T*vtr1; + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + Fscrit= muS[itype][jtype] * fabs(Fne); + + if (fs > Fscrit) { + if (shrmag != 0.0) { + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + fs *= Fscrit/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; + } + + // set all forces and return no energy + + fforce = Fntot; + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = vn1; + svector[5] = vn2; + svector[6] = vn3; + svector[7] = vt1; + svector[8] = vt2; + svector[9] = vt3; + return 0.0; +} diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 4bc867e426..cf30e77ccb 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -39,8 +39,7 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp, int _size_history) : Pair(lmp), - size_history(_size_history) +PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp) { single_enable = 1; no_virial_fdotr_compute = 1; diff --git a/src/GRANULAR/pair_gran_hooke_history.h b/src/GRANULAR/pair_gran_hooke_history.h index 6d9980919b..2cb609fd82 100644 --- a/src/GRANULAR/pair_gran_hooke_history.h +++ b/src/GRANULAR/pair_gran_hooke_history.h @@ -26,7 +26,7 @@ namespace LAMMPS_NS { class PairGranHookeHistory : public Pair { public: - PairGranHookeHistory(class LAMMPS *, int size_history = 3); + PairGranHookeHistory(class LAMMPS *); virtual ~PairGranHookeHistory(); virtual void compute(int, int); virtual void settings(int, char **); diff --git a/src/GRANULAR/pair_gran_hooke_history_multi.cpp b/src/GRANULAR/pair_gran_hooke_history_multi.cpp new file mode 100644 index 0000000000..48e793bbb3 --- /dev/null +++ b/src/GRANULAR/pair_gran_hooke_history_multi.cpp @@ -0,0 +1,915 @@ +/* ---------------------------------------------------------------------- + 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: Leo Silbert (SNL), Gary Grest (SNL) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_gran_hooke_history_multi.h" +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define BIG 1.0e20 + +/* ---------------------------------------------------------------------- */ + +PairGranHookeHistoryMulti::PairGranHookeHistoryMulti(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 1; + no_virial_fdotr_compute = 1; + history = 1; + fix_history = NULL; + + single_extra = 10; + svector = new double[10]; + + neighprev = 0; + + nmax = 0; + mass_rigid = NULL; + + // set comm size needed by this Pair if used with fix rigid + + comm_forward = 1; +} + +/* ---------------------------------------------------------------------- */ + +PairGranHookeHistoryMulti::~PairGranHookeHistoryMulti() +{ + delete [] svector; + if (fix_history) modify->delete_fix("NEIGH_HISTORY"); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(kn); + memory->destroy(kt); + memory->destroy(gamman); + memory->destroy(gammat); + memory->destroy(xmu); + memory->destroy(dampflag); + + delete [] onerad_dynamic; + delete [] onerad_frozen; + delete [] maxrad_dynamic; + delete [] maxrad_frozen; + } + memory->destroy(mass_rigid); +} + +/* ---------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,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 mi,mj,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; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int shearupdate = 1; + if (update->setupflag) shearupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0) { + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + 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 newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firstshear = fix_history->firstvalue; + + // 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]; + radi = radius[i]; + touch = firsttouch[i]; + allshear = firstshear[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]; + 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; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + // normal forces = Hookian contact + normal velocity damping + + damp = meff*gamman[itype][jtype]*vnnr*rsqinv; + ccel = kn[itype][jtype]*(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[itype][jtype]*shear[0] + meff*gammat[itype][jtype]*vtr1); + fs2 = - (kt[itype][jtype]*shear[1] + meff*gammat[itype][jtype]*vtr2); + fs3 = - (kt[itype][jtype]*shear[2] + meff*gammat[itype][jtype]*vtr3); + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + fn = xmu[itype][jtype] * fabs(ccel*r); + + if (fs > fn) { + if (shrmag != 0.0) { + shear[0] = (fn/fs) * (shear[0] + + meff*gammat[itype][jtype]*vtr1/kt[itype][jtype]) - + meff*gammat[itype][jtype]*vtr1/kt[itype][jtype]; + shear[1] = (fn/fs) * (shear[1] + + meff*gammat[itype][jtype]*vtr2/kt[itype][jtype]) - + meff*gammat[itype][jtype]*vtr2/kt[itype][jtype]; + shear[2] = (fn/fs) * (shear[2] + + meff*gammat[itype][jtype]*vtr3/kt[itype][jtype]) - + meff*gammat[itype][jtype]*vtr3/kt[itype][jtype]; + fs1 *= fn/fs; + fs2 *= fn/fs; + fs3 *= fn/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + // forces & torques + + fx = delx*ccel + fs1; + fy = dely*ccel + fs2; + fz = delz*ccel + fs3; + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = rinv * (dely*fs3 - delz*fs2); + tor2 = rinv * (delz*fs1 - delx*fs3); + tor3 = rinv * (delx*fs2 - dely*fs1); + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= 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(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 PairGranHookeHistoryMulti::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(kn,n+1,n+1,"pair:kn"); + memory->create(kt,n+1,n+1,"pair:kt"); + memory->create(gamman,n+1,n+1,"pair:gamman"); + memory->create(gammat,n+1,n+1,"pair:gammat"); + memory->create(xmu,n+1,n+1,"pair:xmu"); + memory->create(dampflag,n+1,n+1,"pair:dampflag"); + + onerad_dynamic = new double[n+1]; + onerad_frozen = new double[n+1]; + maxrad_dynamic = new double[n+1]; + maxrad_frozen = new double[n+1]; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + if (strcmp(arg[0],"NULL") == 0 ) cut_global = -1.0; + else cut_global = force->numeric(FLERR,arg[0]); + + // reset cutoffs that have been explicitly set + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::coeff(int narg, char **arg) +{ + if (narg < 8 || narg > 9) + error->all(FLERR,"Incorrect args for pair coefficients"); + + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double kn_one = force->numeric(FLERR,arg[2]); + double kt_one; + if (strcmp(arg[3],"NULL") == 0) kt_one = kn_one * 2.0/7.0; + else kt_one = force->numeric(FLERR,arg[3]); + + double gamman_one = force->numeric(FLERR,arg[4]); + double gammat_one; + if (strcmp(arg[5],"NULL") == 0) gammat_one = 0.5 * gamman_one; + else gammat_one = force->numeric(FLERR,arg[5]); + + double xmu_one = force->numeric(FLERR,arg[6]); + int dampflag_one = force->inumeric(FLERR,arg[7]); + if (dampflag_one == 0) gammat_one = 0.0; + + if (kn_one < 0.0 || kt_one < 0.0 || gamman_one < 0.0 || gammat_one < 0.0 || + xmu_one < 0.0 || xmu_one > 10000.0 || dampflag_one < 0 || dampflag_one > 1) + error->all(FLERR,"Illegal pair_style command"); + + // convert Kn and Kt from pressure units to force/distance^2 + kn_one /= force->nktv2p; + kt_one /= force->nktv2p; + + double cut_one = cut_global; + if (narg==9) { + if (strcmp(arg[8],"NULL") == 0) cut_one = -1.0; + else cut_one = force->numeric(FLERR,arg[8]); + } + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + kn[i][j] = kn_one; + kt[i][j] = kt_one; + gamman[i][j] = gamman_one; + gammat[i][j] = gammat_one; + xmu[i][j] = xmu_one; + dampflag[i][j] = dampflag_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 PairGranHookeHistoryMulti::init_style() +{ + int i; + + // error and warning checks + + if (!atom->radius_flag || !atom->rmass_flag) + error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); + + // need a granular neigh list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->size = 1; + if (history) neighbor->requests[irequest]->history = 1; + + dt = update->dt; + + // if shear history is stored: + // if first init, create Fix needed for storing shear history + + if (history && fix_history == NULL) { + char dnumstr[16]; + sprintf(dnumstr,"%d",3); + char **fixarg = new char*[4]; + fixarg[0] = (char *) "NEIGH_HISTORY"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "NEIGH_HISTORY"; + fixarg[3] = dnumstr; + modify->add_fix(4,fixarg,1); + delete [] fixarg; + fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; + fix_history->pair = this; + } + + // check for FixFreeze and set freeze_group_bit + + for (i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"freeze") == 0) break; + if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; + else freeze_group_bit = 0; + + // check for FixRigid so can extract rigid body masses + + fix_rigid = NULL; + for (i = 0; i < modify->nfix; i++) + if (modify->fix[i]->rigid_flag) break; + if (i < modify->nfix) fix_rigid = modify->fix[i]; + + // check for FixPour and FixDeposit so can extract particle radii + + int ipour; + for (ipour = 0; ipour < modify->nfix; ipour++) + if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; + if (ipour == modify->nfix) ipour = -1; + + int idep; + for (idep = 0; idep < modify->nfix; idep++) + if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; + if (idep == modify->nfix) idep = -1; + + // set maxrad_dynamic and maxrad_frozen for each type + // include future FixPour and FixDeposit particles as dynamic + + int itype; + for (i = 1; i <= atom->ntypes; i++) { + onerad_dynamic[i] = onerad_frozen[i] = 0.0; + if (ipour >= 0) { + itype = i; + onerad_dynamic[i] = + *((double *) modify->fix[ipour]->extract("radius",itype)); + } + if (idep >= 0) { + itype = i; + onerad_dynamic[i] = + *((double *) modify->fix[idep]->extract("radius",itype)); + } + } + + double *radius = atom->radius; + int *mask = atom->mask; + int *type = atom->type; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & freeze_group_bit) + onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]); + else + onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]); + + MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + + // set fix which stores history info + + if (history) { + int ifix = modify->find_fix("NEIGH_HISTORY"); + if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); + fix_history = (FixNeighHistory *) modify->fix[ifix]; + } +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairGranHookeHistoryMulti::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + kn[i][j] = mix_stiffness(kn[i][i],kn[j][j]); + kt[i][j] = mix_stiffness(kt[i][i],kt[j][j]); + gamman[i][j] = mix_damping(gamman[i][i],gamman[j][j]); + gammat[i][j] = mix_damping(gammat[i][i],gammat[j][j]); + xmu[i][j] = mix_friction(xmu[i][i],xmu[j][j]); + + dampflag[i][j] = 0; + if (dampflag[i][i] || dampflag[j][j]) dampflag[i][j] = 1; + + } + + kn[j][i] = kn[i][j]; + kt[j][i] = kt[i][j]; + gamman[j][i] = gamman[i][j]; + gammat[j][i] = gammat[i][j]; + xmu[j][i] = xmu[i][j]; + dampflag[j][i] = dampflag[i][j]; + + double cutoff = cut[i][j]; + + // It is likely that cut[i][j] at this point is still 0.0. This can happen when + // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates + // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size + // To avoid this issue,for cases involving cut[i][j] = 0.0 (possible only + // if there is no current information about radius/cutoff of type i and j). + // we assign cutoff = min(cut[i][j]) for i,j such that cut[i][j] > 0.0. + + if (cut[i][j] < 0.0) { + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; + } + } + return cutoff; +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::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(&kn[i][j],sizeof(double),1,fp); + fwrite(&kt[i][j],sizeof(double),1,fp); + fwrite(&gamman[i][j],sizeof(double),1,fp); + fwrite(&gammat[i][j],sizeof(double),1,fp); + fwrite(&xmu[i][j],sizeof(double),1,fp); + fwrite(&dampflag[i][j],sizeof(int),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::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(&kn[i][j],sizeof(double),1,fp); + fread(&kt[i][j],sizeof(double),1,fp); + fread(&gamman[i][j],sizeof(double),1,fp); + fread(&gammat[i][j],sizeof(double),1,fp); + fread(&xmu[i][j],sizeof(double),1,fp); + fread(&dampflag[i][j],sizeof(int),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&kn[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&kt[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gamman[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gammat[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&xmu[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&dampflag[i][j],1,MPI_INT,0,world); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file +------------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts +------------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_global,sizeof(double),1,fp); + } + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); +} + +/* ---------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::reset_dt() +{ + dt = update->dt; +} + +/* ---------------------------------------------------------------------- */ + +double PairGranHookeHistoryMulti::single(int i, int j, int itype, int jtype, + double rsq, + double factor_coul, double factor_lj, + double &fforce) +{ + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double mi,mj,meff,damp,ccel; + double vtr1,vtr2,vtr3,vrel,shrmag,rsht; + double fs1,fs2,fs3,fs,fn; + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + + if (rsq >= radsum*radsum) { + fforce = 0.0; + for (int m = 0; m < single_extra; m++) svector[m] = 0.0; + return 0.0; + } + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + // relative translational velocity + + double **v = atom->v; + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + 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 + + double **omega = atom->omega; + 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; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + double *rmass = atom->rmass; + int *mask = atom->mask; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: insure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + // normal forces = Hookian contact + normal velocity damping + + damp = meff*gamman[itype][jtype]*vnnr*rsqinv; + ccel = kn[itype][jtype]*(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 + // neighprev = index of found neigh on previous call + // search entire jnum list of neighbors of I for neighbor J + // start from neighprev, since will typically be next neighbor + // reset neighprev to 0 as necessary + + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allshear = fix_history->firstvalue[i]; + + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + + double *shear = &allshear[3*neighprev]; + 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; + + // tangential forces = shear + tangential velocity damping + + fs1 = - (kt[itype][jtype]*shear[0] + meff*gammat[itype][jtype]*vtr1); + fs2 = - (kt[itype][jtype]*shear[1] + meff*gammat[itype][jtype]*vtr2); + fs3 = - (kt[itype][jtype]*shear[2] + meff*gammat[itype][jtype]*vtr3); + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + fn = xmu[itype][jtype] * fabs(ccel*r); + + if (fs > fn) { + if (shrmag != 0.0) { + fs1 *= fn/fs; + fs2 *= fn/fs; + fs3 *= fn/fs; + fs *= fn/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; + } + + // set force and return no energy + + fforce = ccel; + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = vn1; + svector[5] = vn2; + svector[6] = vn3; + svector[7] = vt1; + svector[8] = vt2; + svector[9] = vt3; + + return 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int PairGranHookeHistoryMulti::pack_forward_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++] = mass_rigid[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranHookeHistoryMulti::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + mass_rigid[i] = buf[m++]; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays +------------------------------------------------------------------------- */ + +double PairGranHookeHistoryMulti::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} + +/* ---------------------------------------------------------------------- + mixing of stiffness +------------------------------------------------------------------------- */ + +double PairGranHookeHistoryMulti::mix_stiffness(double kii, double kjj) +{ + return kii*kjj/(kii + kjj); +} + +/* ---------------------------------------------------------------------- + mixing of damping +------------------------------------------------------------------------- */ + +double PairGranHookeHistoryMulti::mix_damping(double gammaii, double gammajj) +{ + return sqrt(gammaii*gammajj); +} + +/* ---------------------------------------------------------------------- + mixing of friction +------------------------------------------------------------------------- */ + +double PairGranHookeHistoryMulti::mix_friction(double xmuii, double xmujj) +{ + return MAX(xmuii,xmujj); +} + diff --git a/src/GRANULAR/pair_gran_hooke_history_multi.h b/src/GRANULAR/pair_gran_hooke_history_multi.h new file mode 100644 index 0000000000..f302ede96c --- /dev/null +++ b/src/GRANULAR/pair_gran_hooke_history_multi.h @@ -0,0 +1,109 @@ +/* -*- 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(gran/hooke/history/multi,PairGranHookeHistoryMulti) + +#else + +#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_MULTI_H +#define LMP_PAIR_GRAN_HOOKE_HISTORY_MULTI_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairGranHookeHistoryMulti : public Pair { + public: + PairGranHookeHistoryMulti(class LAMMPS *); + virtual ~PairGranHookeHistoryMulti(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); // Made Virtual by IS Oct 7 2017 + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + void reset_dt(); + virtual double single(int, int, int, int, double, double, double, double &); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + protected: + double cut_global; + double **kn,**kt,**gamman,**gammat,**xmu,**cut; + int **dampflag; + double dt; + int freeze_group_bit; + int history; + + int neighprev; + double *onerad_dynamic,*onerad_frozen; + double *maxrad_dynamic,*maxrad_frozen; + + class FixNeighHistory *fix_history; + + // storage of rigid body masses for use in granular interactions + + class Fix *fix_rigid; // ptr to rigid body fix, NULL if none + double *mass_rigid; // rigid mass for owned+ghost atoms + int nmax; // allocated size of mass_rigid + + virtual void allocate(); // Made Virtual by IS Oct 7 2017 + +private: + double mix_stiffness(double kii, double kjj); + double mix_damping(double gammaii, double gammajj); + double mix_friction(double xmuii, double xmujj); +}; + +} + +#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. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: Pair granular requires atom attributes radius, rmass + +The atom style defined does not have these attributes. + +E: Pair granular requires ghost atoms store velocity + +Use the comm_modify vel yes command to enable this. + +E: Pair granular with shear history requires newton pair off + +This is a current restriction of the implementation of pair +granular styles with history. + +E: Could not find pair fix ID + +A fix is created internally by the pair style to store shear +history information. You cannot delete it. + +*/ diff --git a/src/GRANULAR/pair_gran_jkr_rolling_multi.cpp b/src/GRANULAR/pair_gran_jkr_rolling_multi.cpp new file mode 100644 index 0000000000..a9156390e5 --- /dev/null +++ b/src/GRANULAR/pair_gran_jkr_rolling_multi.cpp @@ -0,0 +1,1181 @@ +/* ---------------------------------------------------------------------- +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: Leo Silbert (SNL), Gary Grest (SNL) + ------------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_gran_jkr_rolling_multi.h" +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" +//#include + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define ONETHIRD 0.33333333333333333 +#define TWOTHIRDS 0.66666666666666666 +#define POW6ONE 0.550321208149104 //6^(-1/3) +#define POW6TWO 0.30285343213869 //6^(-2/3) + +#define EPSILON 1e-10 + +enum {TSUJI, BRILLIANTOV}; +enum {INDEP, BRILLROLL}; + +/* ---------------------------------------------------------------------- */ + +PairGranJKRRollingMulti::PairGranJKRRollingMulti(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 1; + no_virial_fdotr_compute = 1; + history = 1; + fix_history = NULL; + + single_extra = 10; + svector = new double[10]; + + neighprev = 0; + + nmax = 0; + mass_rigid = NULL; + + // set comm size needed by this Pair if used with fix rigid + + comm_forward = 1; +} + +/* ---------------------------------------------------------------------- */ +PairGranJKRRollingMulti::~PairGranJKRRollingMulti() +{ + delete [] svector; + if (fix_history) modify->delete_fix("NEIGH_HISTORY"); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(E); + memory->destroy(G); + memory->destroy(normaldamp); + memory->destroy(rollingdamp); + memory->destroy(alpha); + memory->destroy(gamman); + memory->destroy(muS); + memory->destroy(Ecoh); + memory->destroy(kR); + memory->destroy(muR); + memory->destroy(etaR); + + delete [] onerad_dynamic; + delete [] onerad_frozen; + delete [] maxrad_dynamic; + delete [] maxrad_frozen; + } + memory->destroy(mass_rigid); +} +/* ---------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::compute(int eflag, int vflag) +{ +// feenableexcept(FE_INVALID | FE_OVERFLOW); + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + double Fne, Fdamp, Fntot, Fscrit, Frcrit, F_C, delta_C, delta_Cinv; + double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; + double keyterm, keyterm2, keyterm3, aovera0, foverFc; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + double signtwist, magtwist, magtortwist, Mtcrit; + double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; + double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *shear,*allshear,**firstshear; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int shearupdate = 1; + if (update->setupflag) shearupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + 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 newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firstshear = fix_history->firstvalue; + + // 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]; + radi = radius[i]; + touch = firsttouch[i]; + allshear = firstshear[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]; + jtype = type[j]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + R = radi*radj/(radi+radj); + a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); + delta_C = 0.5*a0*a0*POW6ONE/R; + + if ((rsq >= radsum*radsum && touch[jj] == 0) || + (rsq >= (radsum+delta_C)*(radsum+delta_C))) { + + // unset non-touching neighbors + + touch[jj] = 0; + shear = &allshear[3*jj]; + shear[0] = 0.0; + shear[1] = 0.0; + shear[2] = 0.0; + + } else { + F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + //**************************************** + //Normal force = JKR-adjusted Hertzian contact + damping + //**************************************** + if (Ecoh[itype][jtype] != 0.0) delta_Cinv = 1.0/delta_C; + else delta_Cinv = 1.0; + overlap = (radsum - r)*delta_Cinv; + olapsq = overlap*overlap; + olapcubed = olapsq*overlap; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,ONETHIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = POW6TWO * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 + a = aovera0*a0; + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + + Fne = F_C*foverFc; + + //Damping + kn = 4.0/3.0*E[itype][jtype]*a; + if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + Fntot = Fne + Fdamp; + //if (screen) fprintf(screen,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); + //if (logfile) fprintf(logfile,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); + + //**************************************** + //Tangential force, including shear history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + // Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting + // delta/2, i.e. instead of radi, use distance to center of contact point? + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + touch[jj] = 1; + shear = &allshear[3*jj]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // Rotate and update shear displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (shearupdate) { + rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shear[0] -= rsht*nx; + shear[1] -= rsht*ny; + shear[2] -= rsht*nz; + //Also rescale to preserve magnitude + shear[0] *= scalefac; + shear[1] *= scalefac; + shear[2] *= scalefac; + } + //Update shear history + shear[0] += vtr1*dt; + shear[1] += vtr2*dt; + shear[2] += vtr3*dt; + } + + // tangential forces = shear + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = muS[itype][jtype] * fabs(Fne + 2*F_C); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + //**************************************** + // Rolling force, including shear history effects + //**************************************** + + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // Rolling displacement + rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); + rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; + + if (shearupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + shear[3] -= rolldotn*nx; + shear[4] -= rolldotn*ny; + shear[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + shear[3] *= scalefac; + shear[4] *= scalefac; + shear[5] *= scalefac; + } + shear[3] += vrl1*dt; + shear[4] += vrl2*dt; + shear[5] += vrl3*dt; + } + + k_R = kR[itype][jtype]*4.0*F_C*pow(aovera0,1.5); + if (rollingdamp[itype][jtype] == INDEP) eta_R = etaR[itype][jtype]; + else if (rollingdamp[itype][jtype] == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); + fr1 = -k_R*shear[3] - eta_R*vrl1; + fr2 = -k_R*shear[4] - eta_R*vrl2; + fr3 = -k_R*shear[5] - eta_R*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = muR[itype][jtype] * fabs(Fne + 2*F_C); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + + + //**************************************** + // Twisting torque, including shear history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + shear[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + //shear[6] = Mtcrit/k_Q*magtwist/fabs(magtwist); + shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + //if (screen) fprintf(screen,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); + //if (logfile) fprintf(logfile,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + + if (force->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; + + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + + +/* ---------------------------------------------------------------------- + allocate all arrays + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::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(E,n+1,n+1,"pair:E"); + memory->create(G,n+1,n+1,"pair:G"); + memory->create(normaldamp,n+1,n+1,"pair:normaldamp"); + memory->create(rollingdamp,n+1,n+1,"pair:rollingdamp"); + memory->create(alpha,n+1,n+1,"pair:alpha"); + memory->create(gamman,n+1,n+1,"pair:gamman"); + memory->create(muS,n+1,n+1,"pair:muS"); + memory->create(Ecoh,n+1,n+1,"pair:Ecoh"); + memory->create(kR,n+1,n+1,"pair:kR"); + memory->create(muR,n+1,n+1,"pair:muR"); + memory->create(etaR,n+1,n+1,"pair:etaR"); + + onerad_dynamic = new double[n+1]; + onerad_frozen = new double[n+1]; + maxrad_dynamic = new double[n+1]; + maxrad_frozen = new double[n+1]; +} + +/* ---------------------------------------------------------------------- + global settings + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + if (strcmp(arg[0],"NULL") == 0 ) cut_global = -1.0; + else cut_global = force->numeric(FLERR,arg[0]); + + // reset cutoffs that have been explicitly set + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::coeff(int narg, char **arg) +{ + if (narg < 10 || narg > 15) + error->all(FLERR,"Incorrect args for pair coefficients2"); + + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double E_one = force->numeric(FLERR,arg[2]); + double G_one = force->numeric(FLERR,arg[3]); + double muS_one = force->numeric(FLERR,arg[4]); + double cor_one = force->numeric(FLERR,arg[5]); + double Ecoh_one = force->numeric(FLERR,arg[6]); + double kR_one = force->numeric(FLERR,arg[7]); + double muR_one = force->numeric(FLERR,arg[8]); + double etaR_one = force->numeric(FLERR,arg[9]); + + //Defaults + int normaldamp_one = TSUJI; + int rollingdamp_one = INDEP; + double cut_one = cut_global; + + int iarg = 10; + while (iarg < narg) { + if (strcmp(arg[iarg],"normaldamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp_one = TSUJI; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp_one = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else if (strcmp(arg[iarg],"rollingdamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp_one = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp_one = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); + iarg +=2; + } + else { + if (strcmp(arg[iarg],"NULL") == 0) cut_one = -1.0; + else cut_one = force->numeric(FLERR,arg[iarg]); + iarg += 1; + } + } + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + double pois = E_one/(2.0*G_one) - 1.0; + double alpha_one = 1.2728-4.2783*cor_one+11.087*cor_one*cor_one-22.348*cor_one*cor_one*cor_one+27.467*cor_one*cor_one*cor_one*cor_one-18.022*cor_one*cor_one*cor_one*cor_one*cor_one+4.8218*cor_one*cor_one*cor_one*cor_one*cor_one*cor_one; + + for (int j = MAX(jlo,i); j <= jhi; j++) { + E[i][j] = E_one; + G[i][j] = G_one; + if (normaldamp_one == TSUJI) { + normaldamp[i][j] = TSUJI; + alpha[i][j] = alpha_one; + } + else if (normaldamp_one == BRILLIANTOV) { + normaldamp[i][j] = BRILLIANTOV; + gamman[i][j] = cor_one; + } + if (rollingdamp_one == INDEP) { + rollingdamp[i][j] = INDEP; + } + else if (rollingdamp_one == BRILLROLL) { + rollingdamp[i][j] = BRILLROLL; + } + muS[i][j] = muS_one; + Ecoh[i][j] = Ecoh_one; + kR[i][j] = kR_one; + etaR[i][j] = etaR_one; + muR[i][j] = muR_one; + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients1"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::init_style() +{ + int i; + + // error and warning checks + + if (!atom->radius_flag || !atom->rmass_flag) + error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); + + // need a granular neigh list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->size = 1; + if (history) neighbor->requests[irequest]->history = 1; + + dt = update->dt; + + // if shear history is stored: + // if first init, create Fix needed for storing shear history + + if (history && fix_history == NULL) { + char dnumstr[16]; + sprintf(dnumstr,"%d",3); + char **fixarg = new char*[4]; + fixarg[0] = (char *) "NEIGH_HISTORY"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "NEIGH_HISTORY"; + fixarg[3] = dnumstr; + modify->add_fix(4,fixarg,1); + delete [] fixarg; + fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; + fix_history->pair = this; + } + + // check for FixFreeze and set freeze_group_bit + + for (i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"freeze") == 0) break; + if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; + else freeze_group_bit = 0; + + // check for FixRigid so can extract rigid body masses + + fix_rigid = NULL; + for (i = 0; i < modify->nfix; i++) + if (modify->fix[i]->rigid_flag) break; + if (i < modify->nfix) fix_rigid = modify->fix[i]; + + // check for FixPour and FixDeposit so can extract particle radii + + int ipour; + for (ipour = 0; ipour < modify->nfix; ipour++) + if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; + if (ipour == modify->nfix) ipour = -1; + + int idep; + for (idep = 0; idep < modify->nfix; idep++) + if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; + if (idep == modify->nfix) idep = -1; + + // set maxrad_dynamic and maxrad_frozen for each type + // include future FixPour and FixDeposit particles as dynamic + + int itype; + for (i = 1; i <= atom->ntypes; i++) { + onerad_dynamic[i] = onerad_frozen[i] = 0.0; + if (ipour >= 0) { + itype = i; + onerad_dynamic[i] = + *((double *) modify->fix[ipour]->extract("radius",itype)); + } + if (idep >= 0) { + itype = i; + onerad_dynamic[i] = + *((double *) modify->fix[idep]->extract("radius",itype)); + } + } + + double *radius = atom->radius; + int *mask = atom->mask; + int *type = atom->type; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & freeze_group_bit) + onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]); + else + onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]); + + MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + + // set fix which stores history info + + if (history) { + int ifix = modify->find_fix("NEIGH_HISTORY"); + if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); + fix_history = (FixNeighHistory *) modify->fix[ifix]; + } +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i + ------------------------------------------------------------------------- */ + +double PairGranJKRRollingMulti::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + E[i][j] = mix_stiffnessE(E[i][i],E[j][j],G[i][i],G[j][j]); + G[i][j] = mix_stiffnessG(G[i][i],E[j][j],G[i][i],G[j][j]); + if (normaldamp[i][j] == TSUJI) { + alpha[i][j] = mix_geom(alpha[i][i],alpha[j][j]); + } + else if (normaldamp[i][j] == BRILLIANTOV) { + gamman[i][j] = mix_geom(gamman[i][i],gamman[j][j]); + } + muS[i][j] = mix_geom(muS[i][i],muS[j][j]); + Ecoh[i][j] = mix_geom(Ecoh[i][i],Ecoh[j][j]); + kR[i][j] = mix_geom(kR[i][i],kR[j][j]); + etaR[i][j] = mix_geom(etaR[i][i],etaR[j][j]); + muR[i][j] = mix_geom(muR[i][i],muR[j][j]); + } + + E[j][i] = E[i][j]; + G[j][i] = G[i][j]; + normaldamp[j][i] = normaldamp[i][j]; + alpha[j][i] = alpha[i][j]; + gamman[j][i] = gamman[i][j]; + rollingdamp[j][i] = rollingdamp[i][j]; + muS[j][i] = muS[i][j]; + Ecoh[j][i] = Ecoh[i][j]; + kR[j][i] = kR[i][j]; + etaR[j][i] = etaR[i][j]; + muR[j][i] = muR[i][j]; + + double cutoff = cut[i][j]; + + // It is likely that cut[i][j] at this point is still 0.0. This can happen when + // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates + // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size + // To avoid this issue,for cases involving cut[i][j] = 0.0 (possible only + // if there is no current information about radius/cutoff of type i and j). + // we assign cutoff = min(cut[i][j]) for i,j such that cut[i][j] > 0.0. + + if (cut[i][j] < 0.0) { + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; + } + } + return cutoff; +} + + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::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(&E[i][j],sizeof(double),1,fp); + fwrite(&G[i][j],sizeof(double),1,fp); + fwrite(&normaldamp[i][j],sizeof(int),1,fp); + fwrite(&rollingdamp[i][j],sizeof(int),1,fp); + fwrite(&alpha[i][j],sizeof(double),1,fp); + fwrite(&gamman[i][j],sizeof(double),1,fp); + fwrite(&muS[i][j],sizeof(double),1,fp); + fwrite(&Ecoh[i][j],sizeof(double),1,fp); + fwrite(&kR[i][j],sizeof(double),1,fp); + fwrite(&muR[i][j],sizeof(double),1,fp); + fwrite(&etaR[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::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(&E[i][j],sizeof(double),1,fp); + fread(&G[i][j],sizeof(double),1,fp); + fread(&normaldamp[i][j],sizeof(int),1,fp); + fread(&rollingdamp[i][j],sizeof(int),1,fp); + fread(&alpha[i][j],sizeof(double),1,fp); + fread(&gamman[i][j],sizeof(double),1,fp); + fread(&muS[i][j],sizeof(double),1,fp); + fread(&Ecoh[i][j],sizeof(double),1,fp); + fread(&kR[i][j],sizeof(double),1,fp); + fread(&muR[i][j],sizeof(double),1,fp); + fread(&etaR[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&E[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&G[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&normaldamp[i][j],1,MPI_INT,0,world); + MPI_Bcast(&rollingdamp[i][j],1,MPI_INT,0,world); + MPI_Bcast(&alpha[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gamman[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&muS[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&Ecoh[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&kR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&muR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&etaR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts + ------------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_global,sizeof(double),1,fp); + } + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); +} + +/* ---------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::reset_dt() +{ + dt = update->dt; +} + +/* ---------------------------------------------------------------------- */ + +double PairGranJKRRollingMulti::single(int i, int j, int itype, int jtype, + double rsq, double factor_coul, double factor_lj, double &fforce) +{ +// feenableexcept(FE_INVALID | FE_OVERFLOW); + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double overlap, a; + double mi,mj,meff,damp,kn,kt; + double Fdamp,Fne,Fntot,Fscrit; + double eta_N,eta_T; + double vtr1,vtr2,vtr3,vrel; + double fs1,fs2,fs3,fs; + double shrmag; + double F_C, delta_C, olapsq, olapcubed, sqrtterm, tmp, a0; + double keyterm, keyterm2, keyterm3, aovera0, foverFc; + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/(radi+radj); + a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); + delta_C = 0.5*a0*a0*POW6ONE/R; + + int *touch = fix_history->firstflag[i]; + if ((rsq >= (radsum+delta_C)*(radsum+delta_C) )|| + (rsq >= radsum*radsum && touch[j])){ + fforce = 0.0; + svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + return 0.0; + } + + // relative translational velocity + + double **v = atom->v; + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + + vnnr = vr1*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + + // normal force = JKR + F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + overlap = radsum - r; + olapsq = overlap*overlap; + olapcubed = olapsq*olapsq; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,ONETHIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = POW6TWO * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 + a = aovera0*a0; + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + + Fne = F_C*foverFc; + + //Damping + kn = 4.0/3.0*E[itype][jtype]*a; + if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + Fntot = Fne + Fdamp; + + // relative velocities + + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // shear history effects + // neighprev = index of found neigh on previous call + // search entire jnum list of neighbors of I for neighbor J + // start from neighprev, since will typically be next neighbor + // reset neighprev to 0 as necessary + + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allshear = fix_history->firstvalue[i]; + + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + + double *shear = &allshear[3*neighprev]; + shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + + shear[2]*shear[2]); + + // tangential forces = shear + tangential velocity damping + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; + fs1 = -kt*shear[0] - eta_T*vtr1; + fs2 = -kt*shear[1] - eta_T*vtr2; + fs3 = -kt*shear[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + Fscrit= muS[itype][jtype] * fabs(Fne + 2*F_C); + + if (fs > Fscrit) { + if (shrmag != 0.0) { + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + fs *= Fscrit/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; + } + + // set all forces and return no energy + + fforce = Fntot; + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = vn1; + svector[5] = vn2; + svector[6] = vn3; + svector[7] = vt1; + svector[8] = vt2; + svector[9] = vt3; + return 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int PairGranJKRRollingMulti::pack_forward_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++] = mass_rigid[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranJKRRollingMulti::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + mass_rigid[i] = buf[m++]; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays + ------------------------------------------------------------------------- */ + +double PairGranJKRRollingMulti::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} + +/* ---------------------------------------------------------------------- + mixing of stiffness (E) + ------------------------------------------------------------------------- */ + +double PairGranJKRRollingMulti::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); +} + +/* ---------------------------------------------------------------------- + mixing of stiffness (G) + ------------------------------------------------------------------------- */ + +double PairGranJKRRollingMulti::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); +} + +/* ---------------------------------------------------------------------- + mixing of everything else + ------------------------------------------------------------------------- */ + +double PairGranJKRRollingMulti::mix_geom(double valii, double valjj) +{ + return sqrt(valii*valjj); +} diff --git a/src/GRANULAR/pair_gran_jkr_rolling_multi.h b/src/GRANULAR/pair_gran_jkr_rolling_multi.h new file mode 100644 index 0000000000..c9c75de9a6 --- /dev/null +++ b/src/GRANULAR/pair_gran_jkr_rolling_multi.h @@ -0,0 +1,87 @@ +/* -*- 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(gran/jkr/rolling/multi,PairGranJKRRollingMulti) + +#else + +#ifndef LMP_PAIR_GRAN_JKR_ROLLING_MULTI_H +#define LMP_PAIR_GRAN_JKR_ROLLING_MULTI_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairGranJKRRollingMulti : public Pair { +public: + PairGranJKRRollingMulti(class LAMMPS *); + virtual ~PairGranJKRRollingMulti(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); // Made Virtual by IS Oct 7 2017 + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + void reset_dt(); + virtual double single(int, int, int, int, double, double, double, double &); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + protected: + double cut_global; + double **E,**G,**alpha,**gamman,**muS,**Ecoh,**kR,**muR,**etaR,**cut; + int **normaldamp, **rollingdamp; + double dt; + int freeze_group_bit; + int history; + + int neighprev; + double *onerad_dynamic,*onerad_frozen; + double *maxrad_dynamic,*maxrad_frozen; + + class FixNeighHistory *fix_history; + + // storage of rigid body masses for use in granular interactions + + class Fix *fix_rigid; // ptr to rigid body fix, NULL if none + double *mass_rigid; // rigid mass for owned+ghost atoms + int nmax; // allocated size of mass_rigid + + virtual void allocate(); // Made Virtual by IS Oct 7 2017 + +private: + double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); + double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); + double mix_geom(double valii, double valjj); +}; + +} + +#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. + + */ diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp new file mode 100644 index 0000000000..9b693c74b5 --- /dev/null +++ b/src/GRANULAR/pair_granular.cpp @@ -0,0 +1,1187 @@ +/* ---------------------------------------------------------------------- +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: Leo Silbert (SNL), Gary Grest (SNL), + Jeremy Lechman (SNL), Dan Bolintineanu (SNL), Ishan Srivastava (SNL) +----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_granular.h" +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define ONETHIRD 0.33333333333333333 +#define TWOTHIRDS 0.66666666666666666 +#define POW6ONE 0.550321208149104 //6^(-1/3) +#define POW6TWO 0.30285343213869 //6^(-2/3) + +#define EPSILON 1e-10 + +enum {TSUJI, BRILLIANTOV}; +enum {INDEP, BRILLROLL}; + +/* ---------------------------------------------------------------------- */ + +PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 1; + no_virial_fdotr_compute = 1; + history = 1; + fix_history = NULL; + + single_extra = 10; + svector = new double[10]; + + neighprev = 0; + + nmax = 0; + mass_rigid = NULL; + + onerad_dynamic = NULL; + onerad_frozen = NULL; + maxrad_dynamic = NULL; + maxrad_frozen = NULL; + + dt = update->dt; + + // set comm size needed by this Pair if used with fix rigid + + comm_forward = 1; +} + +/* ---------------------------------------------------------------------- */ +PairGranular::~PairGranular() +{ + delete [] svector; + if (fix_history) modify->delete_fix("NEIGH_HISTORY"); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(E); + memory->destroy(G); + memory->destroy(normaldamp); + memory->destroy(rollingdamp); + memory->destroy(alpha); + memory->destroy(gamman); + memory->destroy(muS); + memory->destroy(Ecoh); + memory->destroy(kR); + memory->destroy(muR); + memory->destroy(etaR); + + delete [] onerad_dynamic; + delete [] onerad_frozen; + delete [] maxrad_dynamic; + delete [] maxrad_frozen; + } + memory->destroy(mass_rigid); +} +/* ---------------------------------------------------------------------- */ + +void PairGranular::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + double Fne, Fdamp, Fntot, Fscrit, Frcrit, F_C, delta_C, delta_Cinv; + double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; + double keyterm, keyterm2, keyterm3, aovera0, foverFc; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + double signtwist, magtwist, magtortwist, Mtcrit; + double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; + double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *history,*allhistory,**firsthistory; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int historyupdate = 1; + if (update->setupflag) historyupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + 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 newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firsthistory = fix_history->firstvalue; + + // 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]; + radi = radius[i]; + touch = firsttouch[i]; + allhistory = firsthistory[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]; + jtype = type[j]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + R = radi*radj/(radi+radj); + a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); + delta_C = 0.5*a0*a0*POW6ONE/R; + + if ((rsq >= radsum*radsum && touch[jj] == 0) || + (rsq >= (radsum+delta_C)*(radsum+delta_C))) { + + // unset non-touching neighbors + + touch[jj] = 0; + history = &allhistory[3*jj]; + history[0] = 0.0; + history[1] = 0.0; + history[2] = 0.0; + + } else { + F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + //**************************************** + //Normal force = JKR-adjusted Hertzian contact + damping + //**************************************** + if (Ecoh[itype][jtype] != 0.0) delta_Cinv = 1.0/delta_C; + else delta_Cinv = 1.0; + overlap = (radsum - r)*delta_Cinv; + olapsq = overlap*overlap; + olapcubed = olapsq*overlap; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,ONETHIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = POW6TWO * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 + a = aovera0*a0; + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + + Fne = F_C*foverFc; + + //Damping + kn = 4.0/3.0*E[itype][jtype]*a; + if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + Fntot = Fne + Fdamp; + //if (screen) fprintf(screen,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); + //if (logfile) fprintf(logfile,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); + + //**************************************** + //Tangential force, including history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + // Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting + // delta/2, i.e. instead of radi, use distance to center of contact point? + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // history effects + touch[jj] = 1; + history = &allhistory[3*jj]; + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // Rotate and update displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (historyupdate) { + rsht = history[0]*nx + history[1]*ny + history[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + history[0] -= rsht*nx; + history[1] -= rsht*ny; + history[2] -= rsht*nz; + //Also rescale to preserve magnitude + history[0] *= scalefac; + history[1] *= scalefac; + history[2] *= scalefac; + } + //Update history + history[0] += vtr1*dt; + history[1] += vtr2*dt; + history[2] += vtr3*dt; + } + + // tangential forces = history + tangential velocity damping + // following Zhao and Marshall Phys Fluids v20, p043302 (2008) + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter + fs1 = -kt*history[0] - eta_T*vtr1; //eq 26 + fs2 = -kt*history[1] - eta_T*vtr2; + fs3 = -kt*history[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = muS[itype][jtype] * fabs(Fne + 2*F_C); + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + //history[0] = (Fcrit/fs) * (history[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //history[1] = (Fcrit/fs) * (history[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + //history[2] = (Fcrit/fs) * (history[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; + history[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) + history[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); + history[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + + //**************************************** + // Rolling force, including history history effects + //**************************************** + + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + // Rolling displacement + rollmag = sqrt(history[3]*history[3] + history[4]*history[4] + history[5]*history[5]); + rolldotn = history[3]*nx + history[4]*ny + history[5]*nz; + + if (historyupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + history[3] -= rolldotn*nx; + history[4] -= rolldotn*ny; + history[5] -= rolldotn*nz; + //Also rescale to preserve magnitude + history[3] *= scalefac; + history[4] *= scalefac; + history[5] *= scalefac; + } + history[3] += vrl1*dt; + history[4] += vrl2*dt; + history[5] += vrl3*dt; + } + + k_R = kR[itype][jtype]*4.0*F_C*pow(aovera0,1.5); + if (rollingdamp[itype][jtype] == INDEP) eta_R = etaR[itype][jtype]; + else if (rollingdamp[itype][jtype] == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); + fr1 = -k_R*history[3] - eta_R*vrl1; + fr2 = -k_R*history[4] - eta_R*vrl2; + fr3 = -k_R*history[5] - eta_R*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = muR[itype][jtype] * fabs(Fne + 2*F_C); + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + history[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + history[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + + + //**************************************** + // Twisting torque, including history effects + //**************************************** + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + history[6] += magtwist*dt; + k_Q = 0.5*kt*a*a;; //eq 32 + eta_Q = 0.5*eta_T*a*a; + magtortwist = -k_Q*history[6] - eta_Q*magtwist;//M_t torque (eq 30) + + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + //history[6] = Mtcrit/k_Q*magtwist/fabs(magtwist); + history[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + //if (screen) fprintf(screen,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); + //if (logfile) fprintf(logfile,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + + if (force->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; + + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + + +/* ---------------------------------------------------------------------- +allocate all arrays +------------------------------------------------------------------------- */ + +void PairGranular::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(E,n+1,n+1,"pair:E"); + memory->create(G,n+1,n+1,"pair:G"); + memory->create(normaldamp,n+1,n+1,"pair:normaldamp"); + memory->create(rollingdamp,n+1,n+1,"pair:rollingdamp"); + memory->create(alpha,n+1,n+1,"pair:alpha"); + memory->create(gamman,n+1,n+1,"pair:gamman"); + memory->create(muS,n+1,n+1,"pair:muS"); + memory->create(Ecoh,n+1,n+1,"pair:Ecoh"); + memory->create(kR,n+1,n+1,"pair:kR"); + memory->create(muR,n+1,n+1,"pair:muR"); + memory->create(etaR,n+1,n+1,"pair:etaR"); + + onerad_dynamic = new double[n+1]; + onerad_frozen = new double[n+1]; + maxrad_dynamic = new double[n+1]; + maxrad_frozen = new double[n+1]; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairGranular::settings(int narg, char **arg) +{ + if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + + if (strcmp(arg[0],"NULL") == 0 ) cut_global = -1.0; + else cut_global = force->numeric(FLERR,arg[0]); + + // reset cutoffs that have been explicitly set + if (allocated) { + int i,j; + for (i = 1; i <= atom->ntypes; i++) + for (j = i; j <= atom->ntypes; j++) + if (setflag[i][j]) cut[i][j] = cut_global; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairGranular::coeff(int narg, char **arg) +{ + if (narg < 10 || narg > 15) + error->all(FLERR,"Incorrect args for pair coefficients2"); + + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + double E_one = force->numeric(FLERR,arg[2]); + double G_one = force->numeric(FLERR,arg[3]); + double muS_one = force->numeric(FLERR,arg[4]); + double cor_one = force->numeric(FLERR,arg[5]); + double Ecoh_one = force->numeric(FLERR,arg[6]); + double kR_one = force->numeric(FLERR,arg[7]); + double muR_one = force->numeric(FLERR,arg[8]); + double etaR_one = force->numeric(FLERR,arg[9]); + + //Defaults + int normaldamp_one = TSUJI; + int rollingdamp_one = INDEP; + double cut_one = cut_global; + + int iarg = 10; + while (iarg < narg) { + if (strcmp(arg[iarg],"normaldamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp_one = TSUJI; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp_one = BRILLIANTOV; + else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); + iarg += 2; + } + else if (strcmp(arg[iarg],"rollingdamp") == 0){ + if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); + if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp_one = INDEP; + else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp_one = BRILLROLL; + else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); + iarg +=2; + } + else { + if (strcmp(arg[iarg],"NULL") == 0) cut_one = -1.0; + else cut_one = force->numeric(FLERR,arg[iarg]); + iarg += 1; + } + } + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + double pois = E_one/(2.0*G_one) - 1.0; + double alpha_one = 1.2728-4.2783*cor_one+11.087*cor_one*cor_one-22.348*cor_one*cor_one*cor_one+27.467*cor_one*cor_one*cor_one*cor_one-18.022*cor_one*cor_one*cor_one*cor_one*cor_one+4.8218*cor_one*cor_one*cor_one*cor_one*cor_one*cor_one; + + for (int j = MAX(jlo,i); j <= jhi; j++) { + E[i][j] = E_one; + G[i][j] = G_one; + if (normaldamp_one == TSUJI) { + normaldamp[i][j] = TSUJI; + alpha[i][j] = alpha_one; + } + else if (normaldamp_one == BRILLIANTOV) { + normaldamp[i][j] = BRILLIANTOV; + gamman[i][j] = cor_one; + } + if (rollingdamp_one == INDEP) { + rollingdamp[i][j] = INDEP; + } + else if (rollingdamp_one == BRILLROLL) { + rollingdamp[i][j] = BRILLROLL; + } + muS[i][j] = muS_one; + Ecoh[i][j] = Ecoh_one; + kR[i][j] = kR_one; + etaR[i][j] = etaR_one; + muR[i][j] = muR_one; + cut[i][j] = cut_one; + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients1"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairGranular::init_style() +{ + int i; + + // error and warning checks + + if (!atom->radius_flag || !atom->rmass_flag) + error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); + + // need a granular neigh list + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->size = 1; + if (history) neighbor->requests[irequest]->history = 1; + + dt = update->dt; + + // if history is stored: + // if first init, create Fix needed for storing history + + if (history && fix_history == NULL) { + char dnumstr[16]; + sprintf(dnumstr,"%d",size_history); + char **fixarg = new char*[4]; + fixarg[0] = (char *) "NEIGH_HISTORY"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "NEIGH_HISTORY"; + fixarg[3] = dnumstr; + modify->add_fix(4,fixarg,1); + delete [] fixarg; + fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; + fix_history->pair = this; + } + + // check for FixFreeze and set freeze_group_bit + + for (i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"freeze") == 0) break; + if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; + else freeze_group_bit = 0; + + // check for FixRigid so can extract rigid body masses + + fix_rigid = NULL; + for (i = 0; i < modify->nfix; i++) + if (modify->fix[i]->rigid_flag) break; + if (i < modify->nfix) fix_rigid = modify->fix[i]; + + // check for FixPour and FixDeposit so can extract particle radii + + int ipour; + for (ipour = 0; ipour < modify->nfix; ipour++) + if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; + if (ipour == modify->nfix) ipour = -1; + + int idep; + for (idep = 0; idep < modify->nfix; idep++) + if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; + if (idep == modify->nfix) idep = -1; + + // set maxrad_dynamic and maxrad_frozen for each type + // include future FixPour and FixDeposit particles as dynamic + + int itype; + for (i = 1; i <= atom->ntypes; i++) { + onerad_dynamic[i] = onerad_frozen[i] = 0.0; + if (ipour >= 0) { + itype = i; + onerad_dynamic[i] = + *((double *) modify->fix[ipour]->extract("radius",itype)); + } + if (idep >= 0) { + itype = i; + onerad_dynamic[i] = + *((double *) modify->fix[idep]->extract("radius",itype)); + } + } + + double *radius = atom->radius; + int *mask = atom->mask; + int *type = atom->type; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++) + if (mask[i] & freeze_group_bit) + onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]); + else + onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]); + + MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + + // set fix which stores history info + + if (history) { + int ifix = modify->find_fix("NEIGH_HISTORY"); + if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); + fix_history = (FixNeighHistory *) modify->fix[ifix]; + } +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairGranular::init_one(int i, int j) +{ + if (setflag[i][j] == 0) { + E[i][j] = mix_stiffnessE(E[i][i],E[j][j],G[i][i],G[j][j]); + G[i][j] = mix_stiffnessG(G[i][i],E[j][j],G[i][i],G[j][j]); + if (normaldamp[i][j] == TSUJI) { + alpha[i][j] = mix_geom(alpha[i][i],alpha[j][j]); + } + else if (normaldamp[i][j] == BRILLIANTOV) { + gamman[i][j] = mix_geom(gamman[i][i],gamman[j][j]); + } + muS[i][j] = mix_geom(muS[i][i],muS[j][j]); + Ecoh[i][j] = mix_geom(Ecoh[i][i],Ecoh[j][j]); + kR[i][j] = mix_geom(kR[i][i],kR[j][j]); + etaR[i][j] = mix_geom(etaR[i][i],etaR[j][j]); + muR[i][j] = mix_geom(muR[i][i],muR[j][j]); + } + + E[j][i] = E[i][j]; + G[j][i] = G[i][j]; + normaldamp[j][i] = normaldamp[i][j]; + alpha[j][i] = alpha[i][j]; + gamman[j][i] = gamman[i][j]; + rollingdamp[j][i] = rollingdamp[i][j]; + muS[j][i] = muS[i][j]; + Ecoh[j][i] = Ecoh[i][j]; + kR[j][i] = kR[i][j]; + etaR[j][i] = etaR[i][j]; + muR[j][i] = muR[i][j]; + + double cutoff = cut[i][j]; + + // It is likely that cut[i][j] at this point is still 0.0. This can happen when + // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates + // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size + // To avoid this issue,for cases involving cut[i][j] = 0.0 (possible only + // if there is no current information about radius/cutoff of type i and j). + // we assign cutoff = min(cut[i][j]) for i,j such that cut[i][j] > 0.0. + + if (cut[i][j] < 0.0) { + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; + } + } + return cutoff; +} + + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file + ------------------------------------------------------------------------- */ + +void PairGranular::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(&E[i][j],sizeof(double),1,fp); + fwrite(&G[i][j],sizeof(double),1,fp); + fwrite(&normaldamp[i][j],sizeof(int),1,fp); + fwrite(&rollingdamp[i][j],sizeof(int),1,fp); + fwrite(&alpha[i][j],sizeof(double),1,fp); + fwrite(&gamman[i][j],sizeof(double),1,fp); + fwrite(&muS[i][j],sizeof(double),1,fp); + fwrite(&Ecoh[i][j],sizeof(double),1,fp); + fwrite(&kR[i][j],sizeof(double),1,fp); + fwrite(&muR[i][j],sizeof(double),1,fp); + fwrite(&etaR[i][j],sizeof(double),1,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts + ------------------------------------------------------------------------- */ + +void PairGranular::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(&E[i][j],sizeof(double),1,fp); + fread(&G[i][j],sizeof(double),1,fp); + fread(&normaldamp[i][j],sizeof(int),1,fp); + fread(&rollingdamp[i][j],sizeof(int),1,fp); + fread(&alpha[i][j],sizeof(double),1,fp); + fread(&gamman[i][j],sizeof(double),1,fp); + fread(&muS[i][j],sizeof(double),1,fp); + fread(&Ecoh[i][j],sizeof(double),1,fp); + fread(&kR[i][j],sizeof(double),1,fp); + fread(&muR[i][j],sizeof(double),1,fp); + fread(&etaR[i][j],sizeof(double),1,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&E[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&G[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&normaldamp[i][j],1,MPI_INT,0,world); + MPI_Bcast(&rollingdamp[i][j],1,MPI_INT,0,world); + MPI_Bcast(&alpha[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&gamman[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&muS[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&Ecoh[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&kR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&muR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&etaR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file + ------------------------------------------------------------------------- */ + +void PairGranular::write_restart_settings(FILE *fp) +{ + fwrite(&cut_global,sizeof(double),1,fp); +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts + ------------------------------------------------------------------------- */ + +void PairGranular::read_restart_settings(FILE *fp) +{ + if (comm->me == 0) { + fread(&cut_global,sizeof(double),1,fp); + } + MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); +} + +/* ---------------------------------------------------------------------- */ + +void PairGranular::reset_dt() +{ + dt = update->dt; +} + +/* ---------------------------------------------------------------------- */ + +double PairGranular::single(int i, int j, int itype, int jtype, + double rsq, double factor_coul, double factor_lj, double &fforce) +{ + // feenableexcept(FE_INVALID | FE_OVERFLOW); + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double overlap, a; + double mi,mj,meff,damp,kn,kt; + double Fdamp,Fne,Fntot,Fscrit; + double eta_N,eta_T; + double vtr1,vtr2,vtr3,vrel; + double fs1,fs2,fs3,fs; + double shrmag; + double F_C, delta_C, olapsq, olapcubed, sqrtterm, tmp, a0; + double keyterm, keyterm2, keyterm3, aovera0, foverFc; + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + + r = sqrt(rsq); + rinv = 1.0/r; + rsqinv = 1.0/rsq; + R = radi*radj/(radi+radj); + a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); + delta_C = 0.5*a0*a0*POW6ONE/R; + + int *touch = fix_history->firstflag[i]; + if ((rsq >= (radsum+delta_C)*(radsum+delta_C) )|| + (rsq >= radsum*radsum && touch[j])){ + fforce = 0.0; + svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + return 0.0; + } + + // relative translational velocity + + double **v = atom->v; + vr1 = v[i][0] - v[j][0]; + vr2 = v[i][1] - v[j][1]; + vr3 = v[i][2] - v[j][2]; + + // normal component + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + + vnnr = vr1*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + double *rmass = atom->rmass; + int *type = atom->type; + int *mask = atom->mask; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + + // normal force = JKR + F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + overlap = radsum - r; + olapsq = overlap*overlap; + olapcubed = olapsq*olapsq; + sqrtterm = sqrt(1.0 + olapcubed); + tmp = 2.0 + olapcubed + 2.0*sqrtterm; + keyterm = pow(tmp,ONETHIRD); + keyterm2 = olapsq/keyterm; + keyterm3 = sqrt(overlap + keyterm2 + keyterm); + aovera0 = POW6TWO * (keyterm3 + + sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 + a = aovera0*a0; + foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + + Fne = F_C*foverFc; + + //Damping + kn = 4.0/3.0*E[itype][jtype]*a; + if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; + else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + + Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + + Fntot = Fne + Fdamp; + + // relative velocities + + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // history effects + // neighprev = index of found neigh on previous call + // search entire jnum list of neighbors of I for neighbor J + // start from neighprev, since will typically be next neighbor + // reset neighprev to 0 as necessary + + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allhistory = fix_history->firstvalue[i]; + + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + + double *history = &allhistory[3*neighprev]; + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // tangential forces = history + tangential velocity damping + kt=8.0*G[itype][jtype]*a; + + eta_T = eta_N; + fs1 = -kt*history[0] - eta_T*vtr1; + fs2 = -kt*history[1] - eta_T*vtr2; + fs3 = -kt*history[2] - eta_T*vtr3; + + // rescale frictional displacements and forces if needed + + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + Fscrit= muS[itype][jtype] * fabs(Fne + 2*F_C); + + if (fs > Fscrit) { + if (shrmag != 0.0) { + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + fs *= Fscrit/fs; + } else fs1 = fs2 = fs3 = fs = 0.0; + } + + // set all forces and return no energy + + fforce = Fntot; + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = vn1; + svector[5] = vn2; + svector[6] = vn3; + svector[7] = vt1; + svector[8] = vt2; + svector[9] = vt3; + return 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int PairGranular::pack_forward_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++] = mass_rigid[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranular::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + mass_rigid[i] = buf[m++]; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays + ------------------------------------------------------------------------- */ + +double PairGranular::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} + +/* ---------------------------------------------------------------------- + mixing of stiffness (E) +------------------------------------------------------------------------- */ + +double PairGranular::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); +} + +/* ---------------------------------------------------------------------- + mixing of stiffness (G) + ------------------------------------------------------------------------- */ + +double PairGranular::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); +} + +/* ---------------------------------------------------------------------- + mixing of everything else + ------------------------------------------------------------------------- */ + +double PairGranular::mix_geom(double valii, double valjj) +{ + return sqrt(valii*valjj); +} diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h new file mode 100644 index 0000000000..9fbc9acd51 --- /dev/null +++ b/src/GRANULAR/pair_granular.h @@ -0,0 +1,89 @@ +/* ---------------------------------------------------------- + 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(granular,PairGranular) + +#else + +#ifndef LMP_PAIR_GRANULAR_H +#define LMP_PAIR_GRANULAR_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairGranular : public Pair { +public: + PairGranular(class LAMMPS *); + virtual ~PairGranular(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + void reset_dt(); + virtual double single(int, int, int, int, double, double, double, double &); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + protected: + double cut_global; + double dt; + int freeze_group_bit; + int history; + + int neighprev; + double *onerad_dynamic,*onerad_frozen; + double *maxrad_dynamic,*maxrad_frozen; + + class FixNeighHistory *fix_history; + + // storage of rigid body masses for use in granular interactions + + class Fix *fix_rigid; // ptr to rigid body fix, NULL if none + double *mass_rigid; // rigid mass for owned+ghost atoms + int nmax; // allocated size of mass_rigid + + virtual void allocate(); + + private: + int size_history; + int num_coeffs; + double ***coeffs; + + double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); + double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); + double mix_geom(double valii, double valjj); +}; + +} + +#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. + + */ -- GitLab From fd8130859b9dc840af8d4b459c7de3d055be5c60 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 19 Dec 2018 17:40:35 -0700 Subject: [PATCH 0076/1243] fix a small memory leak in SHAKE setup --- src/RIGID/fix_shake.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 66c92d42c5..51121f0853 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -955,7 +955,7 @@ void FixShake::find_clusters() // ----------------------------------------------------- // set shake_flag,shake_atom,shake_type for non-central atoms - // requires communication for off-proc atoms + // requires rendezvous communication for off-proc atoms // ----------------------------------------------------- shake_info(npartner,partner_tag,partner_shake); @@ -964,6 +964,9 @@ void FixShake::find_clusters() // free local memory // ----------------------------------------------------- + memory->destroy(atomIDs); + memory->destroy(procowner); + memory->destroy(npartner); memory->destroy(nshake); memory->destroy(partner_tag); @@ -1390,24 +1393,24 @@ int FixShake::rendezvous_ids(int n, char *inbuf, FixShake *fsptr = (FixShake *) ptr; Memory *memory = fsptr->memory; - int *procowner; tagint *atomIDs; + int *procowner; - memory->create(procowner,n,"special:procowner"); memory->create(atomIDs,n,"special:atomIDs"); + memory->create(procowner,n,"special:procowner"); IDRvous *in = (IDRvous *) inbuf; for (int i = 0; i < n; i++) { - procowner[i] = in[i].me; atomIDs[i] = in[i].atomID; + procowner[i] = in[i].me; } // store rendezvous data in FixShake class fsptr->nrvous = n; - fsptr->procowner = procowner; fsptr->atomIDs = atomIDs; + fsptr->procowner = procowner; // flag = 0: no 2nd irregular comm needed in comm->rendezvous -- GitLab From 7861de03a21da687d813f5f34eaf92dc27787def Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Thu, 20 Dec 2018 16:59:21 -0700 Subject: [PATCH 0077/1243] Progress on general granular pair style --- src/GRANULAR/pair_granular.cpp | 645 ++++++++++++++++++++++++++------- src/GRANULAR/pair_granular.h | 44 ++- 2 files changed, 565 insertions(+), 124 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 9b693c74b5..73fcb19a8c 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -46,8 +46,12 @@ using namespace MathConst; #define EPSILON 1e-10 -enum {TSUJI, BRILLIANTOV}; -enum {INDEP, BRILLROLL}; +enum {STIFFNESS, MATERIAL}; +enum {VELOCITY, VISCOELASTIC, TSUJI}; +enum {HOOKE, HERTZ, DMT, JKR}; +enum {TANGENTIAL_MINDLIN, TANGENTIAL_NOHISTORY}; +enum {NONE, TWISTING_NOHISTORY, TWISTING_SDS, TWISTING_MARSHALL}; +enum {NONE, ROLLING_NOHISTORY, ROLLING_SDS}; /* ---------------------------------------------------------------------- */ @@ -55,7 +59,7 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) { single_enable = 1; no_virial_fdotr_compute = 1; - history = 1; + use_history = 1; fix_history = NULL; single_extra = 10; @@ -76,6 +80,10 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) // set comm size needed by this Pair if used with fix rigid comm_forward = 1; + + beyond_contact = 0; + rolling_history_index = twisting_history_index = 0; + tangential_history_index = -1; } /* ---------------------------------------------------------------------- */ @@ -108,9 +116,194 @@ PairGranular::~PairGranular() } memory->destroy(mass_rigid); } -/* ---------------------------------------------------------------------- */ -void PairGranular::compute(int eflag, int vflag) +void PairGranular::compute(int eflag, int vflag){ + /* +#ifdef TEMPLATED_PAIR_GRANULAR + if (normal == 0){ + if (damping == 0){ + if (tangential == 0){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,0,0,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,0,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,0,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,0,0,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,0,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,0,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,0,0,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,0,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,0,2,2>(eflag, vflag); + } + } + else if (tangential == 1){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,0,1,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,1,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,1,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,0,1,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,1,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,1,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,0,1,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,1,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,1,2,2>(eflag, vflag); + } + } + else if (tangential == 2){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,0,2,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,2,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,2,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,0,2,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,2,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,2,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,0,2,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,0,2,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,0,2,2,2>(eflag, vflag); + } + } + } + else if (damping == 1){ + if (tangential == 0){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,1,0,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,0,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,0,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,1,0,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,0,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,0,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,1,0,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,0,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,0,2,2>(eflag, vflag); + } + } + else if (tangential == 1){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,1,1,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,1,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,1,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,1,1,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,1,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,1,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,1,1,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,1,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,1,2,2>(eflag, vflag); + } + } + else if (tangential == 2){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,1,2,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,2,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,2,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,1,2,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,2,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,2,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,1,2,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,1,2,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,1,2,2,2>(eflag, vflag); + } + } + } + else if (damping == 2){ + if (tangential == 0){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,2,0,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,0,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,0,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,2,0,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,0,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,0,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,2,0,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,0,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,0,2,2>(eflag, vflag); + } + } + else if (tangential == 1){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,2,1,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,1,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,1,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,2,1,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,1,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,1,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,2,1,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,1,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,1,2,2>(eflag, vflag); + } + } + else if (tangential == 2){ + if (rolling == 0){ + if (twisting == 0) compute_templated<0,0,2,2,0,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,2,0,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,2,0,2>(eflag, vflag); + } + else if (rolling == 1){ + if (twisting == 0) compute_templated<0,0,2,2,1,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,2,1,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,2,1,2>(eflag, vflag); + } + else if (rolling == 2){ + if (twisting == 0) compute_templated<0,0,2,2,2,0>(eflag, vflag); + else if (twisting == 1) compute_templated<0,0,2,2,2,1>(eflag, vflag); + else if (twisting == 2) compute_templated<0,0,2,2,2,2>(eflag, vflag); + } + } + } + } + + + } +#else +#endif +*/ + compute_untemplated(Tp_coeff_types, Tp_normal, Tp_damping, Tp_tangential, + Tp_rolling, Tp_twisting, eflag, vflag); +} +/* ---------------------------------------------------------------------- */ +/*#ifdef TEMPLATED_PAIR_GRANULAR +template < int Tp_coeff_types, + int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_rolling, int Tp_twisting > +void PairGranular::compute_templated(int eflag, int vflag) +#else +*/ +void PairGranular::compute_untemplated + (int Tp_coeff_types, + int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_rolling, int Tp_twisting, + int eflag, int vflag) +//#endif { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; @@ -119,9 +312,13 @@ void PairGranular::compute(int eflag, int vflag) double wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; - double Fne, Fdamp, Fntot, Fscrit, Frcrit, F_C, delta_C, delta_Cinv; + double Fne, Fdamp, Fntot, Fscrit, Frcrit; + + //For JKR + double R, R2, coh, delta_pulloff, dist_pulloff, a, E; double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; double keyterm, keyterm2, keyterm3, aovera0, foverFc; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; double rollmag, rolldotn, scalefac; @@ -134,6 +331,8 @@ void PairGranular::compute(int eflag, int vflag) int *touch,**firsttouch; double *history,*allhistory,**firsthistory; + bool untouchflag; + if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -179,10 +378,18 @@ void PairGranular::compute(int eflag, int vflag) firsttouch = fix_history->firstflag; firsthistory = fix_history->firstvalue; - // loop over neighbors of my atoms + double coh; + double **cohesion; + double **stiffness; + double **damping; + if (Tp_normal == JKR){ + cohesion = coeffs[normal_coeff_inds[4]]; + } + for (ii = 0; ii < inum; ii++) { i = ilist[ii]; + itype = type[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; @@ -193,7 +400,7 @@ void PairGranular::compute(int eflag, int vflag) jlist = firstneigh[i]; jnum = numneigh[i]; - for (jj = 0; jj < jnum; jj++) { + for (jj = 0; jj < jnum; jj++){ j = jlist[jj]; j &= NEIGHMASK; @@ -204,23 +411,25 @@ void PairGranular::compute(int eflag, int vflag) rsq = delx*delx + dely*dely + delz*delz; radj = radius[j]; radsum = radi + radj; - R = radi*radj/(radi+radj); - a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); - delta_C = 0.5*a0*a0*POW6ONE/R; - - if ((rsq >= radsum*radsum && touch[jj] == 0) || - (rsq >= (radsum+delta_C)*(radsum+delta_C))) { + untouchflag = (rsq >= radsum*radsum); + + if (normal[itype][jtype] == JKR){ + R = radi*radj/(radi+radj); + R2 = R*R; + coh = cohesion[itype][jtype]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/R - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum+delta_pulloff; + untouchflag = (rsq >= (dist_pulloff)*(dist_pulloff)); + } + if (untouchflag){ // unset non-touching neighbors - touch[jj] = 0; - history = &allhistory[3*jj]; - history[0] = 0.0; - history[1] = 0.0; - history[2] = 0.0; - - } else { - F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; + history = &allhistory[size_history*jj]; + for (int k = 0; k < size_history; k++) history[k] = 0.0; + } + else{ r = sqrt(rsq); rinv = 1.0/r; rsqinv = 1.0/rsq; @@ -260,23 +469,9 @@ void PairGranular::compute(int eflag, int vflag) //**************************************** //Normal force = JKR-adjusted Hertzian contact + damping //**************************************** - if (Ecoh[itype][jtype] != 0.0) delta_Cinv = 1.0/delta_C; - else delta_Cinv = 1.0; - overlap = (radsum - r)*delta_Cinv; - olapsq = overlap*overlap; - olapcubed = olapsq*overlap; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,ONETHIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = POW6TWO * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 - a = aovera0*a0; - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) - - Fne = F_C*foverFc; + if (normal[itype][jtype] == JKR){ + } //Damping kn = 4.0/3.0*E[itype][jtype]*a; if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; @@ -522,18 +717,15 @@ void PairGranular::allocate() setflag[i][j] = 0; memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(cut,n+1,n+1,"pair:cut"); - memory->create(E,n+1,n+1,"pair:E"); - memory->create(G,n+1,n+1,"pair:G"); - memory->create(normaldamp,n+1,n+1,"pair:normaldamp"); - memory->create(rollingdamp,n+1,n+1,"pair:rollingdamp"); - memory->create(alpha,n+1,n+1,"pair:alpha"); - memory->create(gamman,n+1,n+1,"pair:gamman"); - memory->create(muS,n+1,n+1,"pair:muS"); - memory->create(Ecoh,n+1,n+1,"pair:Ecoh"); - memory->create(kR,n+1,n+1,"pair:kR"); - memory->create(muR,n+1,n+1,"pair:muR"); - memory->create(etaR,n+1,n+1,"pair:etaR"); + memory->create(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); + memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); + memory->create(rolling_coeffs,n+1,n+1,3,"pair:rolling_coeffs"); + memory->create(twisting_coeffs,n+1,n+1,3,"pair:twisting_coeffs"); + + memory->create(normal,n+1,n+1,"pair:normal"); + memory->create(tangential,n+1,n+1,"pair:tangential"); + memory->create(rolling,n+1,n+1,"pair:rolling"); + memory->create(twisting,n+1,n+1,"pair:twisting"); onerad_dynamic = new double[n+1]; onerad_frozen = new double[n+1]; @@ -547,17 +739,135 @@ void PairGranular::allocate() void PairGranular::settings(int narg, char **arg) { - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); + if (narg < 5) error->all(FLERR,"Illegal pair_style command"); - if (strcmp(arg[0],"NULL") == 0 ) cut_global = -1.0; - else cut_global = force->numeric(FLERR,arg[0]); + int iarg = 0; - // reset cutoffs that have been explicitly set - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; + //Some defaults + damping_global = VISCOELASTIC; + coeff_types = STIFFNESS; + tangential_global = -1; //Needs to be explicitly set, since it requires parameters + rolling_global = NONE; + twisting_global = NONE; + tangential_history = rolling_history = twisting_history = 0; + + if (strcmp(arg[iarg], "material") == 0){ + coeff_types = MATERIAL; + iarg += 1; + } + while (iarg < narg){ + if (strcmp(arg[iarg], "hooke") == 0){ + if (coeff_types == MATERIAL) error->all(FLERR,"Illegal pair_coeff command, 'stiffness' coefficients required for Hooke"); + if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); + normal_global = HOOKE; + memory->create(normal_coeffs_one, 2, "pair:normal_coeffs_one"); + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += 3; + } + else if (strcmp(arg[iarg], "hertz") == 0){ + int num_coeffs = 2; + if (coeff_types == MATERIAL) num_coeffs += 1; + if (iarg + offset >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + normal_global = HERTZ; + memory->create(normal_coeffs_one, num_coeffs, "pair:normal_coeffs_one"); + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + if (coeff_types == MATERIAL) normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "dmt") == 0){ + if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_style command, 'material' coefficients required for DMT"); + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + normal_global = DMT; + memory->create(normal_coeffs_one, 4, "pair:normal_coeffs_one"); + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "jkr") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for JKR option"); + if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_style command, 'material' coefficients required for JKR"); + beyond_contact = 1; + normal_global = JKR; + memory->create(normal_coeffs_one, 4, "pair:normal_coeffs_one"); + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "damp_velocity") == 0){ + damping_global = VELOCITY; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ + damping_global = VISCOELASTIC; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_tsuji") == 0){ + damping_global = TSUJI; + iarg += 1; + } + else if (strstr(arg[iarg], "tangential") != NULL){ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); + if (strstr(arg[iarg], "nohistory") != NULL){ + tangential_global = TANGENTIAL_NOHISTORY; + } + else{ + tangential_global = TANGENTIAL_MINDLIN; + tangential_history = 1; + } + memory->create(tangential_coeffs_one, 3, "pair:tangential_coeffs_one"); + tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kt + tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + else if (strstr(arg[iarg], "rolling") != NULL){ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); + if (strstr(arg[iarg], "nohistory") != NULL){ + rolling_global = ROLLING_NOHISTORY; + } + else{ + rolling_global = ROLLING_SDS; + rolling_history = 1; + } + memory->create(rolling_coeffs_one, 3, "pair:rolling_coeffs_one"); + rolling_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kt + rolling_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + rolling_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + else if (strstr(arg[iarg], "twisting") != NULL){ + if (strstr(arg[iarg], "marshall") != NULL){ + twisting_global = TWISTING_MARSHALL; + twisting_history = 1; + memory->create(twisting_coeffs_one, 3, "pair:twisting_coeffs_one"); //To be filled later + } + else{ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twisting model"); + if (strstr(arg[iarg], "nohistory") != NULL){ + twisting_global = TWISTING_NOHISTORY; + } + else{ + twisting_global = TWISTING_SDS; + twisting_history = 1; + } + memory->create(twisting_coeffs_one, 3, "pair:twisting_coeffs_one"); + twisting_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kt + twisting_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + twisting_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + } + } + + //Additional checks + if (tangential_global == -1){ + error->all(FLERR, "Illegal pair_style command: must specify tangential model"); } } @@ -567,8 +877,19 @@ void PairGranular::settings(int narg, char **arg) void PairGranular::coeff(int narg, char **arg) { - if (narg < 10 || narg > 15) - error->all(FLERR,"Incorrect args for pair coefficients2"); + int normal_local, damping_local, tangential_local, rolling_local, twisting_local; + double *normal_coeffs_local; + double *tangential_coeffs_local; + double *rolling_coeffs_local; + double *twisting_coeffs_local; + + normal_coeffs_local = new double[4]; + tangential_coeffs_local = new double[4]; + rolling_coeffs_local = new double[4]; + twisting_coeffs_local = new double[4]; + + if (narg < 2) + error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); @@ -576,77 +897,149 @@ void PairGranular::coeff(int narg, char **arg) force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - double E_one = force->numeric(FLERR,arg[2]); - double G_one = force->numeric(FLERR,arg[3]); - double muS_one = force->numeric(FLERR,arg[4]); - double cor_one = force->numeric(FLERR,arg[5]); - double Ecoh_one = force->numeric(FLERR,arg[6]); - double kR_one = force->numeric(FLERR,arg[7]); - double muR_one = force->numeric(FLERR,arg[8]); - double etaR_one = force->numeric(FLERR,arg[9]); - - //Defaults - int normaldamp_one = TSUJI; - int rollingdamp_one = INDEP; - double cut_one = cut_global; - - int iarg = 10; - while (iarg < narg) { - if (strcmp(arg[iarg],"normaldamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp_one = TSUJI; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp_one = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); - iarg += 2; + int iarg = 2; + while (iarg < narg){ + if (strcmp(arg[iarg], "hooke") == 0){ + if (coeff_types == MATERIAL) error->all(FLERR,"Illegal pair_coeff command, 'stiffness' coefficients required for Hooke"); + if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); + normal_local = HOOKE; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += 3; + } + else if (strcmp(arg[iarg], "hertz") == 0){ + int num_coeffs = 2; + if (coeff_types == MATERIAL) num_coeffs += 1; + if (iarg + offset >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + normal_local = HERTZ; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + if (coeff_types == MATERIAL) normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "dmt") == 0){ + if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_coeff command, 'material' coefficients required for DMT"); + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + normal_local = DMT; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "jkr") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); + if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_coeff command, 'material' coefficients required for JKR"); + beyond_contact = 1; + normal_local = JKR; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + iarg += 5; } - else if (strcmp(arg[iarg],"rollingdamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp_one = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp_one = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); - iarg +=2; + else if (strcmp(arg[iarg], "damp_velocity") == 0){ + damping_local = VELOCITY; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ + damping_local = VISCOELASTIC; + iarg += 1; } - else { - if (strcmp(arg[iarg],"NULL") == 0) cut_one = -1.0; - else cut_one = force->numeric(FLERR,arg[iarg]); + else if (strcmp(arg[iarg], "damp_tsuji") == 0){ + damping_local = TSUJI; iarg += 1; } + else if (strstr(arg[iarg], "tangential") != NULL){ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + if (strstr(arg[iarg], "nohistory") != NULL){ + tangential_local = TANGENTIAL_NOHISTORY; + } + else{ + tangential_local = TANGENTIAL_MINDLIN; + tangential_history = 1; + } + tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt + tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + else if (strstr(arg[iarg], "rolling") != NULL){ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); + if (strstr(arg[iarg], "nohistory") != NULL){ + rolling_local = ROLLING_NOHISTORY; + } + else{ + rolling_local = ROLLING_SDS; + rolling_history = 1; + } + rolling_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt + rolling_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + rolling_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + else if (strstr(arg[iarg], "twisting") != NULL){ + if (strstr(arg[iarg], "marshall") != NULL){ + twisting_local = TWISTING_MARSHALL; + twisting_history = 1; + } + else{ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twisting model"); + if (strstr(arg[iarg], "nohistory") != NULL){ + twisting_local = TWISTING_NOHISTORY; + } + else{ + twisting_local = TWISTING_SDS; + twisting_history = 1; + size_history += 1; + } + twisting_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt + twisting_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + twisting_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + } } int count = 0; - for (int i = ilo; i <= ihi; i++) { - double pois = E_one/(2.0*G_one) - 1.0; - double alpha_one = 1.2728-4.2783*cor_one+11.087*cor_one*cor_one-22.348*cor_one*cor_one*cor_one+27.467*cor_one*cor_one*cor_one*cor_one-18.022*cor_one*cor_one*cor_one*cor_one*cor_one+4.8218*cor_one*cor_one*cor_one*cor_one*cor_one*cor_one; + double damp; + if (damping_local == TSUJI){ + double cor = normal_coeffs_local[1]; + damp =1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_local[1]; + for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - E[i][j] = E_one; - G[i][j] = G_one; - if (normaldamp_one == TSUJI) { - normaldamp[i][j] = TSUJI; - alpha[i][j] = alpha_one; - } - else if (normaldamp_one == BRILLIANTOV) { - normaldamp[i][j] = BRILLIANTOV; - gamman[i][j] = cor_one; - } - if (rollingdamp_one == INDEP) { - rollingdamp[i][j] = INDEP; - } - else if (rollingdamp_one == BRILLROLL) { - rollingdamp[i][j] = BRILLROLL; - } - muS[i][j] = muS_one; - Ecoh[i][j] = Ecoh_one; - kR[i][j] = kR_one; - etaR[i][j] = etaR_one; - muR[i][j] = muR_one; - cut[i][j] = cut_one; + normal[i][j] = normal_local; + normal_coeffs[i][j][0] = normal_coeffs_local[0]; + normal_coeffs[i][j][1] = damp; + if (coeff_types == MATERIAL) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal_local == JKR) || (normal_local == DMT)) + normal_coeffs[i][j][3] = normal_coeffs_local[3]; + + tangential[i][j] = tangential_local; + if (tangential_local != NONE) + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; + + rolling[i][j] = rolling_local; + if (rolling_local != NONE) + for (int k = 0; k < 3; k++) + rolling_coeffs[i][j][k] = tangential_coeffs_local[k]; + + twisting[i][j] = twisting_local; + if (twisting_local != NONE) + for (int k = 0; k < 3; k++) + rolling_coeffs[i][j][k] = tangential_coeffs_local[k]; + setflag[i][j] = 1; count++; } } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients1"); + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } /* ---------------------------------------------------------------------- @@ -751,7 +1144,7 @@ void PairGranular::init_style() // set fix which stores history info - if (history) { + if (size_history > 0) { int ifix = modify->find_fix("NEIGH_HISTORY"); if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); fix_history = (FixNeighHistory *) modify->fix[ifix]; @@ -765,7 +1158,17 @@ void PairGranular::init_style() double PairGranular::init_one(int i, int j) { if (setflag[i][j] == 0) { - E[i][j] = mix_stiffnessE(E[i][i],E[j][j],G[i][i],G[j][j]); + if ((normal[i] != normal[j]) || + (damping[i] != damping[j]) || + (tangential[i] != tangential[j]) || + (rolling[i] != rolling[j]) || + (twisting[i] != twisting[j])){ + + char str[128]; + sprintf(str,"Failed to open FFmpeg pipeline to file %s",filename); + error->one(FLERR,str); + } + G[i][j] = mix_stiffnessG(G[i][i],E[j][j],G[i][i],G[j][j]); if (normaldamp[i][j] == TSUJI) { alpha[i][j] = mix_geom(alpha[i][i],alpha[j][j]); diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 9fbc9acd51..33d28b03bf 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -47,7 +47,7 @@ public: double cut_global; double dt; int freeze_group_bit; - int history; + int use_history; int neighprev; double *onerad_dynamic,*onerad_frozen; @@ -62,11 +62,49 @@ public: int nmax; // allocated size of mass_rigid virtual void allocate(); + int beyond_contact; + + + // comment next line to turn off templating +/*#define TEMPLATED_PAIR_GRANULAR +#ifdef TEMPLATED_PAIR_GRANULAR + template < int Tp_coeff_types, + int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_rolling, int Tp_twisting > + void compute_templated(int eflag, int vflag); +#else +*/ + void compute_untemplated( + int, + int, int, int, + int, int, + int, int); +//#endif private: + int coeff_types; int size_history; - int num_coeffs; - double ***coeffs; + + //Per-type models + int **normal, **damping, **tangential, **rolling, **twisting; + + int normal_global, damping_global; + int tangential_global, rolling_global, twisting_global; + + int tangential_history, rolling_history, twisting_history; + int tangential_history_index; + int rolling_history_index; + int twisting_history_index; + + double *normal_coeffs_one; + double *tangential_coeffs_one; + double *rolling_coeffs_one; + double *twisting_coeffs_one; + + double ***normal_coeffs; + double ***tangential_coeffs; + double ***rolling_coeffs; + double ***twisting_coeffs; double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); -- GitLab From 009d8c8ebf3af1c9d3196192fe2a033af624c6b6 Mon Sep 17 00:00:00 2001 From: dsbolin Date: Fri, 21 Dec 2018 09:29:47 -0700 Subject: [PATCH 0078/1243] Added parsing to pair_coeff, added for for init_one --- src/GRANULAR/pair_granular.cpp | 174 +++++++++++++++++++++------------ src/GRANULAR/pair_granular.h | 8 +- 2 files changed, 114 insertions(+), 68 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 73fcb19a8c..a94575185a 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -493,8 +493,6 @@ void PairGranular::compute_untemplated vt3 = vr3 - vn3; // relative rotational velocity - // Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting - // delta/2, i.e. instead of radi, use distance to center of contact point? wr1 = (radi*omega[i][0] + radj*omega[j][0]); wr2 = (radi*omega[i][1] + radj*omega[j][1]); wr3 = (radi*omega[i][2] + radj*omega[j][2]); @@ -508,7 +506,7 @@ void PairGranular::compute_untemplated // history effects touch[jj] = 1; - history = &allhistory[3*jj]; + history = &allhistory[size_history*jj]; shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -760,9 +758,9 @@ void PairGranular::settings(int narg, char **arg) if (coeff_types == MATERIAL) error->all(FLERR,"Illegal pair_coeff command, 'stiffness' coefficients required for Hooke"); if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); normal_global = HOOKE; - memory->create(normal_coeffs_one, 2, "pair:normal_coeffs_one"); - normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + memory->create(normal_coeffs_global, 2, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += 3; } else if (strcmp(arg[iarg], "hertz") == 0){ @@ -770,21 +768,21 @@ void PairGranular::settings(int narg, char **arg) if (coeff_types == MATERIAL) num_coeffs += 1; if (iarg + offset >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); normal_global = HERTZ; - memory->create(normal_coeffs_one, num_coeffs, "pair:normal_coeffs_one"); - normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E - normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping - if (coeff_types == MATERIAL) normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') + memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + if (coeff_types == MATERIAL) normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "dmt") == 0){ if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_style command, 'material' coefficients required for DMT"); if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); normal_global = DMT; - memory->create(normal_coeffs_one, 4, "pair:normal_coeffs_one"); - normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion iarg += 5; } else if (strcmp(arg[iarg], "jkr") == 0){ @@ -792,11 +790,11 @@ void PairGranular::settings(int narg, char **arg) if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_style command, 'material' coefficients required for JKR"); beyond_contact = 1; normal_global = JKR; - memory->create(normal_coeffs_one, 4, "pair:normal_coeffs_one"); - normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; } else if (strcmp(arg[iarg], "damp_velocity") == 0){ @@ -820,10 +818,10 @@ void PairGranular::settings(int narg, char **arg) tangential_global = TANGENTIAL_MINDLIN; tangential_history = 1; } - memory->create(tangential_coeffs_one, 3, "pair:tangential_coeffs_one"); - tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kt - tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + memory->create(tangential_coeffs_global, 3, "pair:tangential_coeffs_global"); + tangential_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt + tangential_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } else if (strstr(arg[iarg], "rolling") != NULL){ @@ -835,17 +833,17 @@ void PairGranular::settings(int narg, char **arg) rolling_global = ROLLING_SDS; rolling_history = 1; } - memory->create(rolling_coeffs_one, 3, "pair:rolling_coeffs_one"); - rolling_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kt - rolling_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - rolling_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + memory->create(rolling_coeffs_global, 3, "pair:rolling_coeffs_global"); + rolling_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt + rolling_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + rolling_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } else if (strstr(arg[iarg], "twisting") != NULL){ if (strstr(arg[iarg], "marshall") != NULL){ twisting_global = TWISTING_MARSHALL; twisting_history = 1; - memory->create(twisting_coeffs_one, 3, "pair:twisting_coeffs_one"); //To be filled later + memory->create(twisting_coeffs_global, 3, "pair:twisting_coeffs_global"); //To be filled later } else{ if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twisting model"); @@ -856,15 +854,60 @@ void PairGranular::settings(int narg, char **arg) twisting_global = TWISTING_SDS; twisting_history = 1; } - memory->create(twisting_coeffs_one, 3, "pair:twisting_coeffs_one"); - twisting_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kt - twisting_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - twisting_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + memory->create(twisting_coeffs_global, 3, "pair:twisting_coeffs_global"); + twisting_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt + twisting_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + twisting_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } } } + //Set all i-i entrie, which may be replaced by pair coeff commands + //It may also make sense to consider removing all of the above, and only + // having the option for pair_coeff to set the parameters, similar to most LAMMPS pair styles + // The reason for the current setup is to keep true to existing pair gran/hooke etc. syntax, + // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. + allocate(); + double damp; + for (int i = 1; i <= atom->ntypes; i++){ + normal[i][i] = normal_global; + damping[i][i] = damping_global; + tangential[i][i] = tangential_global; + rolling[i][i] = rolling_global; + twisting[i][i] = twisting_global; + + if (damping_global == TSUJI){ + double cor = normal_coeffs_global[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_global[1]; + normal_coeffs[i][i][0] = normal_coeffs_global[0]; + normal_coeffs[i][i][1] = damp; + if (coeff_types == MATERIAL) normal_coeffs[i][i][2] = normal_coeffs_global[2]; + if ((normal_global == JKR) || (normal_global == DMT)) + normal_coeffs[i][i][3] = normal_coeffs_global[3]; + + tangential[i][i] = tangential_global; + if (tangential_global != NONE) + for (int k = 0; k < 3; k++) + tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; + + rolling[i][i] = rolling_global; + if (rolling_global != NONE) + for (int k = 0; k < 3; k++) + rolling_coeffs[i][i][k] = rolling_coeffs_global[k]; + + twisting[i][i] = twisting_global; + if (twisting_global != NONE) + for (int k = 0; k < 3; k++) + twisting_coeffs[i][i][k] = twisting_coeffs_local[k]; + + setflag[i][i] = 1; + } + //Additional checks if (tangential_global == -1){ error->all(FLERR, "Illegal pair_style command: must specify tangential model"); @@ -1005,7 +1048,7 @@ void PairGranular::coeff(int narg, char **arg) double damp; if (damping_local == TSUJI){ double cor = normal_coeffs_local[1]; - damp =1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ 27.467*pow(cor,4)-18.022*pow(cor,5)+ 4.8218*pow(cor,6); } @@ -1028,12 +1071,12 @@ void PairGranular::coeff(int narg, char **arg) rolling[i][j] = rolling_local; if (rolling_local != NONE) for (int k = 0; k < 3; k++) - rolling_coeffs[i][j][k] = tangential_coeffs_local[k]; + rolling_coeffs[i][j][k] = rolling_coeffs_local[k]; twisting[i][j] = twisting_local; if (twisting_local != NONE) - for (int k = 0; k < 3; k++) - rolling_coeffs[i][j][k] = tangential_coeffs_local[k]; + for (int k = 0; k < 3; k++) + twisting_coeffs[i][j][k] = twisting_coeffs_local[k]; setflag[i][j] = 1; count++; @@ -1164,36 +1207,39 @@ double PairGranular::init_one(int i, int j) (rolling[i] != rolling[j]) || (twisting[i] != twisting[j])){ - char str[128]; - sprintf(str,"Failed to open FFmpeg pipeline to file %s",filename); - error->one(FLERR,str); + char str[512]; + sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); + error->one(FLERR,str); } - G[i][j] = mix_stiffnessG(G[i][i],E[j][j],G[i][i],G[j][j]); - if (normaldamp[i][j] == TSUJI) { - alpha[i][j] = mix_geom(alpha[i][i],alpha[j][j]); + if (coeff_types == MATERIAL){ + normal_coeffs[i][j][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][i][2], normal_coeffs[j][j][2]); + normal_coeffs[i][j][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][i][2], normal_coeffs[j][j][2]); } - else if (normaldamp[i][j] == BRILLIANTOV) { - gamman[i][j] = mix_geom(gamman[i][i],gamman[j][j]); + else{ + normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0];) + } + + normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1];) + if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) + normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); + + if (tangential[i][i] != NONE){ + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); } - muS[i][j] = mix_geom(muS[i][i],muS[j][j]); - Ecoh[i][j] = mix_geom(Ecoh[i][i],Ecoh[j][j]); - kR[i][j] = mix_geom(kR[i][i],kR[j][j]); - etaR[i][j] = mix_geom(etaR[i][i],etaR[j][j]); - muR[i][j] = mix_geom(muR[i][i],muR[j][j]); - } - E[j][i] = E[i][j]; - G[j][i] = G[i][j]; - normaldamp[j][i] = normaldamp[i][j]; - alpha[j][i] = alpha[i][j]; - gamman[j][i] = gamman[i][j]; - rollingdamp[j][i] = rollingdamp[i][j]; - muS[j][i] = muS[i][j]; - Ecoh[j][i] = Ecoh[i][j]; - kR[j][i] = kR[i][j]; - etaR[j][i] = etaR[i][j]; - muR[j][i] = muR[i][j]; + if (rolling[i][i] != NONE){ + for (int k = 0; k < 3; k++) + rolling_coeffs[i][j][k] = mix_geom(rolling_coeffs[i][i][k], rolling_coeffs[j][j][k]); + } + + if (twisting[i][i] != NONE){ + for (int k = 0; k < 3; k++) + twisting_coeffs[i][j][k] = mix_geom(twisting_coeffs[i][i][k], twisting_coeffs[j][j][k]); + } double cutoff = cut[i][j]; @@ -1559,7 +1605,7 @@ double PairGranular::memory_usage() } /* ---------------------------------------------------------------------- - mixing of stiffness (E) + mixing of Young's modulus (E) ------------------------------------------------------------------------- */ double PairGranular::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) @@ -1570,7 +1616,7 @@ double PairGranular::mix_stiffnessE(double Eii, double Ejj, double Gii, double G } /* ---------------------------------------------------------------------- - mixing of stiffness (G) + mixing of shear modulus (G) ------------------------------------------------------------------------- */ double PairGranular::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 33d28b03bf..0ad36d85c7 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -96,10 +96,10 @@ public: int rolling_history_index; int twisting_history_index; - double *normal_coeffs_one; - double *tangential_coeffs_one; - double *rolling_coeffs_one; - double *twisting_coeffs_one; + double *normal_coeffs_global; + double *tangential_coeffs_global; + double *rolling_coeffs_global; + double *twisting_coeffs_global; double ***normal_coeffs; double ***tangential_coeffs; -- GitLab From 71ed60ced31a741b708c114c221257237d2421de Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Fri, 21 Dec 2018 15:41:46 -0700 Subject: [PATCH 0079/1243] More work on compute method for generalized pair granular --- src/GRANULAR/pair_granular.cpp | 502 +++++++++++++-------------------- src/GRANULAR/pair_granular.h | 22 +- 2 files changed, 199 insertions(+), 325 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index a94575185a..dd124671e0 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -39,10 +39,12 @@ Contributing authors: Leo Silbert (SNL), Gary Grest (SNL), using namespace LAMMPS_NS; using namespace MathConst; -#define ONETHIRD 0.33333333333333333 -#define TWOTHIRDS 0.66666666666666666 -#define POW6ONE 0.550321208149104 //6^(-1/3) -#define POW6TWO 0.30285343213869 //6^(-2/3) +#define PI27SQ 266.47931882941264802866 // 27*PI**2 +#define THREEROOT3 5.19615242270663202362 // 3*sqrt(3) +#define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) +#define INVROOT6 0.40824829046386307274 // 1/sqrt(6) +#define FOURTHIRDS 1.333333333333333 // 4/3 +#define TWOPI 6.28318530717959 // 2*PI #define EPSILON 1e-10 @@ -97,17 +99,6 @@ PairGranular::~PairGranular() memory->destroy(cutsq); memory->destroy(cut); - memory->destroy(E); - memory->destroy(G); - memory->destroy(normaldamp); - memory->destroy(rollingdamp); - memory->destroy(alpha); - memory->destroy(gamman); - memory->destroy(muS); - memory->destroy(Ecoh); - memory->destroy(kR); - memory->destroy(muR); - memory->destroy(etaR); delete [] onerad_dynamic; delete [] onerad_frozen; @@ -117,215 +108,38 @@ PairGranular::~PairGranular() memory->destroy(mass_rigid); } -void PairGranular::compute(int eflag, int vflag){ - /* -#ifdef TEMPLATED_PAIR_GRANULAR - if (normal == 0){ - if (damping == 0){ - if (tangential == 0){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,0,0,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,0,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,0,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,0,0,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,0,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,0,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,0,0,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,0,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,0,2,2>(eflag, vflag); - } - } - else if (tangential == 1){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,0,1,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,1,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,1,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,0,1,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,1,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,1,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,0,1,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,1,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,1,2,2>(eflag, vflag); - } - } - else if (tangential == 2){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,0,2,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,2,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,2,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,0,2,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,2,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,2,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,0,2,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,0,2,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,0,2,2,2>(eflag, vflag); - } - } - } - else if (damping == 1){ - if (tangential == 0){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,1,0,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,0,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,0,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,1,0,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,0,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,0,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,1,0,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,0,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,0,2,2>(eflag, vflag); - } - } - else if (tangential == 1){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,1,1,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,1,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,1,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,1,1,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,1,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,1,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,1,1,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,1,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,1,2,2>(eflag, vflag); - } - } - else if (tangential == 2){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,1,2,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,2,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,2,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,1,2,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,2,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,2,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,1,2,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,1,2,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,1,2,2,2>(eflag, vflag); - } - } - } - else if (damping == 2){ - if (tangential == 0){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,2,0,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,0,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,0,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,2,0,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,0,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,0,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,2,0,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,0,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,0,2,2>(eflag, vflag); - } - } - else if (tangential == 1){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,2,1,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,1,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,1,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,2,1,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,1,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,1,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,2,1,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,1,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,1,2,2>(eflag, vflag); - } - } - else if (tangential == 2){ - if (rolling == 0){ - if (twisting == 0) compute_templated<0,0,2,2,0,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,2,0,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,2,0,2>(eflag, vflag); - } - else if (rolling == 1){ - if (twisting == 0) compute_templated<0,0,2,2,1,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,2,1,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,2,1,2>(eflag, vflag); - } - else if (rolling == 2){ - if (twisting == 0) compute_templated<0,0,2,2,2,0>(eflag, vflag); - else if (twisting == 1) compute_templated<0,0,2,2,2,1>(eflag, vflag); - else if (twisting == 2) compute_templated<0,0,2,2,2,2>(eflag, vflag); - } - } - } - } - - - } -#else -#endif -*/ - compute_untemplated(Tp_coeff_types, Tp_normal, Tp_damping, Tp_tangential, - Tp_rolling, Tp_twisting, eflag, vflag); -} -/* ---------------------------------------------------------------------- */ -/*#ifdef TEMPLATED_PAIR_GRANULAR -template < int Tp_coeff_types, - int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_rolling, int Tp_twisting > -void PairGranular::compute_templated(int eflag, int vflag) -#else -*/ -void PairGranular::compute_untemplated - (int Tp_coeff_types, - int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_rolling, int Tp_twisting, - int eflag, int vflag) -//#endif +void PairGranular::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; + double radi,radj,radsum,rsq,r,rinv,rsqinv; + double Reff, delta, dR, dR2, sqdR, knfac; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; - double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; + + double damp_normal, damp_tangential; + double kt; double Fne, Fdamp, Fntot, Fscrit, Frcrit; //For JKR - double R, R2, coh, delta_pulloff, dist_pulloff, a, E; - double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; - double keyterm, keyterm2, keyterm3, aovera0, foverFc; + double R2, coh, delta_pulloff, dist_pulloff, a, a2, E; + double delta, t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; double mi,mj,meff,damp,ccel,tor1,tor2,tor3; double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + //Rolling double rollmag, rolldotn, scalefac; double fr, fr1, fr2, fr3; + + //Twisting double signtwist, magtwist, magtortwist, Mtcrit; double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; double tortwist1, tortwist2, tortwist3; + double shrmag,rsht; int *ilist,*jlist,*numneigh,**firstneigh; int *touch,**firsttouch; @@ -378,15 +192,6 @@ void PairGranular::compute_untemplated firsttouch = fix_history->firstflag; firsthistory = fix_history->firstvalue; - double coh; - double **cohesion; - double **stiffness; - double **damping; - if (Tp_normal == JKR){ - cohesion = coeffs[normal_coeff_inds[4]]; - } - - for (ii = 0; ii < inum; ii++) { i = ilist[ii]; itype = type[i]; @@ -413,12 +218,13 @@ void PairGranular::compute_untemplated radsum = radi + radj; untouchflag = (rsq >= radsum*radsum); + E = normal_coeffs[itype][jtype][0]; + Reff = radi*radj/(radi+radj); if (normal[itype][jtype] == JKR){ - R = radi*radj/(radi+radj); - R2 = R*R; - coh = cohesion[itype][jtype]; + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); - delta_pulloff = a*a/R - 2*sqrt(M_PI*coh*a/E); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); dist_pulloff = radsum+delta_pulloff; untouchflag = (rsq >= (dist_pulloff)*(dist_pulloff)); } @@ -466,22 +272,52 @@ void PairGranular::compute_untemplated if (mask[i] & freeze_group_bit) meff = mj; if (mask[j] & freeze_group_bit) meff = mi; - //**************************************** - //Normal force = JKR-adjusted Hertzian contact + damping - //**************************************** + delta = radsum - r; + if (normal[itype][jtype] == JKR){ + dR = delta*Reff; + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = FOURTHIRDS*E*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + + else if (normal[itype][jtype] != HOOKE){ //HERTZ, DMT + a = sqdR = sqrt(dR); + knfac = FOURTHIRDS*E*sqdR; + Fne = knfac*delta; + } + else{ //Hooke + knfac = FOURTHIRDS*E; + Fne = knfac*delta; + } + //Consider restricting Hooke to only have 'velocity' as an option for damping? + if (damping[itype][jtype] == VELOCITY){ + damp_normal = normal_coeffs[itype][jtype][1]; + } + else if (damping[itype][jtype] == VISCOELASTIC){ + if (normal[itype][jtype] == HOOKE) sqdR = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*sqdR*meff; + } + else if (damping[itype][jtype] == TSUJI){ + damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); } - //Damping - kn = 4.0/3.0*E[itype][jtype]*a; - if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + Fdamp = -damp_normal*vnnr; Fntot = Fne + Fdamp; - //if (screen) fprintf(screen,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); - //if (logfile) fprintf(logfile,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); //**************************************** //Tangential force, including history effects @@ -505,54 +341,58 @@ void PairGranular::compute_untemplated vrel = sqrt(vrel); // history effects - touch[jj] = 1; - history = &allhistory[size_history*jj]; - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - - // Rotate and update displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (historyupdate) { - rsht = history[0]*nx + history[1]*ny + history[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - history[0] -= rsht*nx; - history[1] -= rsht*ny; - history[2] -= rsht*nz; - //Also rescale to preserve magnitude - history[0] *= scalefac; - history[1] *= scalefac; - history[2] *= scalefac; + if (tangential_history[itype][jtype]){ + touch[jj] = 1; + history = &allhistory[size_history*jj]; + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // Rotate and update displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (historyupdate) { + rsht = history[0]*nx + history[1]*ny + history[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + history[0] -= rsht*nx; + history[1] -= rsht*ny; + history[2] -= rsht*nz; + //Also rescale to preserve magnitude + history[0] *= scalefac; + history[1] *= scalefac; + history[2] *= scalefac; + } + //Update history + history[0] += vtr1*dt; + history[1] += vtr2*dt; + history[2] += vtr3*dt; } - //Update history - history[0] += vtr1*dt; - history[1] += vtr2*dt; - history[2] += vtr3*dt; - } - // tangential forces = history + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*G[itype][jtype]*a; + // tangential forces = history + tangential velocity damping + if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); + kt=tangential_coeffs[itype][jtype][0]*a; - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*history[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*history[1] - eta_T*vtr2; - fs3 = -kt*history[2] - eta_T*vtr3; + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + fs1 = -kt*history[0] - damp_tangential*vtr1; + fs2 = -kt*history[1] - damp_tangential*vtr2; + fs3 = -kt*history[2] - damp_tangential*vtr3; - // rescale frictional displacements and forces if needed - Fscrit = muS[itype][jtype] * fabs(Fne + 2*F_C); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead + // rescale frictional displacements and forces if needed + if (normal[itype][jtype] == JKR){ + double Fpulloff = -3*M_PI*coh*Reff; + Fscrit = tangential_coeffs[itype][jtype][2] * fabs(Fne + 2*Fpulloff); + } + else{ + Fscrit = tangential_coeffs[itype][jtype][2] * fabs(Fne); + } + // For JKR, use eq 43 of Marshall. For DMT, use Fne instead fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); if (fs > Fscrit) { if (shrmag != 0.0) { - //history[0] = (Fcrit/fs) * (history[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //history[1] = (Fcrit/fs) * (history[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //history[2] = (Fcrit/fs) * (history[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - history[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - history[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - history[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); + history[0] = -1.0/kt*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/kt*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/kt*(Fscrit*fs3/fs + damp_tangential*vtr3); fs1 *= Fscrit/fs; fs2 *= Fscrit/fs; fs3 *= Fscrit/fs; @@ -715,6 +555,7 @@ void PairGranular::allocate() setflag[i][j] = 0; memory->create(cutsq,n+1,n+1,"pair:cutsq"); + memory->create(cut,n+1,n+1,"pair:cut"); memory->create(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); memory->create(rolling_coeffs,n+1,n+1,3,"pair:rolling_coeffs"); @@ -770,6 +611,7 @@ void PairGranular::settings(int narg, char **arg) normal_global = HERTZ; memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E + if (coeff_types == STIFFNESS) normal_coeffs_global[0] /= FOURTHIRDS; normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping if (coeff_types == MATERIAL) normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') iarg += num_coeffs+1; @@ -956,6 +798,7 @@ void PairGranular::coeff(int narg, char **arg) if (iarg + offset >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); normal_local = HERTZ; normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E + if (coeff_types == STIFFNESS) normal_coeffs_local[0] /= FOURTHIRDS; normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping if (coeff_types == MATERIAL) normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') iarg += num_coeffs+1; @@ -1079,6 +922,8 @@ void PairGranular::coeff(int narg, char **arg) twisting_coeffs[i][j][k] = twisting_coeffs_local[k]; setflag[i][j] = 1; + double cut_one; + count++; } } @@ -1100,18 +945,36 @@ void PairGranular::init_style() if (comm->ghost_velocity == 0) error->all(FLERR,"Pair granular requires ghost atoms store velocity"); - // need a granular neigh list + // Determine whether we need a granular neigh list, how large it needs to be + history_flag = tangential_history || rolling_history || twisting_history; + size_history = 3*tangential_history + 3*rolling_history + twisting_history; + + //Determine location of tangential/rolling/twisting histories in array + if (rolling_history){ + if (tangential_history) rolling_history_index = 3; + else rolling_history_index = 0; + } + if (twisting_history){ + if (tangential_history){ + if (rolling_history) twisting_history_index = 6; + else twisting_history_index = 3; + } + else{ + if (rolling_history) twisting_history_index = 3; + else twisting_history_index = 0; + } + } int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->size = 1; - if (history) neighbor->requests[irequest]->history = 1; + if (history_flag) neighbor->requests[irequest]->history = 1; dt = update->dt; // if history is stored: // if first init, create Fix needed for storing history - if (history && fix_history == NULL) { + if (history_flag && fix_history == NULL) { char dnumstr[16]; sprintf(dnumstr,"%d",size_history); char **fixarg = new char*[4]; @@ -1159,13 +1022,15 @@ void PairGranular::init_style() onerad_dynamic[i] = onerad_frozen[i] = 0.0; if (ipour >= 0) { itype = i; - onerad_dynamic[i] = - *((double *) modify->fix[ipour]->extract("radius",itype)); + double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); + if (normal[itype][itype] == JKR) radmax = radmax + 0.5*pulloff_distance(radmax, itype); + onerad_dynamic[i] = radmax; } if (idep >= 0) { itype = i; - onerad_dynamic[i] = - *((double *) modify->fix[idep]->extract("radius",itype)); + double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); + if (normal[itype][itype] == JKR) radmax = radmax + 0.5*pulloff_distance(radmax, itype); + onerad_dynamic[i] = radmax; } } @@ -1174,11 +1039,18 @@ void PairGranular::init_style() int *type = atom->type; int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (mask[i] & freeze_group_bit) - onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]); - else - onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]); + for (i = 0; i < nlocal; i++){ + double radius_cut = radius[i]; + if (normal[type[i]][type[i]] == JKR){ + radius_cut = radius[i] + 0.5*pulloff_distance(radius[i], type[i]); + } + if (mask[i] & freeze_group_bit){ + onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); + } + else{ + onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius_cut); + } + } MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, MPI_DOUBLE,MPI_MAX,world); @@ -1187,7 +1059,7 @@ void PairGranular::init_style() // set fix which stores history info - if (size_history > 0) { + if (size_history > 0){ int ifix = modify->find_fix("NEIGH_HISTORY"); if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); fix_history = (FixNeighHistory *) modify->fix[ifix]; @@ -1219,10 +1091,11 @@ double PairGranular::init_one(int i, int j) normal_coeffs[i][i][2], normal_coeffs[j][j][2]); } else{ - normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0];) + normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); + if (normal[i][j] == HERTZ) normal_coeffs[i][j][0] /= FOURTHIRDS; } - normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1];) + normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); @@ -1240,32 +1113,31 @@ double PairGranular::init_one(int i, int j) for (int k = 0; k < 3; k++) twisting_coeffs[i][j][k] = mix_geom(twisting_coeffs[i][i][k], twisting_coeffs[j][j][k]); } + } - double cutoff = cut[i][j]; - - // It is likely that cut[i][j] at this point is still 0.0. This can happen when + // It is possible that cut[i][j] at this point is still 0.0. This can happen when // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size - // To avoid this issue,for cases involving cut[i][j] = 0.0 (possible only + // To avoid this issue, for cases involving cut[i][j] = 0.0 (possible only // if there is no current information about radius/cutoff of type i and j). - // we assign cutoff = min(cut[i][j]) for i,j such that cut[i][j] > 0.0. - - if (cut[i][j] < 0.0) { - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); - } - cutoff = cutmax; + // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. + + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); } + cutoff = cutmax; } + return cutoff; } @@ -1628,9 +1500,25 @@ double PairGranular::mix_stiffnessG(double Eii, double Ejj, double Gii, double G /* ---------------------------------------------------------------------- mixing of everything else - ------------------------------------------------------------------------- */ +------------------------------------------------------------------------- */ double PairGranular::mix_geom(double valii, double valjj) { - return sqrt(valii*valjj); + return sqrt(valii*valjj); +} + + +/* ---------------------------------------------------------------------- + Compute pull-off distance (beyond contact) for a given radius and atom type +------------------------------------------------------------------------- */ + +double PairGranular::pulloff_distance(double radius, int itype) +{ + double R, E, coh, a, delta_pulloff; + coh = normal_coeffs[itype][itype][3]; + E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], + normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); + a = cbrt(9*M_PI*coh*R*R/(4*E)); + return a*a/R - 2*sqrt(M_PI*coh*a/E); } + diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 0ad36d85c7..14cc02675b 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -52,6 +52,7 @@ public: int neighprev; double *onerad_dynamic,*onerad_frozen; double *maxrad_dynamic,*maxrad_frozen; + double **cut; class FixNeighHistory *fix_history; @@ -64,24 +65,7 @@ public: virtual void allocate(); int beyond_contact; - - // comment next line to turn off templating -/*#define TEMPLATED_PAIR_GRANULAR -#ifdef TEMPLATED_PAIR_GRANULAR - template < int Tp_coeff_types, - int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_rolling, int Tp_twisting > - void compute_templated(int eflag, int vflag); -#else -*/ - void compute_untemplated( - int, - int, int, int, - int, int, - int, int); -//#endif - - private: +private: int coeff_types; int size_history; @@ -91,6 +75,7 @@ public: int normal_global, damping_global; int tangential_global, rolling_global, twisting_global; + int history_flag; int tangential_history, rolling_history, twisting_history; int tangential_history_index; int rolling_history_index; @@ -109,6 +94,7 @@ public: double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); double mix_geom(double valii, double valjj); + double pulloff_distance(double radius, int itype); }; } -- GitLab From 7b4d0092b0d8694fddc9820f74a70ac3a5f77a36 Mon Sep 17 00:00:00 2001 From: dsbolin Date: Sat, 22 Dec 2018 14:33:09 -0700 Subject: [PATCH 0080/1243] Added type- and form-dependent conditionals in PairGranular::compute, still some issues with overall structure of the code. --- src/GRANULAR/pair_granular.cpp | 302 ++++++++++++++++++++------------- 1 file changed, 181 insertions(+), 121 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index dd124671e0..ad7759c83a 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -97,9 +97,19 @@ PairGranular::~PairGranular() if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); + memory->destroy(normal_coeffs); + memory->destroy(tangential_coeffs); + memory->destroy(rolling_coeffs); + memory->destroy(twisting_coeffs); + + memory->destroy(normal); + memory->destroy(damping); + memory->destroy(tangential); + memory->destroy(rolling); + memory->destroy(twisting); + delete [] onerad_dynamic; delete [] onerad_frozen; delete [] maxrad_dynamic; @@ -121,7 +131,7 @@ void PairGranular::compute(int eflag, int vflag) double damp_normal, damp_tangential; double kt; - double Fne, Fdamp, Fntot, Fscrit, Frcrit; + double Fne, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; //For JKR double R2, coh, delta_pulloff, dist_pulloff, a, a2, E; @@ -273,9 +283,8 @@ void PairGranular::compute(int eflag, int vflag) if (mask[j] & freeze_group_bit) meff = mi; delta = radsum - r; - + dR = delta*Reff; if (normal[itype][jtype] == JKR){ - dR = delta*Reff; dR2 = dR*dR; t0 = coh*coh*R2*R2*E; t1 = PI27SQ*t0; @@ -297,8 +306,11 @@ void PairGranular::compute(int eflag, int vflag) a = sqdR = sqrt(dR); knfac = FOURTHIRDS*E*sqdR; Fne = knfac*delta; + if (normal[itype][jtype] == DMT) + Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } else{ //Hooke + a = sqdR = sqrt(dR); knfac = FOURTHIRDS*E; Fne = knfac*delta; } @@ -340,10 +352,29 @@ void PairGranular::compute(int eflag, int vflag) vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); - // history effects - if (tangential_history[itype][jtype]){ + // If any history is needed: + if (history_flag){ touch[jj] = 1; history = &allhistory[size_history*jj]; + Fcrit = fabs(Fne); + if (normal[itype][jtype] == JKR){ + Fpulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*Fpulloff); + } + } + + //------------------------------ + //Tangential forces + //------------------------------ + if (tangential[itype][jtype] == MINDLIN){ + k_tangential = tangential_coeffs[itype][jtype][0]*a; + } + else{ + k_tangential = tangential_coeffs[itype][jtype][0]; + } + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + + if (tangential_history[itype][jtype]){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -369,113 +400,138 @@ void PairGranular::compute(int eflag, int vflag) } // tangential forces = history + tangential velocity damping - if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); - kt=tangential_coeffs[itype][jtype][0]*a; - - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - fs1 = -kt*history[0] - damp_tangential*vtr1; - fs2 = -kt*history[1] - damp_tangential*vtr2; - fs3 = -kt*history[2] - damp_tangential*vtr3; + fs1 = -k_tangential*history[0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[2] - damp_tangential*vtr3; // rescale frictional displacements and forces if needed - if (normal[itype][jtype] == JKR){ - double Fpulloff = -3*M_PI*coh*Reff; - Fscrit = tangential_coeffs[itype][jtype][2] * fabs(Fne + 2*Fpulloff); + Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; } - else{ - Fscrit = tangential_coeffs[itype][jtype][2] * fabs(Fne); - } - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - history[0] = -1.0/kt*(Fscrit*fs1/fs + damp_tangential*vtr1); - history[1] = -1.0/kt*(Fscrit*fs2/fs + damp_tangential*vtr2); - history[2] = -1.0/kt*(Fscrit*fs3/fs + damp_tangential*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) ft = MIN(fn,fs) / vrel; + else ft = 0.0; + fs1 = -ft*vtr1; + fs2 = -ft*vtr2; + fs3 = -ft*vtr3; } //**************************************** - // Rolling force, including history history effects + // Rolling resistance //**************************************** - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(history[3]*history[3] + history[4]*history[4] + history[5]*history[5]); - rolldotn = history[3]*nx + history[4]*ny + history[5]*nz; - - if (historyupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - history[3] -= rolldotn*nx; - history[4] -= rolldotn*ny; - history[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - history[3] *= scalefac; - history[4] *= scalefac; - history[5] *= scalefac; + if (rolling[itype][jtype] != NONE){ + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + if (rolling_history){ + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + int rhist0 = rolling_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + if (historyupdate) { + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + history[rhist0] -= rolldotn*nx; + history[rhist1] -= rolldotn*ny; + history[rhist2] -= rolldotn*nz; + //Also rescale to preserve magnitude + history[rhist0] *= scalefac; + history[rhist1] *= scalefac; + history[rhist2] *= scalefac; + } + history[rhist0] += vrl1*dt; + history[rhist1] += vrl2*dt; + history[rhist2] += vrl3*dt; + } } - history[3] += vrl1*dt; - history[4] += vrl2*dt; - history[5] += vrl3*dt; - } - k_R = kR[itype][jtype]*4.0*F_C*pow(aovera0,1.5); - if (rollingdamp[itype][jtype] == INDEP) eta_R = etaR[itype][jtype]; - else if (rollingdamp[itype][jtype] == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); - fr1 = -k_R*history[3] - eta_R*vrl1; - fr2 = -k_R*history[4] - eta_R*vrl2; - fr3 = -k_R*history[5] - eta_R*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR[itype][jtype] * fabs(Fne + 2*F_C); - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - history[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - history[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } + kR = rolling_coeffs[itype][jtype][0]; + eta_R = rolling_coeffs[itype][jtype][1]; + fr1 = -kR*history[rhist0] - eta_R*vrl1; + fr2 = -kR*history[rhist1] - eta_R*vrl2; + fr3 = -kR*history[rhist2] - eta_R*vrl3; + // rescale frictional displacements and forces if needed + Frcrit = rolling_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); + history[rhist1] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); + history[rhist2] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*rolling_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(fn,fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; + } //**************************************** // Twisting torque, including history effects //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - history[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*history[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - //history[6] = Mtcrit/k_Q*magtwist/fabs(magtwist); - history[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 + if (twist[itype][jtype] != NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (twist[itype][jtype] == MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a; + } + else{ + k_twist = twisting_coeffs[itype][jtype][0]; + damp_twist = twisting_coeffs[itype][jtype][1]; + mu_twist = twisting_coeffs[itype][jtype][2]; + } + if (twist_history){ + history[twist_history_index] += magtwist*dt; + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; } // Apply forces & torques @@ -484,9 +540,6 @@ void PairGranular::compute(int eflag, int vflag) fy = ny*Fntot + fs2; fz = nz*Fntot + fs3; - //if (screen) fprintf(screen,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); - //if (logfile) fprintf(logfile,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); - f[i][0] += fx; f[i][1] += fy; f[i][2] += fz; @@ -499,21 +552,25 @@ void PairGranular::compute(int eflag, int vflag) torque[i][1] -= radi*tor2; torque[i][2] -= radi*tor3; - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; + if (twist[itype][jtype] != NONE){ + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + } - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); + if (rolling[itype][jtype] != NONE){ + torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = R*(nz*fr1 - nx*fr3); + torroll3 = R*(nx*fr2 - ny*fr1); - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + } if (force->newton_pair || j < nlocal) { f[j][0] -= fx; @@ -524,13 +581,16 @@ void PairGranular::compute(int eflag, int vflag) torque[j][1] -= radj*tor2; torque[j][2] -= radj*tor3; - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; + if (rolling[itype][jtype] != NONE){ + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + } + if (rolling[itype][jtype] != NONE){ + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } } if (evflag) ev_tally_xyz(i,j,nlocal,0, 0.0,0.0,fx,fy,fz,delx,dely,delz); @@ -562,6 +622,7 @@ void PairGranular::allocate() memory->create(twisting_coeffs,n+1,n+1,3,"pair:twisting_coeffs"); memory->create(normal,n+1,n+1,"pair:normal"); + memory->create(damping,n+1,n+1,"pair:damping"); memory->create(tangential,n+1,n+1,"pair:tangential"); memory->create(rolling,n+1,n+1,"pair:rolling"); memory->create(twisting,n+1,n+1,"pair:twisting"); @@ -1137,7 +1198,6 @@ double PairGranular::init_one(int i, int j) } cutoff = cutmax; } - return cutoff; } -- GitLab From 41ccf832bf83e11b1d3898e0437c9ab41d011f5c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 30 Dec 2018 04:30:58 -0500 Subject: [PATCH 0081/1243] update log files --- ...0-0.g++.1 => log.12Dec18.airebo-0-0.g++.1} | 31 +++++----- ...0-0.g++.4 => log.12Dec18.airebo-0-0.g++.4} | 33 ++++++----- ...ebo-m.g++.1 => log.12Dec18.airebo-m.g++.1} | 54 +++++++++--------- ...ebo-m.g++.4 => log.12Dec18.airebo-m.g++.4} | 54 +++++++++--------- ....airebo.g++.1 => log.12Dec18.airebo.g++.1} | 56 +++++++++---------- ....airebo.g++.4 => log.12Dec18.airebo.g++.4} | 56 +++++++++---------- ...18.rebo2.g++.1 => log.12Dec18.rebo2.g++.1} | 27 +++++---- ...18.rebo2.g++.4 => log.12Dec18.rebo2.g++.4} | 27 +++++---- 8 files changed, 167 insertions(+), 171 deletions(-) rename examples/airebo/{log.29Jun18.airebo-0-0.g++.1 => log.12Dec18.airebo-0-0.g++.1} (77%) rename examples/airebo/{log.29Jun18.airebo-0-0.g++.4 => log.12Dec18.airebo-0-0.g++.4} (76%) rename examples/airebo/{log.27Nov18.airebo-m.g++.1 => log.12Dec18.airebo-m.g++.1} (67%) rename examples/airebo/{log.27Nov18.airebo-m.g++.4 => log.12Dec18.airebo-m.g++.4} (67%) rename examples/airebo/{log.27Nov18.airebo.g++.1 => log.12Dec18.airebo.g++.1} (67%) rename examples/airebo/{log.27Nov18.airebo.g++.4 => log.12Dec18.airebo.g++.4} (66%) rename examples/airebo/{log.29Jun18.rebo2.g++.1 => log.12Dec18.rebo2.g++.1} (76%) rename examples/airebo/{log.29Jun18.rebo2.g++.4 => log.12Dec18.rebo2.g++.4} (76%) diff --git a/examples/airebo/log.29Jun18.airebo-0-0.g++.1 b/examples/airebo/log.12Dec18.airebo-0-0.g++.1 similarity index 77% rename from examples/airebo/log.29Jun18.airebo-0-0.g++.1 rename to examples/airebo/log.12Dec18.airebo-0-0.g++.1 index d61c8e8b34..7efacc2dd7 100644 --- a/examples/airebo/log.29Jun18.airebo-0-0.g++.1 +++ b/examples/airebo/log.12Dec18.airebo-0-0.g++.1 @@ -1,5 +1,4 @@ -LAMMPS (29 Jun 2018) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -16,7 +15,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 1 by 1 by 1 MPI processor grid 32640 atoms - Time spent = 0.00136042 secs + Time spent = 0.00132823 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -46,31 +45,31 @@ Neighbor list info ... bin: standard Per MPI rank memory allocation (min/avg/max) = 34.21 | 34.21 | 34.21 Mbytes Step Temp E_pair E_mol TotEng Press - 0 300 -138442.83 0 -137177.16 2463.0756 - 10 179.38448 -137931.29 0 -137174.48 15656.689 - 20 206.89283 -138047.05 0 -137174.19 -24047.407 + 0 300 -138442.83 0 -137177.16 2463.0755 + 10 179.38448 -137931.29 0 -137174.48 15656.69 + 20 206.89283 -138047.06 0 -137174.19 -24047.407 30 150.81289 -137807.48 0 -137171.21 -16524.191 40 173.24289 -137902.32 0 -137171.42 -5721.7187 50 151.80722 -137812.37 0 -137171.91 3489.8954 - 60 199.06038 -138013.7 0 -137173.88 17887.024 + 60 199.06038 -138013.7 0 -137173.88 17887.025 70 217.84848 -138093.82 0 -137174.73 -12266.16 - 80 202.34667 -138029.28 0 -137175.59 -7623.6635 + 80 202.34667 -138029.28 0 -137175.59 -7623.6634 90 194.92367 -137997.12 0 -137174.75 -32277.173 100 185.2078 -137954.64 0 -137173.26 -6888.5104 -Loop time of 5.00753 on 1 procs for 100 steps with 32640 atoms +Loop time of 4.96876 on 1 procs for 100 steps with 32640 atoms -Performance: 0.863 ns/day, 27.820 hours/ns, 19.970 timesteps/s +Performance: 0.869 ns/day, 27.604 hours/ns, 20.126 timesteps/s 99.8% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 3.4898 | 3.4898 | 3.4898 | 0.0 | 69.69 -Neigh | 1.4697 | 1.4697 | 1.4697 | 0.0 | 29.35 -Comm | 0.015885 | 0.015885 | 0.015885 | 0.0 | 0.32 -Output | 0.00096607 | 0.00096607 | 0.00096607 | 0.0 | 0.02 -Modify | 0.021901 | 0.021901 | 0.021901 | 0.0 | 0.44 -Other | | 0.009297 | | | 0.19 +Pair | 3.4535 | 3.4535 | 3.4535 | 0.0 | 69.50 +Neigh | 1.4688 | 1.4688 | 1.4688 | 0.0 | 29.56 +Comm | 0.015106 | 0.015106 | 0.015106 | 0.0 | 0.30 +Output | 0.00098944 | 0.00098944 | 0.00098944 | 0.0 | 0.02 +Modify | 0.021631 | 0.021631 | 0.021631 | 0.0 | 0.44 +Other | | 0.008734 | | | 0.18 Nlocal: 32640 ave 32640 max 32640 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/airebo/log.29Jun18.airebo-0-0.g++.4 b/examples/airebo/log.12Dec18.airebo-0-0.g++.4 similarity index 76% rename from examples/airebo/log.29Jun18.airebo-0-0.g++.4 rename to examples/airebo/log.12Dec18.airebo-0-0.g++.4 index 72d6fdd211..e2afb10452 100644 --- a/examples/airebo/log.29Jun18.airebo-0-0.g++.4 +++ b/examples/airebo/log.12Dec18.airebo-0-0.g++.4 @@ -1,5 +1,4 @@ -LAMMPS (29 Jun 2018) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -16,7 +15,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 2 by 2 by 1 MPI processor grid 32640 atoms - Time spent = 0.000609159 secs + Time spent = 0.000664234 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -46,31 +45,31 @@ Neighbor list info ... bin: standard Per MPI rank memory allocation (min/avg/max) = 11.75 | 11.94 | 12.13 Mbytes Step Temp E_pair E_mol TotEng Press - 0 300 -138442.83 0 -137177.16 2463.0756 - 10 179.38448 -137931.29 0 -137174.48 15656.689 - 20 206.89283 -138047.05 0 -137174.19 -24047.407 + 0 300 -138442.83 0 -137177.16 2463.0755 + 10 179.38448 -137931.29 0 -137174.48 15656.69 + 20 206.89283 -138047.06 0 -137174.19 -24047.407 30 150.81289 -137807.48 0 -137171.21 -16524.191 40 173.24289 -137902.32 0 -137171.42 -5721.7187 50 151.80722 -137812.37 0 -137171.91 3489.8954 - 60 199.06038 -138013.7 0 -137173.88 17887.024 + 60 199.06038 -138013.7 0 -137173.88 17887.025 70 217.84848 -138093.82 0 -137174.73 -12266.16 - 80 202.34667 -138029.28 0 -137175.59 -7623.6635 + 80 202.34667 -138029.28 0 -137175.59 -7623.6634 90 194.92367 -137997.12 0 -137174.75 -32277.173 100 185.2078 -137954.64 0 -137173.26 -6888.5104 -Loop time of 1.50369 on 4 procs for 100 steps with 32640 atoms +Loop time of 1.44469 on 4 procs for 100 steps with 32640 atoms -Performance: 2.873 ns/day, 8.354 hours/ns, 66.503 timesteps/s -98.5% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 2.990 ns/day, 8.026 hours/ns, 69.219 timesteps/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.92943 | 0.95749 | 0.97327 | 1.8 | 63.68 -Neigh | 0.456 | 0.46115 | 0.46657 | 0.7 | 30.67 -Comm | 0.048775 | 0.068415 | 0.10077 | 8.2 | 4.55 -Output | 0.00044918 | 0.00073665 | 0.0015814 | 0.0 | 0.05 -Modify | 0.0087936 | 0.0089477 | 0.0091038 | 0.1 | 0.60 -Other | | 0.006951 | | | 0.46 +Pair | 0.92215 | 0.93812 | 0.95363 | 1.6 | 64.94 +Neigh | 0.45592 | 0.45842 | 0.46002 | 0.2 | 31.73 +Comm | 0.016539 | 0.03352 | 0.050276 | 8.6 | 2.32 +Output | 0.00043154 | 0.00059217 | 0.001025 | 0.0 | 0.04 +Modify | 0.0087888 | 0.0090455 | 0.0095809 | 0.3 | 0.63 +Other | | 0.004989 | | | 0.35 Nlocal: 8160 ave 8163 max 8157 min Histogram: 1 1 0 0 0 0 0 0 1 1 diff --git a/examples/airebo/log.27Nov18.airebo-m.g++.1 b/examples/airebo/log.12Dec18.airebo-m.g++.1 similarity index 67% rename from examples/airebo/log.27Nov18.airebo-m.g++.1 rename to examples/airebo/log.12Dec18.airebo-m.g++.1 index 44d8b9d59c..8042130645 100644 --- a/examples/airebo/log.27Nov18.airebo-m.g++.1 +++ b/examples/airebo/log.12Dec18.airebo-m.g++.1 @@ -1,36 +1,36 @@ -LAMMPS (27 Nov 2018) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark -units metal -atom_style atomic +units metal +atom_style atomic -read_data data.airebo +read_data data.airebo orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) 1 by 1 by 1 MPI processor grid reading atoms ... 60 atoms -replicate 17 16 2 +replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 1 by 1 by 1 MPI processor grid 32640 atoms - Time spent = 0.00141144 secs + Time spent = 0.00136471 secs -neighbor 0.5 bin -neigh_modify delay 5 every 1 +neighbor 0.5 bin +neigh_modify delay 5 every 1 -pair_style airebo/morse 3.0 1 1 -pair_coeff * * ../../potentials/CH.airebo-m C H -Reading potential file ../../potentials/CH.airebo-m with DATE: 2016-03-15 +pair_style airebo/morse 3.0 1 1 +pair_coeff * * CH.airebo-m C H +Reading potential file CH.airebo-m with DATE: 2016-03-15 -velocity all create 300.0 761341 +velocity all create 300.0 761341 -fix 1 all nve -timestep 0.0005 +fix 1 all nve +timestep 0.0005 -thermo 10 -run 100 +thermo 10 +run 100 Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -45,7 +45,7 @@ Neighbor list info ... bin: standard Per MPI rank memory allocation (min/avg/max) = 106.4 | 106.4 | 106.4 Mbytes Step Temp E_pair E_mol TotEng Press - 0 300 -139283.82 0 -138018.14 152.25271 + 0 300 -139283.82 0 -138018.14 152.25266 10 166.76148 -138718.75 0 -138015.19 17412.343 20 207.7293 -138891.79 0 -138015.4 -19395.339 30 138.54469 -138596.42 0 -138011.92 -11909.248 @@ -55,21 +55,21 @@ Step Temp E_pair E_mol TotEng Press 70 185.72779 -138799.18 0 -138015.61 -10803.744 80 164.28396 -138709.5 0 -138016.4 -1524.7353 90 180.26403 -138776.42 0 -138015.9 -27143.467 - 100 164.05694 -138706.58 0 -138014.44 5157.5516 -Loop time of 64.6107 on 1 procs for 100 steps with 32640 atoms + 100 164.05694 -138706.58 0 -138014.44 5157.5517 +Loop time of 64.5779 on 1 procs for 100 steps with 32640 atoms -Performance: 0.067 ns/day, 358.948 hours/ns, 1.548 timesteps/s -99.8% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 0.067 ns/day, 358.766 hours/ns, 1.549 timesteps/s +99.9% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 59.916 | 59.916 | 59.916 | 0.0 | 92.73 -Neigh | 4.6347 | 4.6347 | 4.6347 | 0.0 | 7.17 -Comm | 0.025572 | 0.025572 | 0.025572 | 0.0 | 0.04 -Output | 0.00098896 | 0.00098896 | 0.00098896 | 0.0 | 0.00 -Modify | 0.022327 | 0.022327 | 0.022327 | 0.0 | 0.03 -Other | | 0.01076 | | | 0.02 +Pair | 59.905 | 59.905 | 59.905 | 0.0 | 92.76 +Neigh | 4.615 | 4.615 | 4.615 | 0.0 | 7.15 +Comm | 0.024453 | 0.024453 | 0.024453 | 0.0 | 0.04 +Output | 0.00099945 | 0.00099945 | 0.00099945 | 0.0 | 0.00 +Modify | 0.021971 | 0.021971 | 0.021971 | 0.0 | 0.03 +Other | | 0.01029 | | | 0.02 Nlocal: 32640 ave 32640 max 32640 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/airebo/log.27Nov18.airebo-m.g++.4 b/examples/airebo/log.12Dec18.airebo-m.g++.4 similarity index 67% rename from examples/airebo/log.27Nov18.airebo-m.g++.4 rename to examples/airebo/log.12Dec18.airebo-m.g++.4 index a4cc55211b..1aab3b3544 100644 --- a/examples/airebo/log.27Nov18.airebo-m.g++.4 +++ b/examples/airebo/log.12Dec18.airebo-m.g++.4 @@ -1,36 +1,36 @@ -LAMMPS (27 Nov 2018) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark -units metal -atom_style atomic +units metal +atom_style atomic -read_data data.airebo +read_data data.airebo orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) 1 by 1 by 4 MPI processor grid reading atoms ... 60 atoms -replicate 17 16 2 +replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 2 by 2 by 1 MPI processor grid 32640 atoms - Time spent = 0.000637531 secs + Time spent = 0.000692129 secs -neighbor 0.5 bin -neigh_modify delay 5 every 1 +neighbor 0.5 bin +neigh_modify delay 5 every 1 -pair_style airebo/morse 3.0 1 1 -pair_coeff * * ../../potentials/CH.airebo-m C H -Reading potential file ../../potentials/CH.airebo-m with DATE: 2016-03-15 +pair_style airebo/morse 3.0 1 1 +pair_coeff * * CH.airebo-m C H +Reading potential file CH.airebo-m with DATE: 2016-03-15 -velocity all create 300.0 761341 +velocity all create 300.0 761341 -fix 1 all nve -timestep 0.0005 +fix 1 all nve +timestep 0.0005 -thermo 10 -run 100 +thermo 10 +run 100 Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -45,7 +45,7 @@ Neighbor list info ... bin: standard Per MPI rank memory allocation (min/avg/max) = 29.37 | 29.75 | 30.13 Mbytes Step Temp E_pair E_mol TotEng Press - 0 300 -139283.82 0 -138018.14 152.25271 + 0 300 -139283.82 0 -138018.14 152.25266 10 166.76148 -138718.75 0 -138015.19 17412.343 20 207.7293 -138891.79 0 -138015.4 -19395.339 30 138.54469 -138596.42 0 -138011.92 -11909.248 @@ -55,21 +55,21 @@ Step Temp E_pair E_mol TotEng Press 70 185.72779 -138799.18 0 -138015.61 -10803.744 80 164.28396 -138709.5 0 -138016.4 -1524.7353 90 180.26403 -138776.42 0 -138015.9 -27143.467 - 100 164.05694 -138706.58 0 -138014.44 5157.5516 -Loop time of 18.1922 on 4 procs for 100 steps with 32640 atoms + 100 164.05694 -138706.58 0 -138014.44 5157.5517 +Loop time of 17.8093 on 4 procs for 100 steps with 32640 atoms -Performance: 0.237 ns/day, 101.068 hours/ns, 5.497 timesteps/s -98.9% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 0.243 ns/day, 98.940 hours/ns, 5.615 timesteps/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 15.968 | 16.084 | 16.308 | 3.4 | 88.41 -Neigh | 1.6017 | 1.6334 | 1.7006 | 3.1 | 8.98 -Comm | 0.1603 | 0.45122 | 0.59951 | 26.0 | 2.48 -Output | 0.00042605 | 0.00073195 | 0.0016003 | 0.0 | 0.00 -Modify | 0.0092106 | 0.010544 | 0.014411 | 2.2 | 0.06 -Other | | 0.01193 | | | 0.07 +Pair | 15.932 | 16.012 | 16.082 | 1.5 | 89.91 +Neigh | 1.5933 | 1.6063 | 1.6173 | 0.7 | 9.02 +Comm | 0.098741 | 0.17402 | 0.2676 | 16.8 | 0.98 +Output | 0.00044513 | 0.00074279 | 0.0016048 | 0.0 | 0.00 +Modify | 0.0088906 | 0.0089375 | 0.008992 | 0.0 | 0.05 +Other | | 0.007106 | | | 0.04 Nlocal: 8160 ave 8167 max 8153 min Histogram: 1 0 1 0 0 0 0 1 0 1 diff --git a/examples/airebo/log.27Nov18.airebo.g++.1 b/examples/airebo/log.12Dec18.airebo.g++.1 similarity index 67% rename from examples/airebo/log.27Nov18.airebo.g++.1 rename to examples/airebo/log.12Dec18.airebo.g++.1 index 3713c8a8f8..ccc156c15b 100644 --- a/examples/airebo/log.27Nov18.airebo.g++.1 +++ b/examples/airebo/log.12Dec18.airebo.g++.1 @@ -1,36 +1,36 @@ -LAMMPS (27 Nov 2018) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark -units metal -atom_style atomic +units metal +atom_style atomic -read_data data.airebo +read_data data.airebo orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) 1 by 1 by 1 MPI processor grid reading atoms ... 60 atoms -replicate 17 16 2 +replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 1 by 1 by 1 MPI processor grid 32640 atoms - Time spent = 0.00144172 secs + Time spent = 0.0013268 secs -neighbor 0.5 bin -neigh_modify delay 5 every 1 +neighbor 0.5 bin +neigh_modify delay 5 every 1 -pair_style airebo 3.0 1 1 -pair_coeff * * ../../potentials/CH.airebo C H -Reading potential file ../../potentials/CH.airebo with DATE: 2011-10-25 +pair_style airebo 3.0 1 1 +pair_coeff * * CH.airebo C H +Reading potential file CH.airebo with DATE: 2011-10-25 -velocity all create 300.0 761341 +velocity all create 300.0 761341 -fix 1 all nve -timestep 0.0005 +fix 1 all nve +timestep 0.0005 -thermo 10 -run 100 +thermo 10 +run 100 Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -45,31 +45,31 @@ Neighbor list info ... bin: standard Per MPI rank memory allocation (min/avg/max) = 106.4 | 106.4 | 106.4 Mbytes Step Temp E_pair E_mol TotEng Press - 0 300 -139300.72 0 -138035.04 7988.6647 + 0 300 -139300.72 0 -138035.04 7988.6646 10 161.34683 -138712.9 0 -138032.19 33228.921 20 208.59504 -138912.79 0 -138032.74 -3211.8806 30 139.7513 -138618.85 0 -138029.25 10878.143 40 142.14562 -138629.02 0 -138029.32 14601.302 - 50 114.23401 -138510.95 0 -138029 24691.125 + 50 114.23401 -138510.95 0 -138029 24691.124 60 164.92002 -138726 0 -138030.21 35125.541 70 162.15256 -138715.9 0 -138031.79 5658.7946 80 157.16184 -138695.77 0 -138032.72 19824.698 - 90 196.15907 -138860.65 0 -138033.07 -7950.8462 + 90 196.15907 -138860.65 0 -138033.07 -7950.8463 100 178.31875 -138784.89 0 -138032.57 30997.671 -Loop time of 57.9914 on 1 procs for 100 steps with 32640 atoms +Loop time of 57.482 on 1 procs for 100 steps with 32640 atoms -Performance: 0.074 ns/day, 322.174 hours/ns, 1.724 timesteps/s +Performance: 0.075 ns/day, 319.344 hours/ns, 1.740 timesteps/s 99.9% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 53.275 | 53.275 | 53.275 | 0.0 | 91.87 -Neigh | 4.6548 | 4.6548 | 4.6548 | 0.0 | 8.03 -Comm | 0.026622 | 0.026622 | 0.026622 | 0.0 | 0.05 -Output | 0.00097251 | 0.00097251 | 0.00097251 | 0.0 | 0.00 -Modify | 0.022773 | 0.022773 | 0.022773 | 0.0 | 0.04 -Other | | 0.01089 | | | 0.02 +Pair | 52.796 | 52.796 | 52.796 | 0.0 | 91.85 +Neigh | 4.6286 | 4.6286 | 4.6286 | 0.0 | 8.05 +Comm | 0.024035 | 0.024035 | 0.024035 | 0.0 | 0.04 +Output | 0.00098443 | 0.00098443 | 0.00098443 | 0.0 | 0.00 +Modify | 0.021958 | 0.021958 | 0.021958 | 0.0 | 0.04 +Other | | 0.01014 | | | 0.02 Nlocal: 32640 ave 32640 max 32640 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -84,4 +84,4 @@ Total # of neighbors = 22217840 Ave neighs/atom = 680.694 Neighbor list builds = 8 Dangerous builds = 0 -Total wall time: 0:00:59 +Total wall time: 0:00:58 diff --git a/examples/airebo/log.27Nov18.airebo.g++.4 b/examples/airebo/log.12Dec18.airebo.g++.4 similarity index 66% rename from examples/airebo/log.27Nov18.airebo.g++.4 rename to examples/airebo/log.12Dec18.airebo.g++.4 index 335690684a..fbdd9ed2e1 100644 --- a/examples/airebo/log.27Nov18.airebo.g++.4 +++ b/examples/airebo/log.12Dec18.airebo.g++.4 @@ -1,36 +1,36 @@ -LAMMPS (27 Nov 2018) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark -units metal -atom_style atomic +units metal +atom_style atomic -read_data data.airebo +read_data data.airebo orthogonal box = (-2.1 -2.1 0) to (2.1 2.1 25.579) 1 by 1 by 4 MPI processor grid reading atoms ... 60 atoms -replicate 17 16 2 +replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 2 by 2 by 1 MPI processor grid 32640 atoms - Time spent = 0.00262594 secs + Time spent = 0.000614405 secs -neighbor 0.5 bin -neigh_modify delay 5 every 1 +neighbor 0.5 bin +neigh_modify delay 5 every 1 -pair_style airebo 3.0 1 1 -pair_coeff * * ../../potentials/CH.airebo C H -Reading potential file ../../potentials/CH.airebo with DATE: 2011-10-25 +pair_style airebo 3.0 1 1 +pair_coeff * * CH.airebo C H +Reading potential file CH.airebo with DATE: 2011-10-25 -velocity all create 300.0 761341 +velocity all create 300.0 761341 -fix 1 all nve -timestep 0.0005 +fix 1 all nve +timestep 0.0005 -thermo 10 -run 100 +thermo 10 +run 100 Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -45,31 +45,31 @@ Neighbor list info ... bin: standard Per MPI rank memory allocation (min/avg/max) = 29.37 | 29.75 | 30.13 Mbytes Step Temp E_pair E_mol TotEng Press - 0 300 -139300.72 0 -138035.04 7988.6647 + 0 300 -139300.72 0 -138035.04 7988.6646 10 161.34683 -138712.9 0 -138032.19 33228.921 20 208.59504 -138912.79 0 -138032.74 -3211.8806 30 139.7513 -138618.85 0 -138029.25 10878.143 40 142.14562 -138629.02 0 -138029.32 14601.302 - 50 114.23401 -138510.95 0 -138029 24691.125 + 50 114.23401 -138510.95 0 -138029 24691.124 60 164.92002 -138726 0 -138030.21 35125.541 70 162.15256 -138715.9 0 -138031.79 5658.7946 80 157.16184 -138695.77 0 -138032.72 19824.698 - 90 196.15907 -138860.65 0 -138033.07 -7950.8462 + 90 196.15907 -138860.65 0 -138033.07 -7950.8463 100 178.31875 -138784.89 0 -138032.57 30997.671 -Loop time of 16.4395 on 4 procs for 100 steps with 32640 atoms +Loop time of 15.9743 on 4 procs for 100 steps with 32640 atoms -Performance: 0.263 ns/day, 91.331 hours/ns, 6.083 timesteps/s -98.5% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 0.270 ns/day, 88.746 hours/ns, 6.260 timesteps/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 14.263 | 14.349 | 14.483 | 2.3 | 87.28 -Neigh | 1.6071 | 1.6283 | 1.6636 | 1.7 | 9.90 -Comm | 0.26261 | 0.43435 | 0.52323 | 16.1 | 2.64 -Output | 0.00042105 | 0.0007121 | 0.001538 | 0.0 | 0.00 -Modify | 0.00898 | 0.009112 | 0.0093675 | 0.2 | 0.06 -Other | | 0.0184 | | | 0.11 +Pair | 14.13 | 14.185 | 14.258 | 1.3 | 88.80 +Neigh | 1.5945 | 1.6093 | 1.6237 | 0.9 | 10.07 +Comm | 0.075436 | 0.16329 | 0.23273 | 14.3 | 1.02 +Output | 0.00041533 | 0.00069332 | 0.0014405 | 0.0 | 0.00 +Modify | 0.0089853 | 0.0090484 | 0.0091338 | 0.1 | 0.06 +Other | | 0.007319 | | | 0.05 Nlocal: 8160 ave 8174 max 8146 min Histogram: 1 0 1 0 0 0 0 1 0 1 diff --git a/examples/airebo/log.29Jun18.rebo2.g++.1 b/examples/airebo/log.12Dec18.rebo2.g++.1 similarity index 76% rename from examples/airebo/log.29Jun18.rebo2.g++.1 rename to examples/airebo/log.12Dec18.rebo2.g++.1 index 54c87ab474..83c3a8ebea 100644 --- a/examples/airebo/log.29Jun18.rebo2.g++.1 +++ b/examples/airebo/log.12Dec18.rebo2.g++.1 @@ -1,5 +1,4 @@ -LAMMPS (29 Jun 2018) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -16,7 +15,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 1 by 1 by 1 MPI processor grid 32640 atoms - Time spent = 0.00153542 secs + Time spent = 0.0013907 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -50,27 +49,27 @@ Step Temp E_pair E_mol TotEng Press 10 179.37985 -137931.27 0 -137174.48 15655.936 20 206.87654 -138046.99 0 -137174.19 -24042.627 30 150.80122 -137807.43 0 -137171.21 -16524.118 - 40 173.24945 -137902.35 0 -137171.42 -5716.9118 + 40 173.24945 -137902.35 0 -137171.42 -5716.9119 50 151.80455 -137812.36 0 -137171.91 3480.4584 60 199.08777 -138013.82 0 -137173.88 17881.372 70 217.85748 -138093.86 0 -137174.73 -12270.999 - 80 202.37482 -138029.39 0 -137175.59 -7622.732 + 80 202.37482 -138029.39 0 -137175.59 -7622.7319 90 194.90628 -137997.05 0 -137174.75 -32267.471 100 185.17818 -137954.51 0 -137173.26 -6901.7499 -Loop time of 5.03541 on 1 procs for 100 steps with 32640 atoms +Loop time of 4.96341 on 1 procs for 100 steps with 32640 atoms -Performance: 0.858 ns/day, 27.975 hours/ns, 19.859 timesteps/s -99.0% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 0.870 ns/day, 27.574 hours/ns, 20.147 timesteps/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 3.5083 | 3.5083 | 3.5083 | 0.0 | 69.67 -Neigh | 1.4785 | 1.4785 | 1.4785 | 0.0 | 29.36 -Comm | 0.016176 | 0.016176 | 0.016176 | 0.0 | 0.32 -Output | 0.0009644 | 0.0009644 | 0.0009644 | 0.0 | 0.02 -Modify | 0.02224 | 0.02224 | 0.02224 | 0.0 | 0.44 -Other | | 0.009286 | | | 0.18 +Pair | 3.4476 | 3.4476 | 3.4476 | 0.0 | 69.46 +Neigh | 1.4692 | 1.4692 | 1.4692 | 0.0 | 29.60 +Comm | 0.015226 | 0.015226 | 0.015226 | 0.0 | 0.31 +Output | 0.00098777 | 0.00098777 | 0.00098777 | 0.0 | 0.02 +Modify | 0.021646 | 0.021646 | 0.021646 | 0.0 | 0.44 +Other | | 0.008718 | | | 0.18 Nlocal: 32640 ave 32640 max 32640 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/airebo/log.29Jun18.rebo2.g++.4 b/examples/airebo/log.12Dec18.rebo2.g++.4 similarity index 76% rename from examples/airebo/log.29Jun18.rebo2.g++.4 rename to examples/airebo/log.12Dec18.rebo2.g++.4 index b7d63dd2e5..f38f484238 100644 --- a/examples/airebo/log.29Jun18.rebo2.g++.4 +++ b/examples/airebo/log.12Dec18.rebo2.g++.4 @@ -1,5 +1,4 @@ -LAMMPS (29 Jun 2018) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) +LAMMPS (12 Dec 2018) using 1 OpenMP thread(s) per MPI task # AIREBO polyethelene benchmark @@ -16,7 +15,7 @@ replicate 17 16 2 orthogonal box = (-2.1 -2.1 0) to (69.3 65.1 51.158) 2 by 2 by 1 MPI processor grid 32640 atoms - Time spent = 0.00151467 secs + Time spent = 0.000644684 secs neighbor 0.5 bin neigh_modify delay 5 every 1 @@ -50,27 +49,27 @@ Step Temp E_pair E_mol TotEng Press 10 179.37985 -137931.27 0 -137174.48 15655.936 20 206.87654 -138046.99 0 -137174.19 -24042.627 30 150.80122 -137807.43 0 -137171.21 -16524.118 - 40 173.24945 -137902.35 0 -137171.42 -5716.9118 + 40 173.24945 -137902.35 0 -137171.42 -5716.9119 50 151.80455 -137812.36 0 -137171.91 3480.4584 60 199.08777 -138013.82 0 -137173.88 17881.372 70 217.85748 -138093.86 0 -137174.73 -12270.999 - 80 202.37482 -138029.39 0 -137175.59 -7622.732 + 80 202.37482 -138029.39 0 -137175.59 -7622.7319 90 194.90628 -137997.05 0 -137174.75 -32267.471 100 185.17818 -137954.51 0 -137173.26 -6901.7499 -Loop time of 1.49632 on 4 procs for 100 steps with 32640 atoms +Loop time of 1.4517 on 4 procs for 100 steps with 32640 atoms -Performance: 2.887 ns/day, 8.313 hours/ns, 66.831 timesteps/s -98.6% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 2.976 ns/day, 8.065 hours/ns, 68.885 timesteps/s +99.4% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.93275 | 0.95717 | 0.97367 | 1.6 | 63.97 -Neigh | 0.45634 | 0.46084 | 0.46749 | 0.6 | 30.80 -Comm | 0.038283 | 0.062074 | 0.090508 | 7.6 | 4.15 -Output | 0.00046492 | 0.00072992 | 0.0015128 | 0.0 | 0.05 -Modify | 0.0088651 | 0.0090639 | 0.0093012 | 0.2 | 0.61 -Other | | 0.006436 | | | 0.43 +Pair | 0.92079 | 0.93883 | 0.95524 | 1.6 | 64.67 +Neigh | 0.45826 | 0.46013 | 0.46316 | 0.3 | 31.70 +Comm | 0.02183 | 0.038046 | 0.052974 | 7.5 | 2.62 +Output | 0.00044131 | 0.00057179 | 0.00093198 | 0.0 | 0.04 +Modify | 0.0088243 | 0.0089917 | 0.0092998 | 0.2 | 0.62 +Other | | 0.005127 | | | 0.35 Nlocal: 8160 ave 8163 max 8157 min Histogram: 1 1 0 0 0 0 0 0 1 1 -- GitLab From dced4c1fca7f30876bc376363289d7ae7c5585c2 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Fri, 4 Jan 2019 17:03:31 -0700 Subject: [PATCH 0082/1243] More changes, fixed indentation issues --- src/GRANULAR/pair_granular.cpp | 550 +++++++++++++++++---------------- src/GRANULAR/pair_granular.h | 20 +- 2 files changed, 292 insertions(+), 278 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index ad7759c83a..93f8d514b7 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -52,8 +52,8 @@ enum {STIFFNESS, MATERIAL}; enum {VELOCITY, VISCOELASTIC, TSUJI}; enum {HOOKE, HERTZ, DMT, JKR}; enum {TANGENTIAL_MINDLIN, TANGENTIAL_NOHISTORY}; -enum {NONE, TWISTING_NOHISTORY, TWISTING_SDS, TWISTING_MARSHALL}; -enum {NONE, ROLLING_NOHISTORY, ROLLING_SDS}; +enum {NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; +enum {NONE, ROLL_NOHISTORY, ROLL_SDS}; /* ---------------------------------------------------------------------- */ @@ -84,7 +84,7 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) comm_forward = 1; beyond_contact = 0; - rolling_history_index = twisting_history_index = 0; + roll_history_index = twist_history_index = 0; tangential_history_index = -1; } @@ -101,14 +101,14 @@ PairGranular::~PairGranular() memory->destroy(normal_coeffs); memory->destroy(tangential_coeffs); - memory->destroy(rolling_coeffs); - memory->destroy(twisting_coeffs); + memory->destroy(roll_coeffs); + memory->destroy(twist_coeffs); memory->destroy(normal); memory->destroy(damping); memory->destroy(tangential); - memory->destroy(rolling); - memory->destroy(twisting); + memory->destroy(roll); + memory->destroy(twist); delete [] onerad_dynamic; delete [] onerad_frozen; @@ -123,18 +123,19 @@ void PairGranular::compute(int eflag, int vflag) int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; double radi,radj,radsum,rsq,r,rinv,rsqinv; - double Reff, delta, dR, dR2, sqdR, knfac; + double Reff, delta, dR, dR2, sqdR; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; - double damp_normal, damp_tangential; - double kt; - double Fne, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double knfac, damp_normal; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; //For JKR - double R2, coh, delta_pulloff, dist_pulloff, a, a2, E; + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; double delta, t0, t1, t2, t3, t4, t5, t6; double sqrt1, sqrt2, sqrt3, sqrt4; @@ -142,12 +143,14 @@ void PairGranular::compute(int eflag, int vflag) double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; double rollmag, rolldotn, scalefac; double fr, fr1, fr2, fr3; //Twisting + double k_twist, damp_twist, mu_twist; double signtwist, magtwist, magtortwist, Mtcrit; - double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; double tortwist1, tortwist2, tortwist3; double shrmag,rsht; @@ -226,7 +229,6 @@ void PairGranular::compute(int eflag, int vflag) rsq = delx*delx + dely*dely + delz*delz; radj = radius[j]; radsum = radi + radj; - untouchflag = (rsq >= radsum*radsum); E = normal_coeffs[itype][jtype][0]; Reff = radi*radj/(radi+radj); @@ -236,7 +238,10 @@ void PairGranular::compute(int eflag, int vflag) a = cbrt(9.0*M_PI*coh*R2/(4*E)); delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); dist_pulloff = radsum+delta_pulloff; - untouchflag = (rsq >= (dist_pulloff)*(dist_pulloff)); + untouchflag = (rsq >= dist_pulloff*dist_pulloff); + } + else{ + untouchflag = (rsq >= radsum*radsum); } if (untouchflag){ @@ -247,8 +252,6 @@ void PairGranular::compute(int eflag, int vflag) } else{ r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; nx = delx*rinv; ny = dely*rinv; @@ -301,26 +304,21 @@ void PairGranular::compute(int eflag, int vflag) knfac = FOURTHIRDS*E*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); } - - else if (normal[itype][jtype] != HOOKE){ //HERTZ, DMT - a = sqdR = sqrt(dR); - knfac = FOURTHIRDS*E*sqdR; + else{ + knfac = E; //Hooke Fne = knfac*delta; + if (normal[itype][jtype] != HOOKE) + Fne *= a; if (normal[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } - else{ //Hooke - a = sqdR = sqrt(dR); - knfac = FOURTHIRDS*E; - Fne = knfac*delta; - } //Consider restricting Hooke to only have 'velocity' as an option for damping? if (damping[itype][jtype] == VELOCITY){ damp_normal = normal_coeffs[itype][jtype][1]; } else if (damping[itype][jtype] == VISCOELASTIC){ - if (normal[itype][jtype] == HOOKE) sqdR = sqrt(dR); + if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); damp_normal = normal_coeffs[itype][jtype][1]*sqdR*meff; } else if (damping[itype][jtype] == TSUJI){ @@ -356,21 +354,20 @@ void PairGranular::compute(int eflag, int vflag) if (history_flag){ touch[jj] = 1; history = &allhistory[size_history*jj]; - Fcrit = fabs(Fne); - if (normal[itype][jtype] == JKR){ - Fpulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*Fpulloff); - } + } + + Fcrit = fabs(Fne); + if (normal[itype][jtype] == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*F_pulloff); } //------------------------------ //Tangential forces //------------------------------ - if (tangential[itype][jtype] == MINDLIN){ - k_tangential = tangential_coeffs[itype][jtype][0]*a; - } - else{ - k_tangential = tangential_coeffs[itype][jtype][0]; + k_tangential = tangential_coeffs[itype][jtype][0]; + if (normal[itype][jtype] != HOOKE){ + k_tangential *= a; } damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; @@ -420,18 +417,18 @@ void PairGranular::compute(int eflag, int vflag) } else{ //Classic pair gran/hooke (no history) fs = meff*damp_tangential*vrel; - if (vrel != 0.0) ft = MIN(fn,fs) / vrel; - else ft = 0.0; - fs1 = -ft*vtr1; - fs2 = -ft*vtr2; - fs3 = -ft*vtr3; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; } //**************************************** // Rolling resistance //**************************************** - if (rolling[itype][jtype] != NONE){ + if (roll[itype][jtype] != NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -439,24 +436,26 @@ void PairGranular::compute(int eflag, int vflag) // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) // This is different from the Marshall papers, which use the Bagi/Kuhn formulation // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; else vrlmaginv = 0.0; - if (rolling_history){ + if (roll_history){ + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + // Rolling displacement rollmag = sqrt(history[rhist0]*history[rhist0] + history[rhist1]*history[rhist1] + history[rhist2]*history[rhist2]); + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - int rhist0 = rolling_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - if (historyupdate) { + if (historyupdate){ if (fabs(rolldotn) < EPSILON) rolldotn = 0; if (rolldotn > 0){ //Rotate into tangential plane scalefac = rollmag/(rollmag - rolldotn); @@ -472,36 +471,37 @@ void PairGranular::compute(int eflag, int vflag) history[rhist1] += vrl2*dt; history[rhist2] += vrl3*dt; } - } - kR = rolling_coeffs[itype][jtype][0]; - eta_R = rolling_coeffs[itype][jtype][1]; - fr1 = -kR*history[rhist0] - eta_R*vrl1; - fr2 = -kR*history[rhist1] - eta_R*vrl2; - fr3 = -kR*history[rhist2] - eta_R*vrl3; - // rescale frictional displacements and forces if needed - Frcrit = rolling_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - history[rhist1] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - history[rhist2] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; } - } - else{ // - fr = meff*rolling_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(fn,fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; } //**************************************** @@ -509,31 +509,31 @@ void PairGranular::compute(int eflag, int vflag) //**************************************** if (twist[itype][jtype] != NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist[itype][jtype] == MARSHALL){ + if (twist[itype][jtype] == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a; } else{ - k_twist = twisting_coeffs[itype][jtype][0]; - damp_twist = twisting_coeffs[itype][jtype][1]; - mu_twist = twisting_coeffs[itype][jtype][2]; + k_twist = twist_coeffs[itype][jtype][0]; + damp_twist = twist_coeffs[itype][jtype][1]; + mu_twist = twist_coeffs[itype][jtype][2]; } - if (twist_history){ - history[twist_history_index] += magtwist*dt; - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 + if (twist_history){ + history[twist_history_index] += magtwist*dt; + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; } } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; - } - // Apply forces & torques fx = nx*Fntot + fs1; @@ -562,10 +562,10 @@ void PairGranular::compute(int eflag, int vflag) torque[i][2] += tortwist3; } - if (rolling[itype][jtype] != NONE){ - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); + if (roll[itype][jtype] != NONE){ + torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = Reff*(nz*fr1 - nx*fr3); + torroll3 = Reff*(nx*fr2 - ny*fr1); torque[i][0] += torroll1; torque[i][1] += torroll2; @@ -581,12 +581,12 @@ void PairGranular::compute(int eflag, int vflag) torque[j][1] -= radj*tor2; torque[j][2] -= radj*tor3; - if (rolling[itype][jtype] != NONE){ + if (roll[itype][jtype] != NONE){ torque[j][0] -= tortwist1; torque[j][1] -= tortwist2; torque[j][2] -= tortwist3; } - if (rolling[itype][jtype] != NONE){ + if (roll[itype][jtype] != NONE){ torque[j][0] -= torroll1; torque[j][1] -= torroll2; torque[j][2] -= torroll3; @@ -618,14 +618,14 @@ void PairGranular::allocate() memory->create(cut,n+1,n+1,"pair:cut"); memory->create(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); - memory->create(rolling_coeffs,n+1,n+1,3,"pair:rolling_coeffs"); - memory->create(twisting_coeffs,n+1,n+1,3,"pair:twisting_coeffs"); + memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); + memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); memory->create(normal,n+1,n+1,"pair:normal"); memory->create(damping,n+1,n+1,"pair:damping"); memory->create(tangential,n+1,n+1,"pair:tangential"); - memory->create(rolling,n+1,n+1,"pair:rolling"); - memory->create(twisting,n+1,n+1,"pair:twisting"); + memory->create(roll,n+1,n+1,"pair:roll"); + memory->create(twist,n+1,n+1,"pair:twist"); onerad_dynamic = new double[n+1]; onerad_frozen = new double[n+1]; @@ -647,9 +647,9 @@ void PairGranular::settings(int narg, char **arg) damping_global = VISCOELASTIC; coeff_types = STIFFNESS; tangential_global = -1; //Needs to be explicitly set, since it requires parameters - rolling_global = NONE; - twisting_global = NONE; - tangential_history = rolling_history = twisting_history = 0; + roll_global = NONE; + twist_global = NONE; + tangential_history = roll_history = twist_history = 0; if (strcmp(arg[iarg], "material") == 0){ coeff_types = MATERIAL; @@ -668,11 +668,11 @@ void PairGranular::settings(int narg, char **arg) else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; if (coeff_types == MATERIAL) num_coeffs += 1; - if (iarg + offset >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); normal_global = HERTZ; memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E - if (coeff_types == STIFFNESS) normal_coeffs_global[0] /= FOURTHIRDS; + if (coeff_types == MATERIAL) normal_coeffs_global[0] *= FOURTHIRDS; normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping if (coeff_types == MATERIAL) normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') iarg += num_coeffs+1; @@ -682,7 +682,7 @@ void PairGranular::settings(int narg, char **arg) if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); normal_global = DMT; memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //4/3 E normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion @@ -727,58 +727,63 @@ void PairGranular::settings(int narg, char **arg) tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } - else if (strstr(arg[iarg], "rolling") != NULL){ + else if (strstr(arg[iarg], "roll") != NULL){ if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); if (strstr(arg[iarg], "nohistory") != NULL){ - rolling_global = ROLLING_NOHISTORY; + roll_global = ROLL_NOHISTORY; } else{ - rolling_global = ROLLING_SDS; - rolling_history = 1; + roll_global = ROLL_SDS; + roll_history = 1; } - memory->create(rolling_coeffs_global, 3, "pair:rolling_coeffs_global"); - rolling_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt - rolling_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - rolling_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + memory->create(roll_coeffs_global, 3, "pair:roll_coeffs_global"); + roll_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt + roll_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + roll_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } - else if (strstr(arg[iarg], "twisting") != NULL){ + else if (strstr(arg[iarg], "twist") != NULL){ if (strstr(arg[iarg], "marshall") != NULL){ - twisting_global = TWISTING_MARSHALL; - twisting_history = 1; - memory->create(twisting_coeffs_global, 3, "pair:twisting_coeffs_global"); //To be filled later + twist_global = TWIST_MARSHALL; + twist_history = 1; + memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later } else{ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twisting model"); + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); if (strstr(arg[iarg], "nohistory") != NULL){ - twisting_global = TWISTING_NOHISTORY; + twist_global = TWIST_NOHISTORY; } else{ - twisting_global = TWISTING_SDS; - twisting_history = 1; + twist_global = TWIST_SDS; + twist_history = 1; } - memory->create(twisting_coeffs_global, 3, "pair:twisting_coeffs_global"); - twisting_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt - twisting_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - twisting_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); + twist_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt + twist_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + twist_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } } } - //Set all i-i entrie, which may be replaced by pair coeff commands + //Set all i-i entries, which may be replaced by pair coeff commands //It may also make sense to consider removing all of the above, and only // having the option for pair_coeff to set the parameters, similar to most LAMMPS pair styles - // The reason for the current setup is to keep true to existing pair gran/hooke etc. syntax, + // The reason for the current setup is to remain true to existing pair gran/hooke etc. syntax, // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. + + + //Other option is to have two pair styles, e.g. pair gran and pair gran/multi, + // where gran/multi allows per-type coefficients, pair gran does not (would also + // allow minor speed-up for pair gran) allocate(); double damp; for (int i = 1; i <= atom->ntypes; i++){ normal[i][i] = normal_global; damping[i][i] = damping_global; tangential[i][i] = tangential_global; - rolling[i][i] = rolling_global; - twisting[i][i] = twisting_global; + roll[i][i] = roll_global; + twist[i][i] = twist_global; if (damping_global == TSUJI){ double cor = normal_coeffs_global[1]; @@ -798,15 +803,15 @@ void PairGranular::settings(int narg, char **arg) for (int k = 0; k < 3; k++) tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; - rolling[i][i] = rolling_global; - if (rolling_global != NONE) + roll[i][i] = roll_global; + if (roll_global != NONE) for (int k = 0; k < 3; k++) - rolling_coeffs[i][i][k] = rolling_coeffs_global[k]; + roll_coeffs[i][i][k] = roll_coeffs_global[k]; - twisting[i][i] = twisting_global; - if (twisting_global != NONE) + twist[i][i] = twist_global; + if (twist_global != NONE) for (int k = 0; k < 3; k++) - twisting_coeffs[i][i][k] = twisting_coeffs_local[k]; + twist_coeffs[i][i][k] = twist_coeffs_global[k]; setflag[i][i] = 1; } @@ -823,16 +828,16 @@ void PairGranular::settings(int narg, char **arg) void PairGranular::coeff(int narg, char **arg) { - int normal_local, damping_local, tangential_local, rolling_local, twisting_local; + int normal_local, damping_local, tangential_local, roll_local, twist_local; double *normal_coeffs_local; double *tangential_coeffs_local; - double *rolling_coeffs_local; - double *twisting_coeffs_local; + double *roll_coeffs_local; + double *twist_coeffs_local; normal_coeffs_local = new double[4]; tangential_coeffs_local = new double[4]; - rolling_coeffs_local = new double[4]; - twisting_coeffs_local = new double[4]; + roll_coeffs_local = new double[4]; + twist_coeffs_local = new double[4]; if (narg < 2) error->all(FLERR,"Incorrect args for pair coefficients"); @@ -914,35 +919,35 @@ void PairGranular::coeff(int narg, char **arg) else if (strstr(arg[iarg], "rolling") != NULL){ if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); if (strstr(arg[iarg], "nohistory") != NULL){ - rolling_local = ROLLING_NOHISTORY; + roll_local = ROLL_NOHISTORY; } else{ - rolling_local = ROLLING_SDS; - rolling_history = 1; + roll_local = ROLL_SDS; + roll_history = 1; } - rolling_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt - rolling_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - rolling_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt + roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } - else if (strstr(arg[iarg], "twisting") != NULL){ + else if (strstr(arg[iarg], "twist") != NULL){ if (strstr(arg[iarg], "marshall") != NULL){ - twisting_local = TWISTING_MARSHALL; - twisting_history = 1; + twist_local = TWIST_MARSHALL; + twist_history = 1; } else{ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twisting model"); + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); if (strstr(arg[iarg], "nohistory") != NULL){ - twisting_local = TWISTING_NOHISTORY; + twist_local = TWIST_NOHISTORY; } else{ - twisting_local = TWISTING_SDS; - twisting_history = 1; + twist_local = TWIST_SDS; + twist_history = 1; size_history += 1; } - twisting_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt - twisting_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - twisting_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt + twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } } @@ -972,22 +977,27 @@ void PairGranular::coeff(int narg, char **arg) for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; - rolling[i][j] = rolling_local; - if (rolling_local != NONE) + roll[i][j] = roll_local; + if (roll_local != NONE) for (int k = 0; k < 3; k++) - rolling_coeffs[i][j][k] = rolling_coeffs_local[k]; + roll_coeffs[i][j][k] = roll_coeffs_local[k]; - twisting[i][j] = twisting_local; - if (twisting_local != NONE) + twist[i][j] = twist_local; + if (twist_local != NONE) for (int k = 0; k < 3; k++) - twisting_coeffs[i][j][k] = twisting_coeffs_local[k]; + twist_coeffs[i][j][k] = twist_coeffs_local[k]; setflag[i][j] = 1; - double cut_one; count++; } } + + delete[] normal_coeffs_local; + delete[] tangential_coeffs_local; + delete[] roll_coeffs_local; + delete[] twist_coeffs_local; + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -1007,22 +1017,22 @@ void PairGranular::init_style() error->all(FLERR,"Pair granular requires ghost atoms store velocity"); // Determine whether we need a granular neigh list, how large it needs to be - history_flag = tangential_history || rolling_history || twisting_history; - size_history = 3*tangential_history + 3*rolling_history + twisting_history; + history_flag = tangential_history || roll_history || twist_history; + size_history = 3*tangential_history + 3*roll_history + twist_history; - //Determine location of tangential/rolling/twisting histories in array - if (rolling_history){ - if (tangential_history) rolling_history_index = 3; - else rolling_history_index = 0; + //Determine location of tangential/roll/twist histories in array + if (roll_history){ + if (tangential_history) roll_history_index = 3; + else roll_history_index = 0; } - if (twisting_history){ + if (twist_history){ if (tangential_history){ - if (rolling_history) twisting_history_index = 6; - else twisting_history_index = 3; + if (roll_history) twist_history_index = 6; + else twist_history_index = 3; } else{ - if (rolling_history) twisting_history_index = 3; - else twisting_history_index = 0; + if (roll_history) twist_history_index = 3; + else twist_history_index = 0; } } @@ -1137,8 +1147,8 @@ double PairGranular::init_one(int i, int j) if ((normal[i] != normal[j]) || (damping[i] != damping[j]) || (tangential[i] != tangential[j]) || - (rolling[i] != rolling[j]) || - (twisting[i] != twisting[j])){ + (roll[i] != roll[j]) || + (twist[i] != twist[j])){ char str[512]; sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); @@ -1165,14 +1175,14 @@ double PairGranular::init_one(int i, int j) tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); } - if (rolling[i][i] != NONE){ + if (roll[i][i] != NONE){ for (int k = 0; k < 3; k++) - rolling_coeffs[i][j][k] = mix_geom(rolling_coeffs[i][i][k], rolling_coeffs[j][j][k]); + roll_coeffs[i][j][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } - if (twisting[i][i] != NONE){ + if (twist[i][i] != NONE){ for (int k = 0; k < 3; k++) - twisting_coeffs[i][j][k] = mix_geom(twisting_coeffs[i][i][k], twisting_coeffs[j][j][k]); + twist_coeffs[i][j][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } } @@ -1208,24 +1218,20 @@ double PairGranular::init_one(int i, int j) void PairGranular::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(&E[i][j],sizeof(double),1,fp); - fwrite(&G[i][j],sizeof(double),1,fp); - fwrite(&normaldamp[i][j],sizeof(int),1,fp); - fwrite(&rollingdamp[i][j],sizeof(int),1,fp); - fwrite(&alpha[i][j],sizeof(double),1,fp); - fwrite(&gamman[i][j],sizeof(double),1,fp); - fwrite(&muS[i][j],sizeof(double),1,fp); - fwrite(&Ecoh[i][j],sizeof(double),1,fp); - fwrite(&kR[i][j],sizeof(double),1,fp); - fwrite(&muR[i][j],sizeof(double),1,fp); - fwrite(&etaR[i][j],sizeof(double),1,fp); + fwrite(&normal[i][j],sizeof(int),1,fp); + fwrite(&damping[i][j],sizeof(int),1,fp); + fwrite(&tangential[i][j],sizeof(int),1,fp); + fwrite(&roll[i][j],sizeof(int),1,fp); + fwrite(&twist[i][j],sizeof(int),1,fp); + fwrite(&normal_coeffs[i][j],sizeof(double),4,fp); + fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); + fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); + fwrite(&twist_coeffs[i][j],sizeof(double),3,fp); fwrite(&cut[i][j],sizeof(double),1,fp); } } @@ -1238,9 +1244,7 @@ void PairGranular::write_restart(FILE *fp) void PairGranular::read_restart(FILE *fp) { - read_restart_settings(fp); allocate(); - int i,j; int me = comm->me; for (i = 1; i <= atom->ntypes; i++) { @@ -1249,56 +1253,32 @@ void PairGranular::read_restart(FILE *fp) MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world); if (setflag[i][j]) { if (me == 0) { - fread(&E[i][j],sizeof(double),1,fp); - fread(&G[i][j],sizeof(double),1,fp); - fread(&normaldamp[i][j],sizeof(int),1,fp); - fread(&rollingdamp[i][j],sizeof(int),1,fp); - fread(&alpha[i][j],sizeof(double),1,fp); - fread(&gamman[i][j],sizeof(double),1,fp); - fread(&muS[i][j],sizeof(double),1,fp); - fread(&Ecoh[i][j],sizeof(double),1,fp); - fread(&kR[i][j],sizeof(double),1,fp); - fread(&muR[i][j],sizeof(double),1,fp); - fread(&etaR[i][j],sizeof(double),1,fp); + fread(&normal[i][j],sizeof(int),1,fp); + fread(&damping[i][j],sizeof(int),1,fp); + fread(&tangential[i][j],sizeof(int),1,fp); + fread(&roll[i][j],sizeof(int),1,fp); + fread(&twist[i][j],sizeof(int),1,fp); + fread(&normal_coeffs[i][j],sizeof(double),4,fp); + fread(&tangential_coeffs[i][j],sizeof(double),3,fp); + fread(&roll_coeffs[i][j],sizeof(double),3,fp); + fread(&twist_coeffs[i][j],sizeof(double),3,fp); fread(&cut[i][j],sizeof(double),1,fp); } - MPI_Bcast(&E[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&G[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&normaldamp[i][j],1,MPI_INT,0,world); - MPI_Bcast(&rollingdamp[i][j],1,MPI_INT,0,world); - MPI_Bcast(&alpha[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&gamman[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&muS[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&Ecoh[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&kR[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&muR[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&etaR[i][j],1,MPI_DOUBLE,0,world); + MPI_Bcast(&normal[i][j],1,MPI_INT,0,world); + MPI_Bcast(&damping[i][j],1,MPI_INT,0,world); + MPI_Bcast(&tangential[i][j],1,MPI_INT,0,world); + MPI_Bcast(&roll[i][j],1,MPI_INT,0,world); + MPI_Bcast(&twist[i][j],1,MPI_INT,0,world); + MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); + MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&twist_coeffs[i][j],3,MPI_DOUBLE,0,world); MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); } } } } -/* ---------------------------------------------------------------------- - proc 0 writes to restart file - ------------------------------------------------------------------------- */ - -void PairGranular::write_restart_settings(FILE *fp) -{ - fwrite(&cut_global,sizeof(double),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts - ------------------------------------------------------------------------- */ - -void PairGranular::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_global,sizeof(double),1,fp); - } - MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); -} /* ---------------------------------------------------------------------- */ @@ -1312,40 +1292,76 @@ void PairGranular::reset_dt() double PairGranular::single(int i, int j, int itype, int jtype, double rsq, double factor_coul, double factor_lj, double &fforce) { - // feenableexcept(FE_INVALID | FE_OVERFLOW); double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double overlap, a; - double mi,mj,meff,damp,kn,kt; - double Fdamp,Fne,Fntot,Fscrit; - double eta_N,eta_T; double vtr1,vtr2,vtr3,vrel; - double fs1,fs2,fs3,fs; - double shrmag; - double F_C, delta_C, olapsq, olapcubed, sqrtterm, tmp, a0; - double keyterm, keyterm2, keyterm3, aovera0, foverFc; + + double knfac, damp_normal; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; + + //For JKR + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double delta, t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; + + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + + //Twisting + double k_twist, damp_twist, mu_twist; + double signtwist, magtwist, magtortwist, Mtcrit; + double tortwist1, tortwist2, tortwist3; + + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *history,*allhistory,**firsthistory; double *radius = atom->radius; radi = radius[i]; radj = radius[j]; radsum = radi + radj; + Reff = radi*radj/(radi+radj); - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/(radi+radj); - a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); - delta_C = 0.5*a0*a0*POW6ONE/R; - - int *touch = fix_history->firstflag[i]; - if ((rsq >= (radsum+delta_C)*(radsum+delta_C) )|| - (rsq >= radsum*radsum && touch[j])){ + bool untouchflag; + if (normal[itype][jtype] == JKR){ + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum+delta_pulloff; + untouchflag = (rsq >= dist_pulloff*dist_pulloff); + } + else{ + untouchflag = (rsq >= radsum*radsum); + } + + if (untouchflag){ fforce = 0.0; - svector[0] = svector[1] = svector[2] = svector[3] = 0.0; + for (int m = 0; m < single_extra; m++) svector[m] = 0.0; return 0.0; } + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + r = sqrt(rsq); + rinv = 1.0/r; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + // relative translational velocity double **v = atom->v; @@ -1574,11 +1590,11 @@ double PairGranular::mix_geom(double valii, double valjj) double PairGranular::pulloff_distance(double radius, int itype) { - double R, E, coh, a, delta_pulloff; + double E, coh, a, delta_pulloff; coh = normal_coeffs[itype][itype][3]; E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); - a = cbrt(9*M_PI*coh*R*R/(4*E)); - return a*a/R - 2*sqrt(M_PI*coh*a/E); + a = cbrt(9*M_PI*coh*radius*radius/(4*E)); + return a*a/radius - 2*sqrt(M_PI*coh*a/E); } diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 14cc02675b..449b4d8474 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -35,8 +35,6 @@ public: double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); void reset_dt(); virtual double single(int, int, int, int, double, double, double, double &); int pack_forward_comm(int, int *, double *, int, int *); @@ -70,26 +68,26 @@ private: int size_history; //Per-type models - int **normal, **damping, **tangential, **rolling, **twisting; + int **normal, **damping, **tangential, **roll, **twist; int normal_global, damping_global; - int tangential_global, rolling_global, twisting_global; + int tangential_global, roll_global, twist_global; int history_flag; - int tangential_history, rolling_history, twisting_history; + int tangential_history, roll_history, twist_history; int tangential_history_index; - int rolling_history_index; - int twisting_history_index; + int roll_history_index; + int twist_history_index; double *normal_coeffs_global; double *tangential_coeffs_global; - double *rolling_coeffs_global; - double *twisting_coeffs_global; + double *roll_coeffs_global; + double *twist_coeffs_global; double ***normal_coeffs; double ***tangential_coeffs; - double ***rolling_coeffs; - double ***twisting_coeffs; + double ***roll_coeffs; + double ***twist_coeffs; double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); -- GitLab From faa716e348d081e989189afc7888f94cf5f1835f Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Mon, 7 Jan 2019 16:27:04 -0700 Subject: [PATCH 0083/1243] Added PairGranular::single method --- src/GRANULAR/pair_granular.cpp | 321 ++++++++++++++++++++++++--------- src/GRANULAR/pair_granular.h | 1 - 2 files changed, 233 insertions(+), 89 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 93f8d514b7..72b5f7867e 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -61,11 +61,10 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) { single_enable = 1; no_virial_fdotr_compute = 1; - use_history = 1; fix_history = NULL; - single_extra = 10; - svector = new double[10]; + single_extra = 9; + svector = new double[single_extra]; neighprev = 0; @@ -83,6 +82,7 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) comm_forward = 1; + use_history = 0; beyond_contact = 0; roll_history_index = twist_history_index = 0; tangential_history_index = -1; @@ -351,7 +351,7 @@ void PairGranular::compute(int eflag, int vflag) vrel = sqrt(vrel); // If any history is needed: - if (history_flag){ + if (use_history){ touch[jj] = 1; history = &allhistory[size_history*jj]; } @@ -520,7 +520,9 @@ void PairGranular::compute(int eflag, int vflag) mu_twist = twist_coeffs[itype][jtype][2]; } if (twist_history){ - history[twist_history_index] += magtwist*dt; + if (historyupdate){ + history[twist_history_index] += magtwist*dt; + } magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) signtwist = (magtwist > 0) - (magtwist < 0); Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) @@ -1017,7 +1019,7 @@ void PairGranular::init_style() error->all(FLERR,"Pair granular requires ghost atoms store velocity"); // Determine whether we need a granular neigh list, how large it needs to be - history_flag = tangential_history || roll_history || twist_history; + use_history = tangential_history || roll_history || twist_history; size_history = 3*tangential_history + 3*roll_history + twist_history; //Determine location of tangential/roll/twist histories in array @@ -1038,14 +1040,14 @@ void PairGranular::init_style() int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->size = 1; - if (history_flag) neighbor->requests[irequest]->history = 1; + if (use_history) neighbor->requests[irequest]->history = 1; dt = update->dt; // if history is stored: // if first init, create Fix needed for storing history - if (history_flag && fix_history == NULL) { + if (use_history && fix_history == NULL) { char dnumstr[16]; sprintf(dnumstr,"%d",size_history); char **fixarg = new char*[4]; @@ -1294,8 +1296,11 @@ double PairGranular::single(int i, int j, int itype, int jtype, { double radi,radj,radsum; double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; + double dR, dR2, sqdR; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; double knfac, damp_normal; double k_tangential, damp_tangential; @@ -1307,8 +1312,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, double delta, t0, t1, t2, t3, t4, t5, t6; double sqrt1, sqrt2, sqrt3, sqrt4; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; //Rolling double k_roll, damp_roll; @@ -1371,21 +1374,27 @@ double PairGranular::single(int i, int j, int itype, int jtype, // normal component - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - vnnr = vr1*nx + vr2*ny + vr3*nz; vn1 = nx*vnnr; vn2 = ny*vnnr; vn3 = nz*vnnr; + double *rmass = atom->rmass; + int *mask = atom->mask; + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + // tangential component vt1 = vr1 - vn1; @@ -1419,86 +1428,223 @@ double PairGranular::single(int i, int j, int itype, int jtype, if (mask[i] & freeze_group_bit) meff = mj; if (mask[j] & freeze_group_bit) meff = mi; + delta = radsum - r; + dR = delta*Reff; + if (normal[itype][jtype] == JKR){ + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = FOURTHIRDS*E*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + else{ + knfac = E; //Hooke + Fne = knfac*delta; + if (normal[itype][jtype] != HOOKE) + Fne *= a; + if (normal[itype][jtype] == DMT) + Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; + } - // normal force = JKR - F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; - overlap = radsum - r; - olapsq = overlap*overlap; - olapcubed = olapsq*olapsq; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,ONETHIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = POW6TWO * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 - a = aovera0*a0; - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) + //Consider restricting Hooke to only have 'velocity' as an option for damping? + if (damping[itype][jtype] == VELOCITY){ + damp_normal = normal_coeffs[itype][jtype][1]; + } + else if (damping[itype][jtype] == VISCOELASTIC){ + if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*sqdR*meff; + } + else if (damping[itype][jtype] == TSUJI){ + damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); + } - Fne = F_C*foverFc; + Fdamp = -damp_normal*vnnr; - //Damping - kn = 4.0/3.0*E[itype][jtype]*a; - if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); + Fntot = Fne + Fdamp; - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 + int jnum = list->numneigh[i]; + int *jlist = list->firstneigh[i]; + double *allhistory, *history; + + if (use_history){ + allhistory = fix_history->firstvalue[i]; + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + history = &allhistory[size_history*neighprev]; + } - Fntot = Fne + Fdamp; + //**************************************** + //Tangential force, including history effects + //**************************************** - // relative velocities + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + // relative rotational velocity + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities vtr1 = vt1 - (nz*wr2-ny*wr3); vtr2 = vt2 - (nx*wr3-nz*wr1); vtr3 = vt3 - (ny*wr1-nx*wr2); vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); - // history effects - // neighprev = index of found neigh on previous call - // search entire jnum list of neighbors of I for neighbor J - // start from neighprev, since will typically be next neighbor - // reset neighprev to 0 as necessary - - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allhistory = fix_history->firstvalue[i]; - - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; + Fcrit = fabs(Fne); + if (normal[itype][jtype] == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*F_pulloff); } - double *history = &allhistory[3*neighprev]; - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - - // tangential forces = history + tangential velocity damping - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; - fs1 = -kt*history[0] - eta_T*vtr1; - fs2 = -kt*history[1] - eta_T*vtr2; - fs3 = -kt*history[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - Fscrit= muS[itype][jtype] * fabs(Fne + 2*F_C); - - if (fs > Fscrit) { - if (shrmag != 0.0) { - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - fs *= Fscrit/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; + //------------------------------ + //Tangential forces + //------------------------------ + k_tangential = tangential_coeffs[itype][jtype][0]; + if (normal[itype][jtype] != HOOKE){ + k_tangential *= a; + } + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + + if (tangential_history[itype][jtype]){ + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // tangential forces = history + tangential velocity damping + fs1 = -k_tangential*history[0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[2] - damp_tangential*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; } - // set all forces and return no energy + //**************************************** + // Rolling resistance + //**************************************** + + if (roll[itype][jtype] != NONE){ + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + if (roll_history){ + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; + } + } - fforce = Fntot; + //**************************************** + // Twisting torque, including history effects + //**************************************** + if (twist[itype][jtype] != NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (twist[itype][jtype] == TWIST_MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a; + } + else{ + k_twist = twist_coeffs[itype][jtype][0]; + damp_twist = twist_coeffs[itype][jtype][1]; + mu_twist = twist_coeffs[itype][jtype][2]; + } + if (twist_history){ + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; + } + } // set single_extra quantities @@ -1506,12 +1652,11 @@ double PairGranular::single(int i, int j, int itype, int jtype, svector[1] = fs2; svector[2] = fs3; svector[3] = fs; - svector[4] = vn1; - svector[5] = vn2; - svector[6] = vn3; - svector[7] = vt1; - svector[8] = vt2; - svector[9] = vt3; + svector[4] = fr1; + svector[5] = fr2; + svector[6] = fr3; + svector[7] = fr; + svector[8] = magtortwist; return 0.0; } diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 449b4d8474..957a16af8d 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -73,7 +73,6 @@ private: int normal_global, damping_global; int tangential_global, roll_global, twist_global; - int history_flag; int tangential_history, roll_history, twist_history; int tangential_history_index; int roll_history_index; -- GitLab From 7a2d326103b111c6282e128d2c617a4af461237b Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 8 Jan 2019 09:19:49 -0700 Subject: [PATCH 0084/1243] Commit JT 010819 - commit before co --- examples/SPIN/cobalt_hcp/in.spin.cobalt_hcp | 10 +- examples/SPIN/iron/in.spin.iron | 8 +- examples/SPIN/pppm_spin/in.spin.cut_comp | 26 +----- .../SPIN/pppm_spin/in.spin.spin_dipolar_cut | 26 +++--- src/KSPACE/ewald_dipole.cpp | 2 - src/KSPACE/ewald_dipole.h | 1 - src/SPIN/pair_spin_dipolar_long.cpp | 91 +++++++++++-------- 7 files changed, 80 insertions(+), 84 deletions(-) diff --git a/examples/SPIN/cobalt_hcp/in.spin.cobalt_hcp b/examples/SPIN/cobalt_hcp/in.spin.cobalt_hcp index 35aa1df86c..0efa52435d 100644 --- a/examples/SPIN/cobalt_hcp/in.spin.cobalt_hcp +++ b/examples/SPIN/cobalt_hcp/in.spin.cobalt_hcp @@ -25,16 +25,18 @@ velocity all create 100 4928459 rot yes dist gaussian #pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/neel 4.0 pair_style hybrid/overlay eam/alloy spin/exchange 4.0 -pair_coeff * * eam/alloy Co_PurjaPun_2012.eam.alloy Co -pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +pair_coeff * * eam/alloy ../examples/SPIN/cobalt_hcp/Co_PurjaPun_2012.eam.alloy Co +#pair_coeff * * eam/alloy Co_PurjaPun_2012.eam.alloy Co +pair_coeff * * spin/exchange exchange 4.0 -0.3593 1.135028015e-05 1.064568567 #pair_coeff * * spin/neel neel 4.0 0.0048 0.234 1.168 2.6905 0.705 0.652 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 -fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 -fix 2 all langevin/spin 0.0 0.0 21 +fix 1 all precession/spin anisotropy 0.01 0.0 0.0 1.0 +#fix 2 all langevin/spin 0.0 0.0 21 +fix 2 all langevin/spin 0.0 0.1 21 fix 3 all nve/spin lattice yes timestep 0.0001 diff --git a/examples/SPIN/iron/in.spin.iron b/examples/SPIN/iron/in.spin.iron index c2d5082cb6..dab1616e70 100644 --- a/examples/SPIN/iron/in.spin.iron +++ b/examples/SPIN/iron/in.spin.iron @@ -19,11 +19,13 @@ create_atoms 1 box mass 1 55.845 -set group all spin/random 31 2.2 +#set group all spin/random 31 2.2 +set group all spin 2.2 0.0 0.0 1.0 velocity all create 100 4928459 rot yes dist gaussian pair_style hybrid/overlay eam/alloy spin/exchange 3.5 -pair_coeff * * eam/alloy Fe_Mishin2006.eam.alloy Fe +#pair_coeff * * eam/alloy Fe_Mishin2006.eam.alloy Fe +pair_coeff * * eam/alloy ../examples/SPIN/iron/Fe_Mishin2006.eam.alloy Fe pair_coeff * * spin/exchange exchange 3.4 0.02726 0.2171 1.841 neighbor 0.1 bin @@ -53,4 +55,4 @@ thermo 50 compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] -run 50000 +run 50 diff --git a/examples/SPIN/pppm_spin/in.spin.cut_comp b/examples/SPIN/pppm_spin/in.spin.cut_comp index 3d01c56878..373c485c94 100644 --- a/examples/SPIN/pppm_spin/in.spin.cut_comp +++ b/examples/SPIN/pppm_spin/in.spin.cut_comp @@ -29,12 +29,12 @@ neigh_modify delay 0 #neigh_modify every 1 delay 10 check yes page 100000000 one 10000000 #kspace_style pppm/dipole/spin 1.0e-4 -kspace_style ewald/dipole/spin 1.0e-4 -kspace_modify compute yes +#kspace_style ewald/dipole/spin 1.0e-4 +#kspace_modify compute yes #kspace_modify compute yes gewald 0.1 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 -fix 2 all langevin/spin 0.0 0.1 21 +fix 2 all langevin/spin 0.0 0.0 21 #fix 3 all nve/spin lattice yes fix 3 all nve/spin lattice no @@ -44,29 +44,9 @@ thermo_style custom step temp pe ke etotal press thermo_modify format float %20.16g thermo 50 -#compute peratom all pe/atom -#compute pe all reduce sum c_peratom -#thermo_style custom step temp pe c_pe - -#compute peratom2 all stress/atom -#compute peratom2 all stress/atom NULL -#compute p all reduce sum c_peratom2[1] c_peratom2[2] c_peratom2[3] c_peratom2[4] c_peratom2[5] c_peratom2[6] -#variable press equal -(c_p[1]+c_p[2]+c_p[3])/(3*vol) -#variable pxx equal -c_p[1]/vol -#variable pyy equal -c_p[2]/vol -#variable pzz equal -c_p[3]/vol -#variable pxy equal -c_p[4]/vol -#variable pxz equal -c_p[5]/vol -#variable pyz equal -c_p[6]/vol -#thermo_style custom step temp etotal pe c_pe press v_press pxx v_pxx pyy v_pyy pzz v_pzz pxy v_pxy pxz v_pxz pyz v_pyz -#thermo_style custom step etotal pe press v_press v_pxx v_pyy v_pzz v_pxy v_pxz v_pyz -#thermo_style custom step temp etotal press v_press - compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 50 all custom 1 dump.equil id type x y z c_outsp[1] c_outsp[2] c_outsp[3] #c_outsp[5] c_outsp[6] c_outsp[7] #dump_modify 1 format line "%d %d %20.15g %20.15g %20.15g %20.15g %20.15g %20.15g" scale yes -#pair_modify compute no - run 10000 diff --git a/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut b/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut index b265c4413e..a3ca4288fc 100644 --- a/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut +++ b/examples/SPIN/pppm_spin/in.spin.spin_dipolar_cut @@ -21,16 +21,15 @@ mass 1 58.93 set group all spin/random 31 1.72 #set group all spin 1.72 0.0 0.0 1.0 -#velocity all create 100 4928459 rot yes dist gaussian +velocity all create 100 4928459 rot yes dist gaussian -#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/long 8.0 -#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/cut 8.0 -pair_style spin/dipolar/cut 8.0 -#pair_style hybrid/overlay eam/alloy spin/exchange 4.0 -#pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co -#pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 -pair_coeff * * long 8.0 -#pair_coeff * * spin/long long 8.0 +pair_style hybrid/overlay eam/alloy spin/exchange 4.0 spin/dipolar/cut 8.0 +#pair_style hybrid/overlay eam/alloy spin/dipolar/cut 8.0 +pair_coeff * * eam/alloy ../examples/SPIN/pppm_spin/Co_PurjaPun_2012.eam.alloy Co +pair_coeff * * spin/exchange exchange 4.0 0.3593 1.135028015e-05 1.064568567 +pair_coeff * * spin/dipolar/cut long 8.0 +#pair_style spin/dipolar/cut 8.0 +#pair_coeff * * long 8.0 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 @@ -38,8 +37,8 @@ neigh_modify every 10 check yes delay 20 #fix 1 all precession/spin zeeman 1.0 0.0 0.0 1.0 fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 fix 2 all langevin/spin 0.0 0.0 21 -#fix 3 all nve/spin lattice yes -fix 3 all nve/spin lattice no +fix 3 all nve/spin lattice yes +#fix 3 all nve/spin lattice no timestep 0.0001 @@ -55,10 +54,11 @@ variable emag equal c_out_mag[5] variable tmag equal c_out_mag[6] thermo_style custom step time v_magnorm v_emag temp etotal +thermo_modify format float %20.16g thermo 10 compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 100 all custom 1 dump_cobalt_hcp.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] -#run 20000 -run 10 +run 20000 +#run 10 diff --git a/src/KSPACE/ewald_dipole.cpp b/src/KSPACE/ewald_dipole.cpp index 0cd5c95a9b..ebe17c82dd 100644 --- a/src/KSPACE/ewald_dipole.cpp +++ b/src/KSPACE/ewald_dipole.cpp @@ -561,8 +561,6 @@ void EwaldDipole::eik_dot_r() // loop on different k-directions // loop on n kpoints and nlocal atoms - // store (n x nlocal) tab. of values of (mu_i dot k) - // store n values of sum_j[ (mu_j dot k) exp(-k dot r_j) ] // (k,0,0), (0,l,0), (0,0,m) diff --git a/src/KSPACE/ewald_dipole.h b/src/KSPACE/ewald_dipole.h index 77c0af11c2..09a2896b56 100644 --- a/src/KSPACE/ewald_dipole.h +++ b/src/KSPACE/ewald_dipole.h @@ -34,7 +34,6 @@ class EwaldDipole : public Ewald { protected: double musum,musqsum,mu2; - //double **muk; // mu_i dot k double **tk; // field for torque double **vc; // virial per k diff --git a/src/SPIN/pair_spin_dipolar_long.cpp b/src/SPIN/pair_spin_dipolar_long.cpp index 140b92700c..ef79717f63 100644 --- a/src/SPIN/pair_spin_dipolar_long.cpp +++ b/src/SPIN/pair_spin_dipolar_long.cpp @@ -181,10 +181,14 @@ void PairSpinDipolarLong::init_style() // insure use of KSpace long-range solver, set g_ewald - if (force->kspace == NULL) - error->all(FLERR,"Pair style requires a KSpace style"); + //if (force->kspace == NULL) + // error->all(FLERR,"Pair style requires a KSpace style"); + + //g_ewald = force->kspace->g_ewald; + + // test case + g_ewald = 0.1; - g_ewald = force->kspace->g_ewald; } @@ -233,10 +237,11 @@ void PairSpinDipolarLong::compute(int eflag, int vflag) int i,j,ii,jj,inum,jnum,itype,jtype; double r,rinv,r2inv,rsq; double grij,expm2,t,erfc; - double bij[4]; double evdwl,ecoul; - double xi[3],rij[3]; - double spi[4],spj[4],fi[3],fmi[3]; + double bij[4]; + double xi[3],rij[3],eij[3]; + double spi[4],spj[4]; + double fi[3],fmi[3]; double local_cut2; double pre1,pre2,pre3; int *ilist,*jlist,*numneigh,**firstneigh; @@ -298,12 +303,16 @@ void PairSpinDipolarLong::compute(int eflag, int vflag) rij[1] = x[j][1] - xi[1]; rij[2] = x[j][2] - xi[2]; rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + rinv = 1.0/sqrt(rsq); + eij[0] = rij[0]*rinv; + eij[1] = rij[1]*rinv; + eij[2] = rij[2]*rinv; local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; if (rsq < local_cut2) { r2inv = 1.0/rsq; - rinv = sqrt(r2inv); + //rinv = sqrt(r2inv); r = sqrt(rsq); grij = g_ewald * r; @@ -316,18 +325,20 @@ void PairSpinDipolarLong::compute(int eflag, int vflag) bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; - compute_long(i,j,rij,bij,fmi,spi,spj); - compute_long_mech(i,j,rij,bij,fmi,spi,spj); + compute_long(i,j,eij,bij,fmi,spi,spj); + compute_long_mech(i,j,eij,bij,fmi,spi,spj); + //compute_long(i,j,rij,bij,fmi,spi,spj); + //compute_long_mech(i,j,rij,bij,fmi,spi,spj); } // force accumulation - f[i][0] += fi[0] * mub2mu0; - f[i][1] += fi[1] * mub2mu0; - f[i][2] += fi[2] * mub2mu0; - fm[i][0] += fmi[0] * mub2mu0hbinv; - fm[i][1] += fmi[1] * mub2mu0hbinv; - fm[i][2] += fmi[2] * mub2mu0hbinv; + f[i][0] += fi[0]; + f[i][1] += fi[1]; + f[i][2] += fi[2]; + fm[i][0] += fmi[0]; + fm[i][1] += fmi[1]; + fm[i][2] += fmi[2]; if (newton_pair || j < nlocal) { f[j][0] -= fi[0]; @@ -360,7 +371,8 @@ void PairSpinDipolarLong::compute_single_pair(int ii, double fmi[3]) int i,j,jj,jnum,itype,jtype; double r,rinv,r2inv,rsq; double grij,expm2,t,erfc; - double bij[4],xi[3],rij[3]; + double bij[4]; + double xi[3],rij[3],eij[3]; double spi[4],spj[4]; double local_cut2; double pre1,pre2,pre3; @@ -411,12 +423,16 @@ void PairSpinDipolarLong::compute_single_pair(int ii, double fmi[3]) rij[1] = x[j][1] - xi[1]; rij[2] = x[j][2] - xi[2]; rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + rinv = 1.0/sqrt(rsq); + eij[0] = rij[0]*rinv; + eij[1] = rij[1]*rinv; + eij[2] = rij[2]*rinv; local_cut2 = cut_spin_long[itype][jtype]*cut_spin_long[itype][jtype]; if (rsq < local_cut2) { r2inv = 1.0/rsq; - rinv = sqrt(r2inv); + //rinv = sqrt(r2inv); r = sqrt(rsq); grij = g_ewald * r; @@ -429,7 +445,7 @@ void PairSpinDipolarLong::compute_single_pair(int ii, double fmi[3]) bij[2] = (3.0*bij[1] + pre2*expm2) * r2inv; bij[3] = (5.0*bij[2] + pre3*expm2) * r2inv; - compute_long(i,j,rij,bij,fmi,spi,spj); + compute_long(i,j,eij,bij,fmi,spi,spj); } } @@ -447,21 +463,22 @@ void PairSpinDipolarLong::compute_single_pair(int ii, double fmi[3]) compute dipolar interaction between spins i and j ------------------------------------------------------------------------- */ -void PairSpinDipolarLong::compute_long(int i, int j, double rij[3], +void PairSpinDipolarLong::compute_long(int i, int j, double eij[3], double bij[4], double fmi[3], double spi[4], double spj[4]) { - double sjdotr; + double sjeij,pre; double b1,b2,gigj; gigj = spi[3] * spj[3]; - sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + pre = gigj*mub2mu0hbinv; + sjeij = spj[0]*eij[0] + spj[1]*eij[1] + spj[2]*eij[2]; b1 = bij[1]; b2 = bij[2]; - fmi[0] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[0] - b1 * spj[0]); - fmi[1] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[1] - b1 * spj[1]); - fmi[2] += mub2mu0hbinv * gigj * (b2 * sjdotr *rij[2] - b1 * spj[2]); + fmi[0] += pre * (b2 * sjeij * eij[0] - b1 * spj[0]); + fmi[1] += pre * (b2 * sjeij * eij[1] - b1 * spj[1]); + fmi[2] += pre * (b2 * sjeij * eij[2] - b1 * spj[2]); } /* ---------------------------------------------------------------------- @@ -469,29 +486,27 @@ void PairSpinDipolarLong::compute_long(int i, int j, double rij[3], atom i and atom j ------------------------------------------------------------------------- */ -void PairSpinDipolarLong::compute_long_mech(int i, int j, double rij[3], +void PairSpinDipolarLong::compute_long_mech(int i, int j, double eij[3], double bij[4], double fi[3], double spi[3], double spj[3]) { - double sdots,sidotr,sjdotr,b2,b3; - double g1,g2,g1b2_g2b3,gigj; + double sisj,sieij,sjeij,b2,b3; + double g1,g2,g1b2_g2b3,gigj,pre; gigj = spi[3] * spj[3]; - sdots = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; - sidotr = spi[0]*rij[0] + spi[1]*rij[1] + spi[2]*rij[2]; - sjdotr = spj[0]*rij[0] + spj[1]*rij[1] + spj[2]*rij[2]; + pre = gigj*mub2mu0; + sisj = spi[0]*spj[0] + spi[1]*spj[1] + spi[2]*spj[2]; + sieij = spi[0]*eij[0] + spi[1]*eij[1] + spi[2]*eij[2]; + sjeij = spj[0]*eij[0] + spj[1]*eij[1] + spj[2]*eij[2]; b2 = bij[2]; b3 = bij[3]; - g1 = sdots; - g2 = -sidotr*sjdotr; + g1 = sisj; + g2 = -sieij*sjeij; g1b2_g2b3 = g1*b2 + g2*b3; - fi[0] += gigj * (rij[0] * g1b2_g2b3 + - b2 * (sjdotr*spi[0] + sidotr*spj[0])); - fi[1] += gigj * (rij[1] * g1b2_g2b3 + - b2 * (sjdotr*spi[1] + sidotr*spj[1])); - fi[2] += gigj * (rij[2] * g1b2_g2b3 + - b2 * (sjdotr*spi[2] + sidotr*spj[2])); + fi[0] += pre * (eij[0] * g1b2_g2b3 + b2 * (sjeij*spi[0] + sieij*spj[0])); + fi[1] += pre * (eij[1] * g1b2_g2b3 + b2 * (sjeij*spi[1] + sieij*spj[1])); + fi[2] += pre * (eij[2] * g1b2_g2b3 + b2 * (sjeij*spi[2] + sieij*spj[2])); } -- GitLab From 18f8f68e67502fd7bc9edeccf24bc1145c199662 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Tue, 8 Jan 2019 16:33:24 -0700 Subject: [PATCH 0085/1243] Fixed several input parsing issues in pair granular; fixed issue with JKR hysteresis and damping with JKR --- src/GRANULAR/pair_gran_hertz_history.cpp | 2 +- src/GRANULAR/pair_gran_hooke_history.cpp | 5 + src/GRANULAR/pair_granular.cpp | 432 ++++++++++++++--------- src/GRANULAR/pair_granular.h | 2 +- 4 files changed, 266 insertions(+), 175 deletions(-) diff --git a/src/GRANULAR/pair_gran_hertz_history.cpp b/src/GRANULAR/pair_gran_hertz_history.cpp index c96d48de69..d1f3c7bbe1 100644 --- a/src/GRANULAR/pair_gran_hertz_history.cpp +++ b/src/GRANULAR/pair_gran_hertz_history.cpp @@ -36,7 +36,7 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ PairGranHertzHistory::PairGranHertzHistory(LAMMPS *lmp) : - PairGranHookeHistory(lmp, 3) {} + PairGranHookeHistory(lmp) {} /* ---------------------------------------------------------------------- */ diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index cf30e77ccb..04df3b3d9b 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -44,6 +44,7 @@ PairGranHookeHistory::PairGranHookeHistory(LAMMPS *lmp) : Pair(lmp) single_enable = 1; no_virial_fdotr_compute = 1; history = 1; + size_history = 3; fix_history = NULL; single_extra = 10; @@ -348,6 +349,10 @@ void PairGranHookeHistory::settings(int narg, char **arg) { if (narg != 6) error->all(FLERR,"Illegal pair_style command"); + + + + kn = force->numeric(FLERR,arg[0]); if (strcmp(arg[1],"NULL") == 0) kt = kn * 2.0/7.0; else kt = force->numeric(FLERR,arg[1]); diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 72b5f7867e..9ee78686c6 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -48,12 +48,11 @@ using namespace MathConst; #define EPSILON 1e-10 -enum {STIFFNESS, MATERIAL}; enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {HOOKE, HERTZ, DMT, JKR}; +enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; enum {TANGENTIAL_MINDLIN, TANGENTIAL_NOHISTORY}; -enum {NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; -enum {NONE, ROLL_NOHISTORY, ROLL_SDS}; +enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; +enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; /* ---------------------------------------------------------------------- */ @@ -84,8 +83,10 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) use_history = 0; beyond_contact = 0; + nondefault_history_transfer = 0; + tangential_history_index = 0; roll_history_index = twist_history_index = 0; - tangential_history_index = -1; + } /* ---------------------------------------------------------------------- */ @@ -136,7 +137,7 @@ void PairGranular::compute(int eflag, int vflag) //For JKR double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; - double delta, t0, t1, t2, t3, t4, t5, t6; + double t0, t1, t2, t3, t4, t5, t6; double sqrt1, sqrt2, sqrt3, sqrt4; double mi,mj,meff,damp,ccel,tor1,tor2,tor3; @@ -158,7 +159,7 @@ void PairGranular::compute(int eflag, int vflag) int *touch,**firsttouch; double *history,*allhistory,**firsthistory; - bool untouchflag; + bool touchflag; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -232,19 +233,26 @@ void PairGranular::compute(int eflag, int vflag) E = normal_coeffs[itype][jtype][0]; Reff = radi*radj/(radi+radj); + touchflag = false; + if (normal[itype][jtype] == JKR){ - R2 = Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - a = cbrt(9.0*M_PI*coh*R2/(4*E)); - delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); - dist_pulloff = radsum+delta_pulloff; - untouchflag = (rsq >= dist_pulloff*dist_pulloff); + if (touch[jj]){ + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum-delta_pulloff; + touchflag = (rsq <= dist_pulloff*dist_pulloff); + } + else{ + touchflag = (rsq <= radsum*radsum); + } } else{ - untouchflag = (rsq >= radsum*radsum); + touchflag = (rsq <= radsum*radsum); } - if (untouchflag){ + if (!touchflag){ // unset non-touching neighbors touch[jj] = 0; history = &allhistory[size_history*jj]; @@ -252,6 +260,7 @@ void PairGranular::compute(int eflag, int vflag) } else{ r = sqrt(rsq); + rinv = 1.0/r; nx = delx*rinv; ny = dely*rinv; @@ -288,6 +297,7 @@ void PairGranular::compute(int eflag, int vflag) delta = radsum - r; dR = delta*Reff; if (normal[itype][jtype] == JKR){ + touch[jj] = 1; dR2 = dR*dR; t0 = coh*coh*R2*R2*E; t1 = PI27SQ*t0; @@ -308,6 +318,7 @@ void PairGranular::compute(int eflag, int vflag) knfac = E; //Hooke Fne = knfac*delta; if (normal[itype][jtype] != HOOKE) + a = sqdR = sqrt(dR); Fne *= a; if (normal[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; @@ -366,12 +377,9 @@ void PairGranular::compute(int eflag, int vflag) //Tangential forces //------------------------------ k_tangential = tangential_coeffs[itype][jtype][0]; - if (normal[itype][jtype] != HOOKE){ - k_tangential *= a; - } damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - if (tangential_history[itype][jtype]){ + if (tangential_history){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -428,7 +436,7 @@ void PairGranular::compute(int eflag, int vflag) // Rolling resistance //**************************************** - if (roll[itype][jtype] != NONE){ + if (roll[itype][jtype] != ROLL_NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -507,7 +515,7 @@ void PairGranular::compute(int eflag, int vflag) //**************************************** // Twisting torque, including history effects //**************************************** - if (twist[itype][jtype] != NONE){ + if (twist[itype][jtype] != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) if (twist[itype][jtype] == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 @@ -554,7 +562,7 @@ void PairGranular::compute(int eflag, int vflag) torque[i][1] -= radi*tor2; torque[i][2] -= radi*tor3; - if (twist[itype][jtype] != NONE){ + if (twist[itype][jtype] != TWIST_NONE){ tortwist1 = magtortwist * nx; tortwist2 = magtortwist * ny; tortwist3 = magtortwist * nz; @@ -564,7 +572,7 @@ void PairGranular::compute(int eflag, int vflag) torque[i][2] += tortwist3; } - if (roll[itype][jtype] != NONE){ + if (roll[itype][jtype] != ROLL_NONE){ torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr torroll2 = Reff*(nz*fr1 - nx*fr3); torroll3 = Reff*(nx*fr2 - ny*fr1); @@ -583,12 +591,12 @@ void PairGranular::compute(int eflag, int vflag) torque[j][1] -= radj*tor2; torque[j][2] -= radj*tor3; - if (roll[itype][jtype] != NONE){ + if (twist[itype][jtype] != TWIST_NONE){ torque[j][0] -= tortwist1; torque[j][1] -= tortwist2; torque[j][2] -= tortwist3; } - if (roll[itype][jtype] != NONE){ + if (roll[itype][jtype] != ROLL_NONE){ torque[j][0] -= torroll1; torque[j][1] -= torroll2; torque[j][2] -= torroll3; @@ -646,22 +654,21 @@ void PairGranular::settings(int narg, char **arg) int iarg = 0; //Some defaults + normal_global = HERTZ; damping_global = VISCOELASTIC; - coeff_types = STIFFNESS; - tangential_global = -1; //Needs to be explicitly set, since it requires parameters - roll_global = NONE; - twist_global = NONE; + tangential_global = TANGENTIAL_MINDLIN; + roll_global = ROLL_NONE; + twist_global = TWIST_NONE; tangential_history = roll_history = twist_history = 0; - if (strcmp(arg[iarg], "material") == 0){ - coeff_types = MATERIAL; - iarg += 1; - } + int normal_set, tangential_set; + normal_set = tangential_set = 0; + while (iarg < narg){ if (strcmp(arg[iarg], "hooke") == 0){ - if (coeff_types == MATERIAL) error->all(FLERR,"Illegal pair_coeff command, 'stiffness' coefficients required for Hooke"); if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); normal_global = HOOKE; + normal_set = 1; memory->create(normal_coeffs_global, 2, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping @@ -669,20 +676,29 @@ void PairGranular::settings(int narg, char **arg) } else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; - if (coeff_types == MATERIAL) num_coeffs += 1; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); normal_global = HERTZ; + normal_set = 1; + memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "hertz/material") == 0){ + int num_coeffs = 3; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + normal_global = HERTZ_MATERIAL; + normal_set = 1; memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E - if (coeff_types == MATERIAL) normal_coeffs_global[0] *= FOURTHIRDS; + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E (Young's modulus) normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - if (coeff_types == MATERIAL) normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') + normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (shear modulus) iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "dmt") == 0){ - if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_style command, 'material' coefficients required for DMT"); if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); normal_global = DMT; + normal_set = 1; memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //4/3 E normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping @@ -692,9 +708,9 @@ void PairGranular::settings(int narg, char **arg) } else if (strcmp(arg[iarg], "jkr") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for JKR option"); - if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_style command, 'material' coefficients required for JKR"); beyond_contact = 1; normal_global = JKR; + normal_set = 1; memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping @@ -715,57 +731,80 @@ void PairGranular::settings(int narg, char **arg) iarg += 1; } else if (strstr(arg[iarg], "tangential") != NULL){ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); - if (strstr(arg[iarg], "nohistory") != NULL){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ tangential_global = TANGENTIAL_NOHISTORY; + tangential_set = 1; } - else{ + else if (strstr(arg[iarg+1], "mindlin") != NULL){ tangential_global = TANGENTIAL_MINDLIN; tangential_history = 1; + tangential_set = 1; + } + else{ + error->all(FLERR, "Illegal pair_style command, unrecognized sliding friction model"); } memory->create(tangential_coeffs_global, 3, "pair:tangential_coeffs_global"); - tangential_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt - tangential_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. - iarg += 4; + tangential_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } else if (strstr(arg[iarg], "roll") != NULL){ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); - if (strstr(arg[iarg], "nohistory") != NULL){ - roll_global = ROLL_NOHISTORY; + if (strstr(arg[iarg+1], "none") != NULL){ + roll_global = ROLL_NONE; + iarg += 2; } else{ - roll_global = ROLL_SDS; - roll_history = 1; + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + roll_global = ROLL_NOHISTORY; + } + else if (strstr(arg[iarg+1], "sds") != NULL){ + roll_global = ROLL_SDS; + roll_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_style command, unrecognized rolling friction model"); + } + memory->create(roll_coeffs_global, 3, "pair:roll_coeffs_global"); + roll_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } - memory->create(roll_coeffs_global, 3, "pair:roll_coeffs_global"); - roll_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt - roll_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - roll_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. - iarg += 4; } else if (strstr(arg[iarg], "twist") != NULL){ - if (strstr(arg[iarg], "marshall") != NULL){ + if (strstr(arg[iarg+1], "none") != NULL){ + twist_global = TWIST_NONE; + iarg += 2; + } + else if (strstr(arg[iarg+1], "marshall") != NULL){ twist_global = TWIST_MARSHALL; twist_history = 1; - memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later + iarg += 2; } else{ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); - if (strstr(arg[iarg], "nohistory") != NULL){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); + memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later + if (strstr(arg[iarg+1], "nohistory") != NULL){ twist_global = TWIST_NOHISTORY; } - else{ + else if (strstr(arg[iarg+1], "sds") != NULL){ twist_global = TWIST_SDS; twist_history = 1; } + else{ + error->all(FLERR, "Illegal pair_style command, unrecognized twisting friction model"); + } memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); - twist_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kt - twist_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - twist_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. - iarg += 4; + twist_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //ktwist + twist_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammatwist + twist_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } } + else error->all(FLERR, "Illegal pair_style granular command"); } //Set all i-i entries, which may be replaced by pair coeff commands @@ -774,10 +813,9 @@ void PairGranular::settings(int narg, char **arg) // The reason for the current setup is to remain true to existing pair gran/hooke etc. syntax, // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. - - //Other option is to have two pair styles, e.g. pair gran and pair gran/multi, - // where gran/multi allows per-type coefficients, pair gran does not (would also - // allow minor speed-up for pair gran) + //Other option is to have two pair styles, e.g. pair granular and pair granular/multi, + // where granular/multi allows per-type coefficients, pair granular does not (this would also + // allow minor speed-up by templating pair granular) allocate(); double damp; for (int i = 1; i <= atom->ntypes; i++){ @@ -787,40 +825,38 @@ void PairGranular::settings(int narg, char **arg) roll[i][i] = roll_global; twist[i][i] = twist_global; - if (damping_global == TSUJI){ - double cor = normal_coeffs_global[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); + if (normal_set){ + if (damping_global == TSUJI){ + double cor = normal_coeffs_global[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_global[1]; + normal_coeffs[i][i][0] = normal_coeffs_global[0]; + normal_coeffs[i][i][1] = damp; + if (normal[i][i] != HOOKE && normal[i][i] != HERTZ){ + normal_coeffs[i][i][2] = normal_coeffs_global[2]; + } + if ((normal_global == JKR) || (normal_global == DMT)) + normal_coeffs[i][i][3] = normal_coeffs_global[3]; } - else damp = normal_coeffs_global[1]; - normal_coeffs[i][i][0] = normal_coeffs_global[0]; - normal_coeffs[i][i][1] = damp; - if (coeff_types == MATERIAL) normal_coeffs[i][i][2] = normal_coeffs_global[2]; - if ((normal_global == JKR) || (normal_global == DMT)) - normal_coeffs[i][i][3] = normal_coeffs_global[3]; - - tangential[i][i] = tangential_global; - if (tangential_global != NONE) + if(tangential_set){ + tangential[i][i] = tangential_global; for (int k = 0; k < 3; k++) tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; - + } roll[i][i] = roll_global; - if (roll_global != NONE) + if (roll_global != ROLL_NONE) for (int k = 0; k < 3; k++) roll_coeffs[i][i][k] = roll_coeffs_global[k]; twist[i][i] = twist_global; - if (twist_global != NONE) + if (twist_global != TWIST_NONE && twist_global != TWIST_MARSHALL) for (int k = 0; k < 3; k++) twist_coeffs[i][i][k] = twist_coeffs_global[k]; - setflag[i][i] = 1; - } - - //Additional checks - if (tangential_global == -1){ - error->all(FLERR, "Illegal pair_style command: must specify tangential model"); + if (normal_set && tangential_set) setflag[i][i] = 1; } } @@ -850,10 +886,12 @@ void PairGranular::coeff(int narg, char **arg) force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + normal_local = tangential_local = roll_local = twist_local = -1; + damping_local = -1; + int iarg = 2; while (iarg < narg){ if (strcmp(arg[iarg], "hooke") == 0){ - if (coeff_types == MATERIAL) error->all(FLERR,"Illegal pair_coeff command, 'stiffness' coefficients required for Hooke"); if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); normal_local = HOOKE; normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn @@ -862,20 +900,25 @@ void PairGranular::coeff(int narg, char **arg) } else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; - if (coeff_types == MATERIAL) num_coeffs += 1; - if (iarg + offset >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); normal_local = HERTZ; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn or E - if (coeff_types == STIFFNESS) normal_coeffs_local[0] /= FOURTHIRDS; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "hertz/material") == 0){ + int num_coeffs = 3; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + normal_local = HERTZ; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - if (coeff_types == MATERIAL) normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G (if 'material') + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "dmt") == 0){ - if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_coeff command, 'material' coefficients required for DMT"); if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); normal_local = DMT; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion @@ -883,7 +926,6 @@ void PairGranular::coeff(int narg, char **arg) } else if (strcmp(arg[iarg], "jkr") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); - if (coeff_types == STIFFNESS) error->all(FLERR,"Illegal pair_coeff command, 'material' coefficients required for JKR"); beyond_contact = 1; normal_local = JKR; normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E @@ -905,91 +947,128 @@ void PairGranular::coeff(int narg, char **arg) iarg += 1; } else if (strstr(arg[iarg], "tangential") != NULL){ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - if (strstr(arg[iarg], "nohistory") != NULL){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ tangential_local = TANGENTIAL_NOHISTORY; } - else{ + else if (strstr(arg[iarg+1], "mindlin") != NULL){ tangential_local = TANGENTIAL_MINDLIN; tangential_history = 1; } - tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt - tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. - iarg += 4; + else{ + error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); + } + tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } else if (strstr(arg[iarg], "rolling") != NULL){ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); - if (strstr(arg[iarg], "nohistory") != NULL){ - roll_local = ROLL_NOHISTORY; + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + if (strstr(arg[iarg+1], "none") != NULL){ + roll_local = ROLL_NONE; + iarg += 2; } else{ - roll_local = ROLL_SDS; - roll_history = 1; + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + roll_local = ROLL_NOHISTORY; + } + else if (strstr(arg[iarg+1], "sds") != NULL){ + roll_local = ROLL_SDS; + roll_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); + } + roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } - roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt - roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. - iarg += 4; } else if (strstr(arg[iarg], "twist") != NULL){ - if (strstr(arg[iarg], "marshall") != NULL){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + if (strstr(arg[iarg+1], "none") != NULL){ + twist_local = TWIST_NONE; + iarg += 2; + } + else if (strstr(arg[iarg+1], "marshall") != NULL){ twist_local = TWIST_MARSHALL; twist_history = 1; + iarg += 2; } else{ - if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - if (strstr(arg[iarg], "nohistory") != NULL){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ twist_local = TWIST_NOHISTORY; } - else{ + else if (strstr(arg[iarg+1], "sds") != NULL){ twist_local = TWIST_SDS; twist_history = 1; - size_history += 1; } - twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kt - twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //gammat - twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. - iarg += 4; + else{ + error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); + } + twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } } + else error->all(FLERR, "Illegal pair coeff command"); } int count = 0; double damp; - if (damping_local == TSUJI){ - double cor = normal_coeffs_local[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); + if (damping_local >= 0){ + if (normal_local == -1) + error->all(FLERR, "Illegal pair_coeff command, must specify normal model when setting damping model"); + if (damping_local == TSUJI){ + double cor; + cor = normal_coeffs_local[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_local[1]; } - else damp = normal_coeffs_local[1]; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - normal[i][j] = normal_local; - normal_coeffs[i][j][0] = normal_coeffs_local[0]; - normal_coeffs[i][j][1] = damp; - if (coeff_types == MATERIAL) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal_local == JKR) || (normal_local == DMT)) + if (normal_local >= 0){ + normal[i][j] = normal_local; + normal_coeffs[i][j][0] = normal_coeffs_local[0]; + if (damping_local == -1){ + damp = normal_coeffs_global[1]; + } + normal_coeffs[i][j][1] = damp; + if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal_local == JKR) || (normal_local == DMT)) normal_coeffs[i][j][3] = normal_coeffs_local[3]; - - tangential[i][j] = tangential_local; - if (tangential_local != NONE) + } + if (damping_local >= 0){ + damping[i][j] = damping_local; + } + if (tangential_local >= 0){ + tangential[i][j] = tangential_local; for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; + } + if (roll_local >= 0){ + roll[i][j] = roll_local; + if (roll_local != ROLL_NONE) + for (int k = 0; k < 3; k++) + roll_coeffs[i][j][k] = roll_coeffs_local[k]; + } + if (twist_local >= 0){ + twist[i][j] = twist_local; + if (twist_local != TWIST_NONE && twist_local != TWIST_MARSHALL) + for (int k = 0; k < 3; k++) + twist_coeffs[i][j][k] = twist_coeffs_local[k]; + } - roll[i][j] = roll_local; - if (roll_local != NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs_local[k]; - - twist[i][j] = twist_local; - if (twist_local != NONE) - for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs_local[k]; - - setflag[i][j] = 1; + if (normal_local >= 0 && tangential_local >= 0) setflag[i][j] = 1; count++; } @@ -1020,6 +1099,12 @@ void PairGranular::init_style() // Determine whether we need a granular neigh list, how large it needs to be use_history = tangential_history || roll_history || twist_history; + + //For JKR, will need fix/neigh/history to keep track of touch arrays + for (int i = 1; i <= atom->ntypes; i++) + for (int j = 1; j <= atom->ntypes; j++) + if (normal[i][j] == JKR) use_history = 1; + size_history = 3*tangential_history + 3*roll_history + twist_history; //Determine location of tangential/roll/twist histories in array @@ -1145,6 +1230,7 @@ void PairGranular::init_style() double PairGranular::init_one(int i, int j) { + double cutoff; if (setflag[i][j] == 0) { if ((normal[i] != normal[j]) || (damping[i] != damping[j]) || @@ -1157,7 +1243,7 @@ double PairGranular::init_one(int i, int j) error->one(FLERR,str); } - if (coeff_types == MATERIAL){ + if (normal[i][j] != HOOKE && normal[i][j] != HERTZ){ normal_coeffs[i][j][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], normal_coeffs[i][i][2], normal_coeffs[j][j][2]); normal_coeffs[i][j][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], @@ -1165,24 +1251,22 @@ double PairGranular::init_one(int i, int j) } else{ normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); - if (normal[i][j] == HERTZ) normal_coeffs[i][j][0] /= FOURTHIRDS; } normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); - if (tangential[i][i] != NONE){ - for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - } + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - if (roll[i][i] != NONE){ + + if (roll[i][i] != ROLL_NONE){ for (int k = 0; k < 3; k++) roll_coeffs[i][j][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } - if (twist[i][i] != NONE){ + if (twist[i][i] != TWIST_NONE && twist[i][i] != TWIST_MARSHALL){ for (int k = 0; k < 3; k++) twist_coeffs[i][j][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } @@ -1325,6 +1409,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, double tortwist1, tortwist2, tortwist3; double shrmag,rsht; + int jnum; int *ilist,*jlist,*numneigh,**firstneigh; int *touch,**firsttouch; double *history,*allhistory,**firsthistory; @@ -1335,20 +1420,20 @@ double PairGranular::single(int i, int j, int itype, int jtype, radsum = radi + radj; Reff = radi*radj/(radi+radj); - bool untouchflag; + bool touchflag; if (normal[itype][jtype] == JKR){ R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); dist_pulloff = radsum+delta_pulloff; - untouchflag = (rsq >= dist_pulloff*dist_pulloff); + touchflag = (rsq <= dist_pulloff*dist_pulloff); } else{ - untouchflag = (rsq >= radsum*radsum); + touchflag = (rsq <= radsum*radsum); } - if (untouchflag){ + if (touchflag){ fforce = 0.0; for (int m = 0; m < single_extra; m++) svector[m] = 0.0; return 0.0; @@ -1412,9 +1497,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, // if I or J part of rigid body, use body mass // if I or J is frozen, meff is other particle - double *rmass = atom->rmass; int *type = atom->type; - int *mask = atom->mask; mi = rmass[i]; mj = rmass[j]; @@ -1446,11 +1529,13 @@ double PairGranular::single(int i, int j, int itype, int jtype, a2 = a*a; knfac = FOURTHIRDS*E*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + if (damping[itype][jtype] == VISCOELASTIC) sqdR = sqrt(dR); } else{ - knfac = E; //Hooke + knfac = E; Fne = knfac*delta; if (normal[itype][jtype] != HOOKE) + a = sqdR = sqrt(dR); Fne *= a; if (normal[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; @@ -1462,6 +1547,8 @@ double PairGranular::single(int i, int j, int itype, int jtype, } else if (damping[itype][jtype] == VISCOELASTIC){ if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); + + damp_normal = normal_coeffs[itype][jtype][1]*sqdR*meff; } else if (damping[itype][jtype] == TSUJI){ @@ -1472,9 +1559,8 @@ double PairGranular::single(int i, int j, int itype, int jtype, Fntot = Fne + Fdamp; - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allhistory, *history; + jnum = list->numneigh[i]; + jlist = list->firstneigh[i]; if (use_history){ allhistory = fix_history->firstvalue[i]; @@ -1522,7 +1608,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, } damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - if (tangential_history[itype][jtype]){ + if (tangential_history){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -1558,7 +1644,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, // Rolling resistance //**************************************** - if (roll[itype][jtype] != NONE){ + if (roll[itype][jtype] != ROLL_NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -1619,7 +1705,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, //**************************************** // Twisting torque, including history effects //**************************************** - if (twist[itype][jtype] != NONE){ + if (twist[itype][jtype] != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) if (twist[itype][jtype] == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 957a16af8d..0e6f28c514 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -62,9 +62,9 @@ public: virtual void allocate(); int beyond_contact; + int nondefault_history_transfer; private: - int coeff_types; int size_history; //Per-type models -- GitLab From 29dcdec8756bf714fc76b6e35026082494bea4d3 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Thu, 10 Jan 2019 16:53:50 -0700 Subject: [PATCH 0086/1243] Separated templated pair granular from pair granular/multi --- src/GRANULAR/pair_granular.cpp | 1069 ++++++++++++--- src/GRANULAR/pair_granular.h | 33 +- src/GRANULAR/pair_granular_multi.cpp | 1837 ++++++++++++++++++++++++++ src/GRANULAR/pair_granular_multi.h | 108 ++ src/fix_neigh_history.cpp | 8 +- src/pair.h | 4 + 6 files changed, 2850 insertions(+), 209 deletions(-) create mode 100644 src/GRANULAR/pair_granular_multi.cpp create mode 100644 src/GRANULAR/pair_granular_multi.h diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 9ee78686c6..c75c80fea5 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -48,9 +48,9 @@ using namespace MathConst; #define EPSILON 1e-10 -enum {VELOCITY, VISCOELASTIC, TSUJI}; enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; -enum {TANGENTIAL_MINDLIN, TANGENTIAL_NOHISTORY}; +enum {VELOCITY, VISCOELASTIC, TSUJI}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_MINDLIN}; enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; @@ -105,12 +105,6 @@ PairGranular::~PairGranular() memory->destroy(roll_coeffs); memory->destroy(twist_coeffs); - memory->destroy(normal); - memory->destroy(damping); - memory->destroy(tangential); - memory->destroy(roll); - memory->destroy(twist); - delete [] onerad_dynamic; delete [] onerad_frozen; delete [] maxrad_dynamic; @@ -119,12 +113,730 @@ PairGranular::~PairGranular() memory->destroy(mass_rigid); } -void PairGranular::compute(int eflag, int vflag) +void PairGranular::compute(int eflag, int vflag){ +#ifdef TEMPLATED_PAIR_GRANULAR + if (normal == HOOKE){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == HERTZ){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == HERTZ_MATERIAL){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == DMT){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == JKR){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,3,2>(eflag, vflag); + } + } + } + } + +#else + compute_untemplated(Tp_normal, Tp_damping, Tp_tangential, + Tp_roll, Tp_twist, + eflag, vflag); +#endif +} + +#ifdef TEMPLATED_PAIR_GRANULAR +template < int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_roll, int Tp_twist > +void PairGranular::compute_templated(int eflag, int vflag) +#else +void PairGranular::compute_untemplated + (int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_roll, int Tp_twist, int eflag, int vflag) +#endif { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; double radi,radj,radsum,rsq,r,rinv,rsqinv; - double Reff, delta, dR, dR2, sqdR; + double Reff, delta, dR, dR2; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3; @@ -235,21 +947,21 @@ void PairGranular::compute(int eflag, int vflag) Reff = radi*radj/(radi+radj); touchflag = false; - if (normal[itype][jtype] == JKR){ + if (Tp_normal == JKR){ if (touch[jj]){ R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); dist_pulloff = radsum-delta_pulloff; - touchflag = (rsq <= dist_pulloff*dist_pulloff); + touchflag = (rsq < dist_pulloff*dist_pulloff); } else{ - touchflag = (rsq <= radsum*radsum); + touchflag = (rsq < radsum*radsum); } } else{ - touchflag = (rsq <= radsum*radsum); + touchflag = (rsq < radsum*radsum); } if (!touchflag){ @@ -296,8 +1008,10 @@ void PairGranular::compute(int eflag, int vflag) delta = radsum - r; dR = delta*Reff; - if (normal[itype][jtype] == JKR){ + if (Tp_normal == JKR){ touch[jj] = 1; + R2=Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; dR2 = dR*dR; t0 = coh*coh*R2*R2*E; t1 = PI27SQ*t0; @@ -317,22 +1031,22 @@ void PairGranular::compute(int eflag, int vflag) else{ knfac = E; //Hooke Fne = knfac*delta; - if (normal[itype][jtype] != HOOKE) - a = sqdR = sqrt(dR); + if (Tp_normal != HOOKE) + a = sqrt(dR); Fne *= a; - if (normal[itype][jtype] == DMT) + if (Tp_normal == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping[itype][jtype] == VELOCITY){ + if (Tp_damping == VELOCITY){ damp_normal = normal_coeffs[itype][jtype][1]; } - else if (damping[itype][jtype] == VISCOELASTIC){ - if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); - damp_normal = normal_coeffs[itype][jtype][1]*sqdR*meff; + else if (Tp_damping == VISCOELASTIC){ + if (Tp_normal == HOOKE) a = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*a*meff; } - else if (damping[itype][jtype] == TSUJI){ + else if (Tp_damping == TSUJI){ damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); } @@ -367,11 +1081,14 @@ void PairGranular::compute(int eflag, int vflag) history = &allhistory[size_history*jj]; } - Fcrit = fabs(Fne); - if (normal[itype][jtype] == JKR){ + + if (Tp_normal == JKR){ F_pulloff = 3*M_PI*coh*Reff; Fcrit = fabs(Fne + 2*F_pulloff); } + else{ + Fcrit = fabs(Fne); + } //------------------------------ //Tangential forces @@ -379,7 +1096,7 @@ void PairGranular::compute(int eflag, int vflag) k_tangential = tangential_coeffs[itype][jtype][0]; damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - if (tangential_history){ + if (Tp_tangential > 0){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -436,7 +1153,7 @@ void PairGranular::compute(int eflag, int vflag) // Rolling resistance //**************************************** - if (roll[itype][jtype] != ROLL_NONE){ + if (Tp_roll != ROLL_NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -451,7 +1168,7 @@ void PairGranular::compute(int eflag, int vflag) if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; else vrlmaginv = 0.0; - if (roll_history){ + if (Tp_roll > 1){ int rhist0 = roll_history_index; int rhist1 = rhist0 + 1; int rhist2 = rhist1 + 1; @@ -515,9 +1232,9 @@ void PairGranular::compute(int eflag, int vflag) //**************************************** // Twisting torque, including history effects //**************************************** - if (twist[itype][jtype] != TWIST_NONE){ + if (Tp_twist != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist[itype][jtype] == TWIST_MARSHALL){ + if (Tp_twist == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a; @@ -527,7 +1244,7 @@ void PairGranular::compute(int eflag, int vflag) damp_twist = twist_coeffs[itype][jtype][1]; mu_twist = twist_coeffs[itype][jtype][2]; } - if (twist_history){ + if (Tp_twist > 1){ if (historyupdate){ history[twist_history_index] += magtwist*dt; } @@ -562,7 +1279,7 @@ void PairGranular::compute(int eflag, int vflag) torque[i][1] -= radi*tor2; torque[i][2] -= radi*tor3; - if (twist[itype][jtype] != TWIST_NONE){ + if (Tp_twist != TWIST_NONE){ tortwist1 = magtortwist * nx; tortwist2 = magtortwist * ny; tortwist3 = magtortwist * nz; @@ -572,7 +1289,7 @@ void PairGranular::compute(int eflag, int vflag) torque[i][2] += tortwist3; } - if (roll[itype][jtype] != ROLL_NONE){ + if (Tp_roll != ROLL_NONE){ torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr torroll2 = Reff*(nz*fr1 - nx*fr3); torroll3 = Reff*(nx*fr2 - ny*fr1); @@ -591,12 +1308,12 @@ void PairGranular::compute(int eflag, int vflag) torque[j][1] -= radj*tor2; torque[j][2] -= radj*tor3; - if (twist[itype][jtype] != TWIST_NONE){ + if (Tp_twist != TWIST_NONE){ torque[j][0] -= tortwist1; torque[j][1] -= tortwist2; torque[j][2] -= tortwist3; } - if (roll[itype][jtype] != ROLL_NONE){ + if (Tp_roll != ROLL_NONE){ torque[j][0] -= torroll1; torque[j][1] -= torroll2; torque[j][2] -= torroll3; @@ -631,12 +1348,6 @@ void PairGranular::allocate() memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); - memory->create(normal,n+1,n+1,"pair:normal"); - memory->create(damping,n+1,n+1,"pair:damping"); - memory->create(tangential,n+1,n+1,"pair:tangential"); - memory->create(roll,n+1,n+1,"pair:roll"); - memory->create(twist,n+1,n+1,"pair:twist"); - onerad_dynamic = new double[n+1]; onerad_frozen = new double[n+1]; maxrad_dynamic = new double[n+1]; @@ -654,12 +1365,14 @@ void PairGranular::settings(int narg, char **arg) int iarg = 0; //Some defaults - normal_global = HERTZ; - damping_global = VISCOELASTIC; - tangential_global = TANGENTIAL_MINDLIN; - roll_global = ROLL_NONE; - twist_global = TWIST_NONE; - tangential_history = roll_history = twist_history = 0; + normal = HERTZ; + damping = VISCOELASTIC; + tangential = TANGENTIAL_MINDLIN; + roll = ROLL_NONE; + twist = TWIST_NONE; + + tangential_history = 1; + roll_history = twist_history = 0; int normal_set, tangential_set; normal_set = tangential_set = 0; @@ -667,8 +1380,7 @@ void PairGranular::settings(int narg, char **arg) while (iarg < narg){ if (strcmp(arg[iarg], "hooke") == 0){ if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); - normal_global = HOOKE; - normal_set = 1; + normal = HOOKE; memory->create(normal_coeffs_global, 2, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping @@ -677,7 +1389,7 @@ void PairGranular::settings(int narg, char **arg) else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal_global = HERTZ; + normal = HERTZ; normal_set = 1; memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn @@ -687,7 +1399,7 @@ void PairGranular::settings(int narg, char **arg) else if (strcmp(arg[iarg], "hertz/material") == 0){ int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal_global = HERTZ_MATERIAL; + normal = HERTZ_MATERIAL; normal_set = 1; memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E (Young's modulus) @@ -697,7 +1409,7 @@ void PairGranular::settings(int narg, char **arg) } else if (strcmp(arg[iarg], "dmt") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal_global = DMT; + normal = DMT; normal_set = 1; memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //4/3 E @@ -709,7 +1421,7 @@ void PairGranular::settings(int narg, char **arg) else if (strcmp(arg[iarg], "jkr") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for JKR option"); beyond_contact = 1; - normal_global = JKR; + normal = JKR; normal_set = 1; memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E @@ -719,25 +1431,25 @@ void PairGranular::settings(int narg, char **arg) iarg += 5; } else if (strcmp(arg[iarg], "damp_velocity") == 0){ - damping_global = VELOCITY; + damping = VELOCITY; iarg += 1; } else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ - damping_global = VISCOELASTIC; + damping = VISCOELASTIC; iarg += 1; } else if (strcmp(arg[iarg], "damp_tsuji") == 0){ - damping_global = TSUJI; + damping = TSUJI; iarg += 1; } else if (strstr(arg[iarg], "tangential") != NULL){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); if (strstr(arg[iarg+1], "nohistory") != NULL){ - tangential_global = TANGENTIAL_NOHISTORY; + tangential = TANGENTIAL_NOHISTORY; tangential_set = 1; } else if (strstr(arg[iarg+1], "mindlin") != NULL){ - tangential_global = TANGENTIAL_MINDLIN; + tangential = TANGENTIAL_MINDLIN; tangential_history = 1; tangential_set = 1; } @@ -752,16 +1464,16 @@ void PairGranular::settings(int narg, char **arg) } else if (strstr(arg[iarg], "roll") != NULL){ if (strstr(arg[iarg+1], "none") != NULL){ - roll_global = ROLL_NONE; + roll = ROLL_NONE; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); if (strstr(arg[iarg+1], "nohistory") != NULL){ - roll_global = ROLL_NOHISTORY; + roll = ROLL_NOHISTORY; } else if (strstr(arg[iarg+1], "sds") != NULL){ - roll_global = ROLL_SDS; + roll = ROLL_SDS; roll_history = 1; } else{ @@ -776,11 +1488,11 @@ void PairGranular::settings(int narg, char **arg) } else if (strstr(arg[iarg], "twist") != NULL){ if (strstr(arg[iarg+1], "none") != NULL){ - twist_global = TWIST_NONE; + twist = TWIST_NONE; iarg += 2; } else if (strstr(arg[iarg+1], "marshall") != NULL){ - twist_global = TWIST_MARSHALL; + twist = TWIST_MARSHALL; twist_history = 1; iarg += 2; } @@ -788,10 +1500,10 @@ void PairGranular::settings(int narg, char **arg) if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later if (strstr(arg[iarg+1], "nohistory") != NULL){ - twist_global = TWIST_NOHISTORY; + twist = TWIST_NOHISTORY; } else if (strstr(arg[iarg+1], "sds") != NULL){ - twist_global = TWIST_SDS; + twist = TWIST_SDS; twist_history = 1; } else{ @@ -813,46 +1525,35 @@ void PairGranular::settings(int narg, char **arg) // The reason for the current setup is to remain true to existing pair gran/hooke etc. syntax, // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. - //Other option is to have two pair styles, e.g. pair granular and pair granular/multi, - // where granular/multi allows per-type coefficients, pair granular does not (this would also - // allow minor speed-up by templating pair granular) allocate(); double damp; - for (int i = 1; i <= atom->ntypes; i++){ - normal[i][i] = normal_global; - damping[i][i] = damping_global; - tangential[i][i] = tangential_global; - roll[i][i] = roll_global; - twist[i][i] = twist_global; + if (damping == TSUJI){ + double cor = normal_coeffs_global[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_global[1]; + for (int i = 1; i <= atom->ntypes; i++){ if (normal_set){ - if (damping_global == TSUJI){ - double cor = normal_coeffs_global[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_global[1]; normal_coeffs[i][i][0] = normal_coeffs_global[0]; normal_coeffs[i][i][1] = damp; - if (normal[i][i] != HOOKE && normal[i][i] != HERTZ){ + if (normal != HOOKE && normal != HERTZ){ normal_coeffs[i][i][2] = normal_coeffs_global[2]; } - if ((normal_global == JKR) || (normal_global == DMT)) + if ((normal == JKR) || (normal == DMT)) normal_coeffs[i][i][3] = normal_coeffs_global[3]; } if(tangential_set){ - tangential[i][i] = tangential_global; for (int k = 0; k < 3; k++) tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; } - roll[i][i] = roll_global; - if (roll_global != ROLL_NONE) + if (roll != ROLL_NONE) for (int k = 0; k < 3; k++) roll_coeffs[i][i][k] = roll_coeffs_global[k]; - twist[i][i] = twist_global; - if (twist_global != TWIST_NONE && twist_global != TWIST_MARSHALL) + if (twist != TWIST_NONE && twist != TWIST_MARSHALL) for (int k = 0; k < 3; k++) twist_coeffs[i][i][k] = twist_coeffs_global[k]; @@ -866,7 +1567,7 @@ void PairGranular::settings(int narg, char **arg) void PairGranular::coeff(int narg, char **arg) { - int normal_local, damping_local, tangential_local, roll_local, twist_local; + int normal_set, damping_set, tangential_set, roll_set, twist_set; double *normal_coeffs_local; double *tangential_coeffs_local; double *roll_coeffs_local; @@ -886,78 +1587,83 @@ void PairGranular::coeff(int narg, char **arg) force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - normal_local = tangential_local = roll_local = twist_local = -1; - damping_local = -1; + normal_set = damping_set = tangential_set = roll_set = twist_set = 0; int iarg = 2; while (iarg < narg){ if (strcmp(arg[iarg], "hooke") == 0){ if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); - normal_local = HOOKE; + if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_set = 1; iarg += 3; } else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_local = HERTZ; + if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_set = 1; iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "hertz/material") == 0){ int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_local = HERTZ; + if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_set = 1; iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "dmt") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_local = DMT; + if (normal != DMT) if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + normal_set = 1; iarg += 5; } else if (strcmp(arg[iarg], "jkr") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); beyond_contact = 1; - normal_local = JKR; + if (normal != JKR) if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + normal_set = 1; iarg += 5; } else if (strcmp(arg[iarg], "damp_velocity") == 0){ - damping_local = VELOCITY; + if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be consistent"); iarg += 1; } else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ - damping_local = VISCOELASTIC; + if (damping != VISCOELASTIC) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be consistent"); iarg += 1; } else if (strcmp(arg[iarg], "damp_tsuji") == 0){ - damping_local = TSUJI; + if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be consistent"); iarg += 1; } else if (strstr(arg[iarg], "tangential") != NULL){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); if (strstr(arg[iarg+1], "nohistory") != NULL){ - tangential_local = TANGENTIAL_NOHISTORY; + if (tangential != TANGENTIAL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be consistent"); } else if (strstr(arg[iarg+1], "mindlin") != NULL){ - tangential_local = TANGENTIAL_MINDLIN; + if (tangential != TANGENTIAL_MINDLIN) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be consistent");; tangential_history = 1; } else{ error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); } + tangential_set = 1; tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. @@ -966,21 +1672,22 @@ void PairGranular::coeff(int narg, char **arg) else if (strstr(arg[iarg], "rolling") != NULL){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); if (strstr(arg[iarg+1], "none") != NULL){ - roll_local = ROLL_NONE; + if (roll != ROLL_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be consistent"); iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); if (strstr(arg[iarg+1], "nohistory") != NULL){ - roll_local = ROLL_NOHISTORY; + if (roll != ROLL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be consistent"); } else if (strstr(arg[iarg+1], "sds") != NULL){ - roll_local = ROLL_SDS; + if (roll != ROLL_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be consistent"); roll_history = 1; } else{ error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); } + roll_set =1 ; roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. @@ -990,26 +1697,27 @@ void PairGranular::coeff(int narg, char **arg) else if (strstr(arg[iarg], "twist") != NULL){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); if (strstr(arg[iarg+1], "none") != NULL){ - twist_local = TWIST_NONE; + if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); iarg += 2; } else if (strstr(arg[iarg+1], "marshall") != NULL){ - twist_local = TWIST_MARSHALL; + if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); twist_history = 1; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); if (strstr(arg[iarg+1], "nohistory") != NULL){ - twist_local = TWIST_NOHISTORY; + if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); } else if (strstr(arg[iarg+1], "sds") != NULL){ - twist_local = TWIST_SDS; + if (twist != TWIST_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); twist_history = 1; } else{ error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); } + twist_set = 1; twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. @@ -1021,55 +1729,39 @@ void PairGranular::coeff(int narg, char **arg) int count = 0; double damp; - if (damping_local >= 0){ - if (normal_local == -1) - error->all(FLERR, "Illegal pair_coeff command, must specify normal model when setting damping model"); - if (damping_local == TSUJI){ - double cor; - cor = normal_coeffs_local[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_local[1]; + if (damping == TSUJI){ + double cor; + cor = normal_coeffs_local[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); } + else damp = normal_coeffs_local[1]; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - if (normal_local >= 0){ - normal[i][j] = normal_local; + if (normal_set){ normal_coeffs[i][j][0] = normal_coeffs_local[0]; - if (damping_local == -1){ - damp = normal_coeffs_global[1]; - } normal_coeffs[i][j][1] = damp; - if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal_local == JKR) || (normal_local == DMT)) + if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal == JKR) || (normal == DMT)) normal_coeffs[i][j][3] = normal_coeffs_local[3]; } - if (damping_local >= 0){ - damping[i][j] = damping_local; - } - if (tangential_local >= 0){ - tangential[i][j] = tangential_local; + if (tangential_set){ for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; } - if (roll_local >= 0){ - roll[i][j] = roll_local; - if (roll_local != ROLL_NONE) + if (roll_set){ + if (roll != ROLL_NONE) for (int k = 0; k < 3; k++) roll_coeffs[i][j][k] = roll_coeffs_local[k]; } - if (twist_local >= 0){ - twist[i][j] = twist_local; - if (twist_local != TWIST_NONE && twist_local != TWIST_MARSHALL) + if (twist_set){ + if (twist != TWIST_NONE && twist != TWIST_MARSHALL) for (int k = 0; k < 3; k++) twist_coeffs[i][j][k] = twist_coeffs_local[k]; } - - if (normal_local >= 0 && tangential_local >= 0) setflag[i][j] = 1; - + setflag[i][j] = 1; count++; } } @@ -1101,9 +1793,7 @@ void PairGranular::init_style() use_history = tangential_history || roll_history || twist_history; //For JKR, will need fix/neigh/history to keep track of touch arrays - for (int i = 1; i <= atom->ntypes; i++) - for (int j = 1; j <= atom->ntypes; j++) - if (normal[i][j] == JKR) use_history = 1; + if (normal == JKR) use_history = 1; size_history = 3*tangential_history + 3*roll_history + twist_history; @@ -1181,13 +1871,13 @@ void PairGranular::init_style() if (ipour >= 0) { itype = i; double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); - if (normal[itype][itype] == JKR) radmax = radmax + 0.5*pulloff_distance(radmax, itype); + if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); onerad_dynamic[i] = radmax; } if (idep >= 0) { itype = i; double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); - if (normal[itype][itype] == JKR) radmax = radmax + 0.5*pulloff_distance(radmax, itype); + if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); onerad_dynamic[i] = radmax; } } @@ -1199,8 +1889,8 @@ void PairGranular::init_style() for (i = 0; i < nlocal; i++){ double radius_cut = radius[i]; - if (normal[type[i]][type[i]] == JKR){ - radius_cut = radius[i] + 0.5*pulloff_distance(radius[i], type[i]); + if (normal == JKR){ + radius_cut = radius[i] - 0.5*pulloff_distance(radius[i], type[i]); } if (mask[i] & freeze_group_bit){ onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); @@ -1232,18 +1922,8 @@ double PairGranular::init_one(int i, int j) { double cutoff; if (setflag[i][j] == 0) { - if ((normal[i] != normal[j]) || - (damping[i] != damping[j]) || - (tangential[i] != tangential[j]) || - (roll[i] != roll[j]) || - (twist[i] != twist[j])){ - - char str[512]; - sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); - error->one(FLERR,str); - } - if (normal[i][j] != HOOKE && normal[i][j] != HERTZ){ + if (normal != HOOKE && normal != HERTZ){ normal_coeffs[i][j][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], normal_coeffs[i][i][2], normal_coeffs[j][j][2]); normal_coeffs[i][j][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], @@ -1254,19 +1934,19 @@ double PairGranular::init_one(int i, int j) } normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); - if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) + if ((normal == JKR) || (normal == DMT)) normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - if (roll[i][i] != ROLL_NONE){ + if (roll != ROLL_NONE){ for (int k = 0; k < 3; k++) roll_coeffs[i][j][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } - if (twist[i][i] != TWIST_NONE && twist[i][i] != TWIST_MARSHALL){ + if (twist != TWIST_NONE && twist != TWIST_MARSHALL){ for (int k = 0; k < 3; k++) twist_coeffs[i][j][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } @@ -1305,15 +1985,15 @@ double PairGranular::init_one(int i, int j) void PairGranular::write_restart(FILE *fp) { int i,j; + fwrite(&normal,sizeof(int),1,fp); + fwrite(&damping,sizeof(int),1,fp); + fwrite(&tangential,sizeof(int),1,fp); + fwrite(&roll,sizeof(int),1,fp); + fwrite(&twist,sizeof(int),1,fp); 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(&normal[i][j],sizeof(int),1,fp); - fwrite(&damping[i][j],sizeof(int),1,fp); - fwrite(&tangential[i][j],sizeof(int),1,fp); - fwrite(&roll[i][j],sizeof(int),1,fp); - fwrite(&twist[i][j],sizeof(int),1,fp); fwrite(&normal_coeffs[i][j],sizeof(double),4,fp); fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); @@ -1333,28 +2013,30 @@ void PairGranular::read_restart(FILE *fp) allocate(); int i,j; int me = comm->me; + if (me == 0){ + fread(&normal,sizeof(int),1,fp); + fread(&damping,sizeof(int),1,fp); + fread(&tangential,sizeof(int),1,fp); + fread(&roll,sizeof(int),1,fp); + fread(&twist,sizeof(int),1,fp); + } + MPI_Bcast(&normal,1,MPI_INT,0,world); + MPI_Bcast(&damping,1,MPI_INT,0,world); + MPI_Bcast(&tangential,1,MPI_INT,0,world); + MPI_Bcast(&roll,1,MPI_INT,0,world); + MPI_Bcast(&twist,1,MPI_INT,0,world); 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(&normal[i][j],sizeof(int),1,fp); - fread(&damping[i][j],sizeof(int),1,fp); - fread(&tangential[i][j],sizeof(int),1,fp); - fread(&roll[i][j],sizeof(int),1,fp); - fread(&twist[i][j],sizeof(int),1,fp); fread(&normal_coeffs[i][j],sizeof(double),4,fp); fread(&tangential_coeffs[i][j],sizeof(double),3,fp); fread(&roll_coeffs[i][j],sizeof(double),3,fp); fread(&twist_coeffs[i][j],sizeof(double),3,fp); fread(&cut[i][j],sizeof(double),1,fp); } - MPI_Bcast(&normal[i][j],1,MPI_INT,0,world); - MPI_Bcast(&damping[i][j],1,MPI_INT,0,world); - MPI_Bcast(&tangential[i][j],1,MPI_INT,0,world); - MPI_Bcast(&roll[i][j],1,MPI_INT,0,world); - MPI_Bcast(&twist[i][j],1,MPI_INT,0,world); MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); @@ -1380,7 +2062,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, { double radi,radj,radsum; double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; - double dR, dR2, sqdR; + double dR, dR2; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; double mi,mj,meff,damp,ccel,tor1,tor2,tor3; @@ -1421,7 +2103,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, Reff = radi*radj/(radi+radj); bool touchflag; - if (normal[itype][jtype] == JKR){ + if (normal == JKR){ R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); @@ -1513,7 +2195,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, delta = radsum - r; dR = delta*Reff; - if (normal[itype][jtype] == JKR){ + if (normal == JKR){ dR2 = dR*dR; t0 = coh*coh*R2*R2*E; t1 = PI27SQ*t0; @@ -1529,29 +2211,26 @@ double PairGranular::single(int i, int j, int itype, int jtype, a2 = a*a; knfac = FOURTHIRDS*E*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - if (damping[itype][jtype] == VISCOELASTIC) sqdR = sqrt(dR); } else{ knfac = E; Fne = knfac*delta; - if (normal[itype][jtype] != HOOKE) - a = sqdR = sqrt(dR); + if (normal != HOOKE) + a = sqrt(dR); Fne *= a; - if (normal[itype][jtype] == DMT) + if (normal == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping[itype][jtype] == VELOCITY){ + if (damping == VELOCITY){ damp_normal = normal_coeffs[itype][jtype][1]; } - else if (damping[itype][jtype] == VISCOELASTIC){ - if (normal[itype][jtype] == HOOKE) a = sqdR = sqrt(dR); - - - damp_normal = normal_coeffs[itype][jtype][1]*sqdR*meff; + else if (damping == VISCOELASTIC){ + if (normal == HOOKE) a = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*a*meff; } - else if (damping[itype][jtype] == TSUJI){ + else if (damping == TSUJI){ damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); } @@ -1594,7 +2273,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, vrel = sqrt(vrel); Fcrit = fabs(Fne); - if (normal[itype][jtype] == JKR){ + if (normal == JKR){ F_pulloff = 3*M_PI*coh*Reff; Fcrit = fabs(Fne + 2*F_pulloff); } @@ -1603,7 +2282,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, //Tangential forces //------------------------------ k_tangential = tangential_coeffs[itype][jtype][0]; - if (normal[itype][jtype] != HOOKE){ + if (normal != HOOKE){ k_tangential *= a; } damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; @@ -1644,7 +2323,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, // Rolling resistance //**************************************** - if (roll[itype][jtype] != ROLL_NONE){ + if (roll != ROLL_NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -1705,9 +2384,9 @@ double PairGranular::single(int i, int j, int itype, int jtype, //**************************************** // Twisting torque, including history effects //**************************************** - if (twist[itype][jtype] != TWIST_NONE){ + if (twist != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist[itype][jtype] == TWIST_MARSHALL){ + if (twist == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a; diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 0e6f28c514..897316c907 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -28,7 +28,19 @@ class PairGranular : public Pair { public: PairGranular(class LAMMPS *); virtual ~PairGranular(); - virtual void compute(int, int); + + void compute(int, int); + // comment next line to turn off templating +#define TEMPLATED_PAIR_GRANULAR +#ifdef TEMPLATED_PAIR_GRANULAR + template < int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_roll, int Tp_twist> + void compute_templated(int, int); +#else + void compute_untemplated(int, int, int, int, int, + int, int); +#endif + virtual void settings(int, char **); virtual void coeff(int, char **); void init_style(); @@ -61,28 +73,27 @@ public: int nmax; // allocated size of mass_rigid virtual void allocate(); - int beyond_contact; - int nondefault_history_transfer; private: int size_history; - //Per-type models - int **normal, **damping, **tangential, **roll, **twist; - - int normal_global, damping_global; - int tangential_global, roll_global, twist_global; + //Models + int normal, damping, tangential, roll, twist; + //History flags int tangential_history, roll_history, twist_history; - int tangential_history_index; - int roll_history_index; - int twist_history_index; + //Indices of history entries + int tangential_history_index, roll_history_index, twist_history_index; + + //Coefficients declared in pair style command, used as default unless + // overwritten in pair coeff command double *normal_coeffs_global; double *tangential_coeffs_global; double *roll_coeffs_global; double *twist_coeffs_global; + //Per-type coefficients declared in pair coeff command double ***normal_coeffs; double ***tangential_coeffs; double ***roll_coeffs; diff --git a/src/GRANULAR/pair_granular_multi.cpp b/src/GRANULAR/pair_granular_multi.cpp new file mode 100644 index 0000000000..11381444a2 --- /dev/null +++ b/src/GRANULAR/pair_granular_multi.cpp @@ -0,0 +1,1837 @@ +/* ---------------------------------------------------------------------- +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: +Dan Bolintineanu (SNL), Ishan Srivastava (SNL), Jeremy Lechman(SNL) +Leo Silbert (SNL), Gary Grest (SNL) +----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_granular_multi.h" +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define PI27SQ 266.47931882941264802866 // 27*PI**2 +#define THREEROOT3 5.19615242270663202362 // 3*sqrt(3) +#define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) +#define INVROOT6 0.40824829046386307274 // 1/sqrt(6) +#define FOURTHIRDS 1.333333333333333 // 4/3 +#define TWOPI 6.28318530717959 // 2*PI + +#define EPSILON 1e-10 + +enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; +enum {VELOCITY, VISCOELASTIC, TSUJI}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_MINDLIN}; +enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; +enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; + +/* ---------------------------------------------------------------------- */ + +PairGranularMulti::PairGranularMulti(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 1; + no_virial_fdotr_compute = 1; + fix_history = NULL; + + single_extra = 9; + svector = new double[single_extra]; + + neighprev = 0; + + nmax = 0; + mass_rigid = NULL; + + onerad_dynamic = NULL; + onerad_frozen = NULL; + maxrad_dynamic = NULL; + maxrad_frozen = NULL; + + dt = update->dt; + + // set comm size needed by this Pair if used with fix rigid + + comm_forward = 1; + + use_history = 0; + beyond_contact = 0; + nondefault_history_transfer = 0; + tangential_history_index = 0; + roll_history_index = twist_history_index = 0; + +} + +/* ---------------------------------------------------------------------- */ +PairGranularMulti::~PairGranularMulti() +{ + delete [] svector; + if (fix_history) modify->delete_fix("NEIGH_HISTORY"); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(cut); + + memory->destroy(normal_coeffs); + memory->destroy(tangential_coeffs); + memory->destroy(roll_coeffs); + memory->destroy(twist_coeffs); + + memory->destroy(normal); + memory->destroy(damping); + memory->destroy(tangential); + memory->destroy(roll); + memory->destroy(twist); + + delete [] onerad_dynamic; + delete [] onerad_frozen; + delete [] maxrad_dynamic; + delete [] maxrad_frozen; + } + memory->destroy(mass_rigid); +} + +void PairGranularMulti::compute(int eflag, int vflag) +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv; + double Reff, delta, dR, dR2; + + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + + double knfac, damp_normal; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; + + //For JKR + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; + + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + + //Twisting + double k_twist, damp_twist, mu_twist; + double signtwist, magtwist, magtortwist, Mtcrit; + double tortwist1, tortwist2, tortwist3; + + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *history,*allhistory,**firsthistory; + + bool touchflag; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int historyupdate = 1; + if (update->setupflag) historyupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + 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 newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firsthistory = fix_history->firstvalue; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + radi = radius[i]; + touch = firsttouch[i]; + allhistory = firsthistory[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]; + jtype = type[j]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + + E = normal_coeffs[itype][jtype][0]; + Reff = radi*radj/(radi+radj); + touchflag = false; + + if (normal[itype][jtype] == JKR){ + if (touch[jj]){ + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum-delta_pulloff; + touchflag = (rsq < dist_pulloff*dist_pulloff); + } + else{ + touchflag = (rsq < radsum*radsum); + } + } + else{ + touchflag = (rsq < radsum*radsum); + } + + if (!touchflag){ + // unset non-touching neighbors + touch[jj] = 0; + history = &allhistory[size_history*jj]; + for (int k = 0; k < size_history; k++) history[k] = 0.0; + } + else{ + r = sqrt(rsq); + rinv = 1.0/r; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + if (normal[itype][jtype] == JKR){ + touch[jj] = 1; + R2=Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = FOURTHIRDS*E*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + else{ + knfac = E; //Hooke + Fne = knfac*delta; + if (normal[itype][jtype] != HOOKE) + a = sqrt(dR); + Fne *= a; + if (normal[itype][jtype] == DMT) + Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; + } + + //Consider restricting Hooke to only have 'velocity' as an option for damping? + if (damping[itype][jtype] == VELOCITY){ + damp_normal = normal_coeffs[itype][jtype][1]; + } + else if (damping[itype][jtype] == VISCOELASTIC){ + if (normal[itype][jtype] == HOOKE) a = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*a*meff; + } + else if (damping[itype][jtype] == TSUJI){ + damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); + } + + Fdamp = -damp_normal*vnnr; + + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // If any history is needed: + if (use_history){ + touch[jj] = 1; + history = &allhistory[size_history*jj]; + } + + if (normal[itype][jtype] == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*F_pulloff); + } + else{ + Fcrit = fabs(Fne); + } + + //------------------------------ + //Tangential forces + //------------------------------ + k_tangential = tangential_coeffs[itype][jtype][0]; + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + + if (tangential_history){ + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // Rotate and update displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (historyupdate) { + rsht = history[0]*nx + history[1]*ny + history[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + history[0] -= rsht*nx; + history[1] -= rsht*ny; + history[2] -= rsht*nz; + //Also rescale to preserve magnitude + history[0] *= scalefac; + history[1] *= scalefac; + history[2] *= scalefac; + } + //Update history + history[0] += vtr1*dt; + history[1] += vtr2*dt; + history[2] += vtr3*dt; + } + + // tangential forces = history + tangential velocity damping + fs1 = -k_tangential*history[0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[2] - damp_tangential*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; + } + + //**************************************** + // Rolling resistance + //**************************************** + + if (roll[itype][jtype] != ROLL_NONE){ + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + if (roll_history){ + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + if (historyupdate){ + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + history[rhist0] -= rolldotn*nx; + history[rhist1] -= rolldotn*ny; + history[rhist2] -= rolldotn*nz; + //Also rescale to preserve magnitude + history[rhist0] *= scalefac; + history[rhist1] *= scalefac; + history[rhist2] *= scalefac; + } + history[rhist0] += vrl1*dt; + history[rhist1] += vrl2*dt; + history[rhist2] += vrl3*dt; + } + + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; + } + } + + //**************************************** + // Twisting torque, including history effects + //**************************************** + if (twist[itype][jtype] != TWIST_NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (twist[itype][jtype] == TWIST_MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a; + } + else{ + k_twist = twist_coeffs[itype][jtype][0]; + damp_twist = twist_coeffs[itype][jtype][1]; + mu_twist = twist_coeffs[itype][jtype][2]; + } + if (twist[itype][jtype] > 1){ + if (historyupdate){ + history[twist_history_index] += magtwist*dt; + } + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; + } + } + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + if (twist[itype][jtype] != TWIST_NONE){ + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + } + + if (roll[itype][jtype] != ROLL_NONE){ + torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = Reff*(nz*fr1 - nx*fr3); + torroll3 = Reff*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + } + + if (force->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 (twist[itype][jtype] != TWIST_NONE){ + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + } + if (roll[itype][jtype] != ROLL_NONE){ + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + + +/* ---------------------------------------------------------------------- +allocate all arrays +------------------------------------------------------------------------- */ + +void PairGranularMulti::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(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); + memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); + memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); + memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); + + memory->create(normal,n+1,n+1,"pair:normal"); + memory->create(damping,n+1,n+1,"pair:damping"); + memory->create(tangential,n+1,n+1,"pair:tangential"); + memory->create(roll,n+1,n+1,"pair:roll"); + memory->create(twist,n+1,n+1,"pair:twist"); + + onerad_dynamic = new double[n+1]; + onerad_frozen = new double[n+1]; + maxrad_dynamic = new double[n+1]; + maxrad_frozen = new double[n+1]; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairGranularMulti::settings(int narg, char **arg) +{ + if (narg < 5) error->all(FLERR,"Illegal pair_style command"); + + int iarg = 0; + + //Some defaults + normal_global = HERTZ; + damping_global = VISCOELASTIC; + tangential_global = TANGENTIAL_MINDLIN; + roll_global = ROLL_NONE; + twist_global = TWIST_NONE; + + tangential_history = 1; + roll_history = twist_history = 0; + + int normal_set, tangential_set; + normal_set = tangential_set = 0; + + while (iarg < narg){ + if (strcmp(arg[iarg], "hooke") == 0){ + if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); + normal_global = HOOKE; + normal_set = 1; + memory->create(normal_coeffs_global, 2, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += 3; + } + else if (strcmp(arg[iarg], "hertz") == 0){ + int num_coeffs = 2; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + normal_global = HERTZ; + normal_set = 1; + memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "hertz/material") == 0){ + int num_coeffs = 3; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + normal_global = HERTZ_MATERIAL; + normal_set = 1; + memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E (Young's modulus) + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (shear modulus) + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "dmt") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); + normal_global = DMT; + normal_set = 1; + memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //4/3 E + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "jkr") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for JKR option"); + beyond_contact = 1; + normal_global = JKR; + normal_set = 1; + memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); + normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "damp_velocity") == 0){ + damping_global = VELOCITY; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ + damping_global = VISCOELASTIC; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_tsuji") == 0){ + damping_global = TSUJI; + iarg += 1; + } + else if (strstr(arg[iarg], "tangential") != NULL){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + tangential_global = TANGENTIAL_NOHISTORY; + tangential_set = 1; + } + else if (strstr(arg[iarg+1], "mindlin") != NULL){ + tangential_global = TANGENTIAL_MINDLIN; + tangential_history = 1; + tangential_set = 1; + } + else{ + error->all(FLERR, "Illegal pair_style command, unrecognized sliding friction model"); + } + memory->create(tangential_coeffs_global, 3, "pair:tangential_coeffs_global"); + tangential_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + else if (strstr(arg[iarg], "roll") != NULL){ + if (strstr(arg[iarg+1], "none") != NULL){ + roll_global = ROLL_NONE; + iarg += 2; + } + else{ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + roll_global = ROLL_NOHISTORY; + } + else if (strstr(arg[iarg+1], "sds") != NULL){ + roll_global = ROLL_SDS; + roll_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_style command, unrecognized rolling friction model"); + } + memory->create(roll_coeffs_global, 3, "pair:roll_coeffs_global"); + roll_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + } + else if (strstr(arg[iarg], "twist") != NULL){ + if (strstr(arg[iarg+1], "none") != NULL){ + twist_global = TWIST_NONE; + iarg += 2; + } + else if (strstr(arg[iarg+1], "marshall") != NULL){ + twist_global = TWIST_MARSHALL; + twist_history = 1; + iarg += 2; + } + else{ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); + memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later + if (strstr(arg[iarg+1], "nohistory") != NULL){ + twist_global = TWIST_NOHISTORY; + } + else if (strstr(arg[iarg+1], "sds") != NULL){ + twist_global = TWIST_SDS; + twist_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_style command, unrecognized twisting friction model"); + } + memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); + twist_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //ktwist + twist_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammatwist + twist_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + } + else error->all(FLERR, "Illegal pair_style granular command"); + } + + //Set all i-i entries, which may be replaced by pair coeff commands + //It may also make sense to consider removing all of the above, and only + // having the option for pair_coeff to set the parameters, similar to most LAMMPS pair styles + // The reason for the current setup is to remain true to existing pair gran/hooke etc. syntax, + // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. + + //Other option is to have two pair styles, e.g. pair granular and pair granular/multi, + // where granular/multi allows per-type coefficients, pair granular does not (this would also + // allow minor speed-up by templating pair granular) + allocate(); + double damp; + for (int i = 1; i <= atom->ntypes; i++){ + normal[i][i] = normal_global; + damping[i][i] = damping_global; + tangential[i][i] = tangential_global; + roll[i][i] = roll_global; + twist[i][i] = twist_global; + + if (normal_set){ + if (damping_global == TSUJI){ + double cor = normal_coeffs_global[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_global[1]; + normal_coeffs[i][i][0] = normal_coeffs_global[0]; + normal_coeffs[i][i][1] = damp; + if (normal[i][i] != HOOKE && normal[i][i] != HERTZ){ + normal_coeffs[i][i][2] = normal_coeffs_global[2]; + } + if ((normal_global == JKR) || (normal_global == DMT)) + normal_coeffs[i][i][3] = normal_coeffs_global[3]; + } + if(tangential_set){ + tangential[i][i] = tangential_global; + for (int k = 0; k < 3; k++) + tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; + } + roll[i][i] = roll_global; + if (roll_global != ROLL_NONE) + for (int k = 0; k < 3; k++) + roll_coeffs[i][i][k] = roll_coeffs_global[k]; + + twist[i][i] = twist_global; + if (twist_global != TWIST_NONE && twist_global != TWIST_MARSHALL) + for (int k = 0; k < 3; k++) + twist_coeffs[i][i][k] = twist_coeffs_global[k]; + + if (normal_set && tangential_set) setflag[i][i] = 1; + } +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairGranularMulti::coeff(int narg, char **arg) +{ + int normal_local, damping_local, tangential_local, roll_local, twist_local; + double *normal_coeffs_local; + double *tangential_coeffs_local; + double *roll_coeffs_local; + double *twist_coeffs_local; + + normal_coeffs_local = new double[4]; + tangential_coeffs_local = new double[4]; + roll_coeffs_local = new double[4]; + twist_coeffs_local = new double[4]; + + if (narg < 2) + error->all(FLERR,"Incorrect args for pair coefficients"); + + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + normal_local = tangential_local = roll_local = twist_local = -1; + damping_local = -1; + + int iarg = 2; + while (iarg < narg){ + if (strcmp(arg[iarg], "hooke") == 0){ + if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); + normal_local = HOOKE; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += 3; + } + else if (strcmp(arg[iarg], "hertz") == 0){ + int num_coeffs = 2; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + normal_local = HERTZ; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "hertz/material") == 0){ + int num_coeffs = 3; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + normal_local = HERTZ; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "dmt") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + normal_local = DMT; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "jkr") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); + beyond_contact = 1; + normal_local = JKR; + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "damp_velocity") == 0){ + damping_local = VELOCITY; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ + damping_local = VISCOELASTIC; + iarg += 1; + } + else if (strcmp(arg[iarg], "damp_tsuji") == 0){ + damping_local = TSUJI; + iarg += 1; + } + else if (strstr(arg[iarg], "tangential") != NULL){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + tangential_local = TANGENTIAL_NOHISTORY; + } + else if (strstr(arg[iarg+1], "mindlin") != NULL){ + tangential_local = TANGENTIAL_MINDLIN; + tangential_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); + } + tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + else if (strstr(arg[iarg], "rolling") != NULL){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + if (strstr(arg[iarg+1], "none") != NULL){ + roll_local = ROLL_NONE; + iarg += 2; + } + else{ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + roll_local = ROLL_NOHISTORY; + } + else if (strstr(arg[iarg+1], "sds") != NULL){ + roll_local = ROLL_SDS; + roll_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); + } + roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + } + else if (strstr(arg[iarg], "twist") != NULL){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + if (strstr(arg[iarg+1], "none") != NULL){ + twist_local = TWIST_NONE; + iarg += 2; + } + else if (strstr(arg[iarg+1], "marshall") != NULL){ + twist_local = TWIST_MARSHALL; + twist_history = 1; + iarg += 2; + } + else{ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); + if (strstr(arg[iarg+1], "nohistory") != NULL){ + twist_local = TWIST_NOHISTORY; + } + else if (strstr(arg[iarg+1], "sds") != NULL){ + twist_local = TWIST_SDS; + twist_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); + } + twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + } + else error->all(FLERR, "Illegal pair coeff command"); + } + + int count = 0; + double damp; + if (damping_local >= 0){ + if (normal_local == -1) + error->all(FLERR, "Illegal pair_coeff command, must specify normal model when setting damping model"); + if (damping_local == TSUJI){ + double cor; + cor = normal_coeffs_local[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_local[1]; + } + + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + if (normal_local >= 0){ + normal[i][j] = normal_local; + normal_coeffs[i][j][0] = normal_coeffs_local[0]; + if (damping_local == -1){ + damp = normal_coeffs_global[1]; + } + normal_coeffs[i][j][1] = damp; + if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal_local == JKR) || (normal_local == DMT)) + normal_coeffs[i][j][3] = normal_coeffs_local[3]; + } + if (damping_local >= 0){ + damping[i][j] = damping_local; + } + if (tangential_local >= 0){ + tangential[i][j] = tangential_local; + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; + } + if (roll_local >= 0){ + roll[i][j] = roll_local; + if (roll_local != ROLL_NONE) + for (int k = 0; k < 3; k++) + roll_coeffs[i][j][k] = roll_coeffs_local[k]; + } + if (twist_local >= 0){ + twist[i][j] = twist_local; + if (twist_local != TWIST_NONE && twist_local != TWIST_MARSHALL) + for (int k = 0; k < 3; k++) + twist_coeffs[i][j][k] = twist_coeffs_local[k]; + } + + if (normal_local >= 0 && tangential_local >= 0) setflag[i][j] = 1; + + count++; + } + } + + delete[] normal_coeffs_local; + delete[] tangential_coeffs_local; + delete[] roll_coeffs_local; + delete[] twist_coeffs_local; + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairGranularMulti::init_style() +{ + int i; + + // error and warning checks + + if (!atom->radius_flag || !atom->rmass_flag) + error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); + + // Determine whether we need a granular neigh list, how large it needs to be + use_history = tangential_history || roll_history || twist_history; + + //For JKR, will need fix/neigh/history to keep track of touch arrays + for (int i = 1; i <= atom->ntypes; i++) + for (int j = 1; j <= atom->ntypes; j++) + if (normal[i][j] == JKR) use_history = 1; + + size_history = 3*tangential_history + 3*roll_history + twist_history; + + //Determine location of tangential/roll/twist histories in array + if (roll_history){ + if (tangential_history) roll_history_index = 3; + else roll_history_index = 0; + } + if (twist_history){ + if (tangential_history){ + if (roll_history) twist_history_index = 6; + else twist_history_index = 3; + } + else{ + if (roll_history) twist_history_index = 3; + else twist_history_index = 0; + } + } + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->size = 1; + if (use_history) neighbor->requests[irequest]->history = 1; + + dt = update->dt; + + // if history is stored: + // if first init, create Fix needed for storing history + + if (use_history && fix_history == NULL) { + char dnumstr[16]; + sprintf(dnumstr,"%d",size_history); + char **fixarg = new char*[4]; + fixarg[0] = (char *) "NEIGH_HISTORY"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "NEIGH_HISTORY"; + fixarg[3] = dnumstr; + modify->add_fix(4,fixarg,1); + delete [] fixarg; + fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; + fix_history->pair = this; + } + + // check for FixFreeze and set freeze_group_bit + + for (i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"freeze") == 0) break; + if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; + else freeze_group_bit = 0; + + // check for FixRigid so can extract rigid body masses + + fix_rigid = NULL; + for (i = 0; i < modify->nfix; i++) + if (modify->fix[i]->rigid_flag) break; + if (i < modify->nfix) fix_rigid = modify->fix[i]; + + // check for FixPour and FixDeposit so can extract particle radii + + int ipour; + for (ipour = 0; ipour < modify->nfix; ipour++) + if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; + if (ipour == modify->nfix) ipour = -1; + + int idep; + for (idep = 0; idep < modify->nfix; idep++) + if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; + if (idep == modify->nfix) idep = -1; + + // set maxrad_dynamic and maxrad_frozen for each type + // include future FixPour and FixDeposit particles as dynamic + + int itype; + for (i = 1; i <= atom->ntypes; i++) { + onerad_dynamic[i] = onerad_frozen[i] = 0.0; + if (ipour >= 0) { + itype = i; + double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); + if (normal[itype][itype] == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); + onerad_dynamic[i] = radmax; + } + if (idep >= 0) { + itype = i; + double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); + if (normal[itype][itype] == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); + onerad_dynamic[i] = radmax; + } + } + + double *radius = atom->radius; + int *mask = atom->mask; + int *type = atom->type; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++){ + double radius_cut = radius[i]; + if (normal[type[i]][type[i]] == JKR){ + radius_cut = radius[i] - 0.5*pulloff_distance(radius[i], type[i]); + } + if (mask[i] & freeze_group_bit){ + onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); + } + else{ + onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius_cut); + } + } + + MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + + // set fix which stores history info + + if (size_history > 0){ + int ifix = modify->find_fix("NEIGH_HISTORY"); + if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); + fix_history = (FixNeighHistory *) modify->fix[ifix]; + } +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairGranularMulti::init_one(int i, int j) +{ + double cutoff; + if (setflag[i][j] == 0) { + if ((normal[i][i] != normal[j][j]) || + (damping[i][i] != damping[j][j]) || + (tangential[i][i] != tangential[j][j]) || + (roll[i][i] != roll[j][j]) || + (twist[i][i] != twist[j][j])){ + + char str[512]; + sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); + error->one(FLERR,str); + } + + if (normal[i][j] != HOOKE && normal[i][j] != HERTZ){ + normal_coeffs[i][j][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][i][2], normal_coeffs[j][j][2]); + normal_coeffs[i][j][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][i][2], normal_coeffs[j][j][2]); + } + else{ + normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); + } + + normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); + if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) + normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); + + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); + + + if (roll[i][i] != ROLL_NONE){ + for (int k = 0; k < 3; k++) + roll_coeffs[i][j][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); + } + + if (twist[i][i] != TWIST_NONE && twist[i][i] != TWIST_MARSHALL){ + for (int k = 0; k < 3; k++) + twist_coeffs[i][j][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); + } + } + + // It is possible that cut[i][j] at this point is still 0.0. This can happen when + // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates + // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size + // To avoid this issue, for cases involving cut[i][j] = 0.0 (possible only + // if there is no current information about radius/cutoff of type i and j). + // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. + + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; + } + return cutoff; +} + + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file + ------------------------------------------------------------------------- */ + +void PairGranularMulti::write_restart(FILE *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(&normal[i][j],sizeof(int),1,fp); + fwrite(&damping[i][j],sizeof(int),1,fp); + fwrite(&tangential[i][j],sizeof(int),1,fp); + fwrite(&roll[i][j],sizeof(int),1,fp); + fwrite(&twist[i][j],sizeof(int),1,fp); + fwrite(&normal_coeffs[i][j],sizeof(double),4,fp); + fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); + fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); + fwrite(&twist_coeffs[i][j],sizeof(double),3,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts + ------------------------------------------------------------------------- */ + +void PairGranularMulti::read_restart(FILE *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(&normal[i][j],sizeof(int),1,fp); + fread(&damping[i][j],sizeof(int),1,fp); + fread(&tangential[i][j],sizeof(int),1,fp); + fread(&roll[i][j],sizeof(int),1,fp); + fread(&twist[i][j],sizeof(int),1,fp); + fread(&normal_coeffs[i][j],sizeof(double),4,fp); + fread(&tangential_coeffs[i][j],sizeof(double),3,fp); + fread(&roll_coeffs[i][j],sizeof(double),3,fp); + fread(&twist_coeffs[i][j],sizeof(double),3,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&normal[i][j],1,MPI_INT,0,world); + MPI_Bcast(&damping[i][j],1,MPI_INT,0,world); + MPI_Bcast(&tangential[i][j],1,MPI_INT,0,world); + MPI_Bcast(&roll[i][j],1,MPI_INT,0,world); + MPI_Bcast(&twist[i][j],1,MPI_INT,0,world); + MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); + MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&twist_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } + } +} + + +/* ---------------------------------------------------------------------- */ + +void PairGranularMulti::reset_dt() +{ + dt = update->dt; +} + +/* ---------------------------------------------------------------------- */ + +double PairGranularMulti::single(int i, int j, int itype, int jtype, + double rsq, double factor_coul, double factor_lj, double &fforce) +{ + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; + double dR, dR2; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + double knfac, damp_normal; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; + + //For JKR + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double delta, t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; + + + //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + + //Twisting + double k_twist, damp_twist, mu_twist; + double signtwist, magtwist, magtortwist, Mtcrit; + double tortwist1, tortwist2, tortwist3; + + double shrmag,rsht; + int jnum; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *history,*allhistory,**firsthistory; + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + Reff = radi*radj/(radi+radj); + + bool touchflag; + if (normal[itype][jtype] == JKR){ + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum+delta_pulloff; + touchflag = (rsq <= dist_pulloff*dist_pulloff); + } + else{ + touchflag = (rsq <= radsum*radsum); + } + + if (touchflag){ + fforce = 0.0; + for (int m = 0; m < single_extra; m++) svector[m] = 0.0; + return 0.0; + } + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + r = sqrt(rsq); + rinv = 1.0/r; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // relative translational velocity + + double **v = atom->v; + 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*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + double *rmass = atom->rmass; + int *mask = atom->mask; + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + int *type = atom->type; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + if (normal[itype][jtype] == JKR){ + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = FOURTHIRDS*E*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + else{ + knfac = E; + Fne = knfac*delta; + if (normal[itype][jtype] != HOOKE) + a = sqrt(dR); + Fne *= a; + if (normal[itype][jtype] == DMT) + Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; + } + + //Consider restricting Hooke to only have 'velocity' as an option for damping? + if (damping[itype][jtype] == VELOCITY){ + damp_normal = normal_coeffs[itype][jtype][1]; + } + else if (damping[itype][jtype] == VISCOELASTIC){ + if (normal[itype][jtype] == HOOKE) a = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*a*meff; + } + else if (damping[itype][jtype] == TSUJI){ + damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); + } + + Fdamp = -damp_normal*vnnr; + + Fntot = Fne + Fdamp; + + jnum = list->numneigh[i]; + jlist = list->firstneigh[i]; + + if (use_history){ + allhistory = fix_history->firstvalue[i]; + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + history = &allhistory[size_history*neighprev]; + } + + //**************************************** + //Tangential force, including history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + if (normal[itype][jtype] == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*F_pulloff); + } + else{ + Fcrit = fabs(Fne); + } + + //------------------------------ + //Tangential forces + //------------------------------ + k_tangential = tangential_coeffs[itype][jtype][0]; + if (normal[itype][jtype] != HOOKE){ + k_tangential *= a; + } + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + + if (tangential_history){ + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // tangential forces = history + tangential velocity damping + fs1 = -k_tangential*history[0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[2] - damp_tangential*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; + } + + //**************************************** + // Rolling resistance + //**************************************** + + if (roll[itype][jtype] != ROLL_NONE){ + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + if (roll_history){ + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; + } + } + + //**************************************** + // Twisting torque, including history effects + //**************************************** + if (twist[itype][jtype] != TWIST_NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (twist[itype][jtype] == TWIST_MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a; + } + else{ + k_twist = twist_coeffs[itype][jtype][0]; + damp_twist = twist_coeffs[itype][jtype][1]; + mu_twist = twist_coeffs[itype][jtype][2]; + } + if (twist_history){ + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; + } + } + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = fr1; + svector[5] = fr2; + svector[6] = fr3; + svector[7] = fr; + svector[8] = magtortwist; + return 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int PairGranularMulti::pack_forward_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++] = mass_rigid[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranularMulti::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + mass_rigid[i] = buf[m++]; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays + ------------------------------------------------------------------------- */ + +double PairGranularMulti::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} + +/* ---------------------------------------------------------------------- + mixing of Young's modulus (E) +------------------------------------------------------------------------- */ + +double PairGranularMulti::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); +} + +/* ---------------------------------------------------------------------- + mixing of shear modulus (G) + ------------------------------------------------------------------------- */ + +double PairGranularMulti::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); +} + +/* ---------------------------------------------------------------------- + mixing of everything else +------------------------------------------------------------------------- */ + +double PairGranularMulti::mix_geom(double valii, double valjj) +{ + return sqrt(valii*valjj); +} + + +/* ---------------------------------------------------------------------- + Compute pull-off distance (beyond contact) for a given radius and atom type +------------------------------------------------------------------------- */ + +double PairGranularMulti::pulloff_distance(double radius, int itype) +{ + double E, coh, a, delta_pulloff; + coh = normal_coeffs[itype][itype][3]; + E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], + normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); + a = cbrt(9*M_PI*coh*radius*radius/(4*E)); + return a*a/radius - 2*sqrt(M_PI*coh*a/E); +} + diff --git a/src/GRANULAR/pair_granular_multi.h b/src/GRANULAR/pair_granular_multi.h new file mode 100644 index 0000000000..e853e564df --- /dev/null +++ b/src/GRANULAR/pair_granular_multi.h @@ -0,0 +1,108 @@ +/* ---------------------------------------------------------- + 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(granular/multi,PairGranularMulti) + +#else + +#ifndef LMP_PAIR_GRANULAR_MULTI_H +#define LMP_PAIR_GRANULAR_MULTI_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairGranularMulti : public Pair { +public: + PairGranularMulti(class LAMMPS *); + virtual ~PairGranularMulti(); + virtual void compute(int, int); + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void reset_dt(); + virtual double single(int, int, int, int, double, double, double, double &); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + protected: + double cut_global; + double dt; + int freeze_group_bit; + int use_history; + + int neighprev; + double *onerad_dynamic,*onerad_frozen; + double *maxrad_dynamic,*maxrad_frozen; + double **cut; + + class FixNeighHistory *fix_history; + + // storage of rigid body masses for use in granular interactions + + class Fix *fix_rigid; // ptr to rigid body fix, NULL if none + double *mass_rigid; // rigid mass for owned+ghost atoms + int nmax; // allocated size of mass_rigid + + virtual void allocate(); + +private: + int size_history; + + //Per-type models + int **normal, **damping, **tangential, **roll, **twist; + + int normal_global, damping_global; + int tangential_global, roll_global, twist_global; + + int tangential_history, roll_history, twist_history; + int tangential_history_index; + int roll_history_index; + int twist_history_index; + + double *normal_coeffs_global; + double *tangential_coeffs_global; + double *roll_coeffs_global; + double *twist_coeffs_global; + + double ***normal_coeffs; + double ***tangential_coeffs; + double ***roll_coeffs; + double ***twist_coeffs; + + double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); + double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); + double mix_geom(double valii, double valjj); + double pulloff_distance(double radius, int itype); +}; + +} + +#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. + + */ diff --git a/src/fix_neigh_history.cpp b/src/fix_neigh_history.cpp index c21b494aa4..e33ebe57dc 100644 --- a/src/fix_neigh_history.cpp +++ b/src/fix_neigh_history.cpp @@ -408,7 +408,8 @@ void FixNeighHistory::pre_exchange_newton() m = npartner[j]++; partner[j][m] = tag[i]; jvalues = &valuepartner[j][dnum*m]; - for (n = 0; n < dnum; n++) jvalues[n] = -onevalues[n]; + if (pair->nondefault_history_transfer) pair->transfer_history(onevalues, jvalues); + else for (n = 0; n < dnum; n++) jvalues[n] = -onevalues[n]; } } } @@ -520,7 +521,8 @@ void FixNeighHistory::pre_exchange_no_newton() m = npartner[j]++; partner[j][m] = tag[i]; jvalues = &valuepartner[j][dnum*m]; - for (n = 0; n < dnum; n++) jvalues[n] = -onevalues[n]; + if (pair->nondefault_history_transfer) pair->transfer_history(onevalues, jvalues); + else for (n = 0; n < dnum; n++) jvalues[n] = -onevalues[n]; } } } @@ -604,7 +606,7 @@ void FixNeighHistory::post_neighbor() for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; - rflag = sbmask(j); + rflag = sbmask(j) | pair->beyond_contact; j &= NEIGHMASK; jlist[jj] = j; diff --git a/src/pair.h b/src/pair.h index 27b6d41eef..0911bff706 100644 --- a/src/pair.h +++ b/src/pair.h @@ -98,6 +98,8 @@ class Pair : protected Pointers { enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; // mixing options + int beyond_contact, nondefault_history_transfer; //for granular styles + // KOKKOS host/device flag and data masks ExecutionSpace execution_space; @@ -180,6 +182,7 @@ class Pair : protected Pointers { virtual void min_xf_pointers(int, double **, double **) {} virtual void min_xf_get(int) {} virtual void min_x_set(int) {} + virtual void transfer_history(double *, double*) {} // management of callbacks to be run from ev_tally() @@ -202,6 +205,7 @@ class Pair : protected Pointers { double tabinner; // inner cutoff for Coulomb table double tabinner_disp; // inner cutoff for dispersion table + public: // custom data type for accessing Coulomb tables -- GitLab From ef803be08e65999b2b1c657d32ec6187ec774569 Mon Sep 17 00:00:00 2001 From: dsbolin Date: Tue, 15 Jan 2019 10:18:46 -0700 Subject: [PATCH 0087/1243] Moved all model option syntax for pair granular to pair coeff command; added global cutoff option for pair style granular command; initial write-up of documentation. --- doc/src/pair_granular.txt | 332 +++++++++++++++++++++++ src/GRANULAR/pair_granular.cpp | 384 ++++++++------------------- src/GRANULAR/pair_granular.h | 15 +- src/GRANULAR/pair_granular_multi.cpp | 379 ++++++-------------------- src/GRANULAR/pair_granular_multi.h | 17 +- 5 files changed, 535 insertions(+), 592 deletions(-) create mode 100644 doc/src/pair_granular.txt diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt new file mode 100644 index 0000000000..19c16cc6ea --- /dev/null +++ b/doc/src/pair_granular.txt @@ -0,0 +1,332 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +pair_style granular command :h3 +pair_style granular/multi command :h3 + +[Syntax:] + +pair_style style cutoff :pre + +style = {granular} or {granular/multi} :ulb,l +cutoff = global cutoff (optional). See discussion below. + +[Examples:] + +pair_style granular +pair coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair coeff 2 2 hertz 200.0 20.0 tangential mindlin 300.0 50.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall + +pair_style granular/multi +pair coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair coeff 2 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall +pair coeff 1 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall + + +[Description:] + +The {granular} styles support a variety of options for the normal, tangential, rolling and twisting +forces resulting from contact between two granular particles. The computed force depends on the combination +of choices for these models. + +All model options and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. +Unlike e.g. "pair gran/hooke"_pair_gran.html, coefficient values are not global, but can be set to different values for +various combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. +In the case of {granular}, coefficients +can vary between particle types, but model choices cannot. For instance, in the first +example above, the stiffness, damping, and tangential friction are different for type 1 - type 1 and type 2 - type 2 interactions, but +both 1-1 and 2-2 interactions must have the same model form, hence all keywords are identical between the two types. Cross-coefficients +for 1-2 interactions for the case of the {hertz} model above are set via simple geometric mixing rules. The {granular/multi} +style removes this restriction at a small cost in computational efficiency, so that different particle types +can potentially interact via different model forms. As shown in the second example, +1-1 interactions are based on a Hertzian contact model and 2-2 interactions are based on a {dmt} model (see below). +In the case that 1-1 and 2-2 interactions have different model forms, mixing of coefficients cannot be +determined, so 1-2 interactions must be explicitly defined via the pair coeff command, otherwise an error results. + +The first required keyword for the pair coeff command is the normal contact model. Currently supported options and +the required arguments are: + +{hooke} : k_n, damping +{hertz} : k_n, damping +{hertz/material} : E, damping, G +{dmt} : E, damping, G, cohesion +{jkr} : E, damping, G, cohesion + +Here, k_n is spring stiffness, damping is a damping constant or a coefficient of restitution, depending on +the choice of damping model (see below), E and G are Young's modulus and shear modulus, in units of pressure, +and cohesion is a surface energy density, in units of energy/length^2. + +For the {hooke} model, the normal component of force is given by: +:c,image(Eqs/hooke_normal.jpg) + +For {hertz}, the normal force is given by: +:c,image{Eqs/hertz_normal.jpg} + +For both [hooke] and [hertz], stiffness for unspecified cross-terms is given by simple geometric mixing +(e.g. if stiffness is specified for type 1 and type 2 particles as k_n_1 and k_n_2, respectively, +type 1 - type 2 contacts use a stiffness given by k_n_{12} = sqrt(k_n_1*k_n_2)) + +For {hertz/material}, the form is the same as above, but coefficients are computed differently, and mixing follows +a different rule based on shear modulus: +:c,image{Eqs/hertz_material_normal.jpg} + +For {dmt}, the normal force is given by: +:c,image{Eqs/dmt_normal.jpg} + +Where gamma is cohesion. + +For {jkr}, the normal force is given by: +:c,image{Eqs/jkr_normal.jpg} + +The same mixing rule for stiffness as for {hertz/material} is used by both the {dmt} and {jkr} models. + +The tangential contact model must also be specified, which follows +the required {tangential} keyword. Currently supported options +and their required arguments are: + +{no_history}: k_t, tangential_damping, friction coefficient +{mindlin}: k_t, tangential_damping, friction coefficient + +For {no_history}, the tangential force is computed according to + +The total force on a particle is the sum of the normal and tangential forces from all interactions. The tangential +force also induces a torque on both particles in a contacting pair. Additionally, rolling and twisting friction +models can also be applied, which may induce additional torques (but no force). The following options are +supported for the rolling friction model + + +The first required keyword +in the pair coeff command is the choice +of normal force contact model, for which current opitons are {hooke}, {hertz} + +The {gran} styles use the following formulas for the frictional force +between two granular particles, as described in +"(Brilliantov)"_#Brilliantov, "(Silbert)"_#Silbert, and +"(Zhang)"_#Zhang3, when the distance r between two particles of radii +Ri and Rj is less than their contact distance d = Ri + Rj. There is +no force between the particles when r > d. + +The two Hookean styles use this formula: + +:c,image(Eqs/pair_gran_hooke.jpg) + +The Hertzian style uses this formula: + +:c,image(Eqs/pair_gran_hertz.jpg) + +In both equations the first parenthesized term is the normal force +between the two particles and the second parenthesized term is the +tangential force. The normal force has 2 terms, a contact force and a +damping force. The tangential force also has 2 terms: a shear force +and a damping force. The shear force is a "history" effect that +accounts for the tangential displacement between the particles for the +duration of the time they are in contact. This term is included in +pair styles {hooke/history} and {hertz/history}, but is not included +in pair style {hooke}. The tangential damping force term is included +in all three pair styles if {dampflag} is set to 1; it is not included +if {dampflag} is set to 0. + +The other quantities in the equations are as follows: + +delta = d - r = overlap distance of 2 particles +Kn = elastic constant for normal contact +Kt = elastic constant for tangential contact +gamma_n = viscoelastic damping constant for normal contact +gamma_t = viscoelastic damping constant for tangential contact +m_eff = Mi Mj / (Mi + Mj) = effective mass of 2 particles of mass Mi and Mj +Delta St = tangential displacement vector between 2 particles \ + which is truncated to satisfy a frictional yield criterion +n_ij = unit vector along the line connecting the centers of the 2 particles +Vn = normal component of the relative velocity of the 2 particles +Vt = tangential component of the relative velocity of the 2 particles :ul + +The Kn, Kt, gamma_n, and gamma_t coefficients are specified as +parameters to the pair_style command. If a NULL is used for Kt, then +a default value is used where Kt = 2/7 Kn. If a NULL is used for +gamma_t, then a default value is used where gamma_t = 1/2 gamma_n. + +The interpretation and units for these 4 coefficients are different in +the Hookean versus Hertzian equations. + +The Hookean model is one where the normal push-back force for two +overlapping particles is a linear function of the overlap distance. +Thus the specified Kn is in units of (force/distance). Note that this +push-back force is independent of absolute particle size (in the +monodisperse case) and of the relative sizes of the two particles (in +the polydisperse case). This model also applies to the other terms in +the force equation so that the specified gamma_n is in units of +(1/time), Kt is in units of (force/distance), and gamma_t is in units +of (1/time). + +The Hertzian model is one where the normal push-back force for two +overlapping particles is proportional to the area of overlap of the +two particles, and is thus a non-linear function of overlap distance. +Thus Kn has units of force per area and is thus specified in units of +(pressure). The effects of absolute particle size (monodispersity) +and relative size (polydispersity) are captured in the radii-dependent +pre-factors. When these pre-factors are carried through to the other +terms in the force equation it means that the specified gamma_n is in +units of (1/(time*distance)), Kt is in units of (pressure), and +gamma_t is in units of (1/(time*distance)). + +Note that in the Hookean case, Kn can be thought of as a linear spring +constant with units of force/distance. In the Hertzian case, Kn is +like a non-linear spring constant with units of force/area or +pressure, and as shown in the "(Zhang)"_#Zhang3 paper, Kn = 4G / +(3(1-nu)) where nu = the Poisson ratio, G = shear modulus = E / +(2(1+nu)), and E = Young's modulus. Similarly, Kt = 4G / (2-nu). +(NOTE: in an earlier version of the manual, we incorrectly stated that +Kt = 8G / (2-nu).) + +Thus in the Hertzian case Kn and Kt can be set to values that +corresponds to properties of the material being modeled. This is also +true in the Hookean case, except that a spring constant must be chosen +that is appropriate for the absolute size of particles in the model. +Since relative particle sizes are not accounted for, the Hookean +styles may not be a suitable model for polydisperse systems. + +NOTE: In versions of LAMMPS before 9Jan09, the equation for Hertzian +interactions did not include the sqrt(RiRj/Ri+Rj) term and thus was +not as accurate for polydisperse systems. For monodisperse systems, +sqrt(RiRj/Ri+Rj) is a constant factor that effectively scales all 4 +coefficients: Kn, Kt, gamma_n, gamma_t. Thus you can set the values +of these 4 coefficients appropriately in the current code to reproduce +the results of a previous Hertzian monodisperse calculation. For +example, for the common case of a monodisperse system with particles +of diameter 1, all 4 of these coefficients should now be set 2x larger +than they were previously. + +Xmu is also specified in the pair_style command and is the upper limit +of the tangential force through the Coulomb criterion Ft = xmu*Fn, +where Ft and Fn are the total tangential and normal force components +in the formulas above. Thus in the Hookean case, the tangential force +between 2 particles grows according to a tangential spring and +dash-pot model until Ft/Fn = xmu and is then held at Ft = Fn*xmu until +the particles lose contact. In the Hertzian case, a similar analogy +holds, though the spring is no longer linear. + +NOTE: Normally, xmu should be specified as a fractional value between +0.0 and 1.0, however LAMMPS allows large values (up to 1.0e4) to allow +for modeling of systems which can sustain very large tangential +forces. + +The effective mass {m_eff} is given by the formula above for two +isolated particles. If either particle is part of a rigid body, its +mass is replaced by the mass of the rigid body in the formula above. +This is determined by searching for a "fix rigid"_fix_rigid.html +command (or its variants). + +For granular styles there are no additional coefficients to set for +each pair of atom types via the "pair_coeff"_pair_coeff.html command. +All settings are global and are made via the pair_style command. +However you must still use the "pair_coeff"_pair_coeff.html for all +pairs of granular atom types. For example the command + +pair_coeff * * :pre + +should be used if all atoms in the simulation interact via a granular +potential (i.e. one of the pair styles above is used). If a granular +potential is used as a sub-style of "pair_style +hybrid"_pair_hybrid.html, then specific atom types can be used in the +pair_coeff command to determine which atoms interact via a granular +potential. + +:line + +Styles with a {gpu}, {intel}, {kk}, {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 on the "Speed packages"_Speed_packages.html doc +page. 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 GPU, USER-INTEL, KOKKOS, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the "Build +package"_Build_package.html doc page 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"_Run_options.html when you invoke LAMMPS, or you can use the +"suffix"_suffix.html command in your input script. + +See the "Speed packages"_Speed_packages.html doc page for more +instructions on how to use the accelerated styles effectively. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +The "pair_modify"_pair_modify.html mix, shift, table, and tail options +are not relevant for granular pair styles. + +These pair styles write their information to "binary restart +files"_restart.html, so a pair_style command does not need to be +specified in an input script that reads a restart file. + +These pair styles can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. They do not support the +{inner}, {middle}, {outer} keywords. + +The single() function of these pair styles returns 0.0 for the energy +of a pairwise interaction, since energy is not conserved in these +dissipative potentials. It also returns only the normal component of +the pairwise interaction force. However, the single() function also +calculates 10 extra pairwise quantities. The first 3 are the +components of the tangential force between particles I and J, acting +on particle I. The 4th is the magnitude of this tangential force. +The next 3 (5-7) are the components of the relative velocity in the +normal direction (along the line joining the 2 sphere centers). The +last 3 (8-10) the components of the relative velocity in the +tangential direction. + +These extra quantities can be accessed by the "compute +pair/local"_compute_pair_local.html command, as {p1}, {p2}, ..., +{p10}. + +:line + +[Restrictions:] + +All the granular pair styles are part of the GRANULAR package. It is +only enabled if LAMMPS was built with that package. See the "Build +package"_Build_package.html doc page for more info. + +These pair styles require that atoms store torque and angular velocity +(omega) as defined by the "atom_style"_atom_style.html. They also +require a per-particle radius is stored. The {sphere} atom style does +all of this. + +This pair style requires you to use the "comm_modify vel +yes"_comm_modify.html command so that velocities are stored by ghost +atoms. + +These pair styles will not restart exactly when using the +"read_restart"_read_restart.html command, though they should provide +statistically similar results. This is because the forces they +compute depend on atom velocities. See the +"read_restart"_read_restart.html command for more details. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] none + +:line + +:link(Brilliantov) +[(Brilliantov)] Brilliantov, Spahn, Hertzsch, Poschel, Phys Rev E, 53, +p 5382-5392 (1996). + +:link(Silbert) +[(Silbert)] Silbert, Ertas, Grest, Halsey, Levine, Plimpton, Phys Rev +E, 64, p 051302 (2001). + +:link(Zhang3) +[(Zhang)] Zhang and Makse, Phys Rev E, 72, p 011301 (2005). diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index c75c80fea5..9fe4bd8415 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -1360,205 +1360,15 @@ void PairGranular::allocate() void PairGranular::settings(int narg, char **arg) { - if (narg < 5) error->all(FLERR,"Illegal pair_style command"); - - int iarg = 0; - - //Some defaults - normal = HERTZ; - damping = VISCOELASTIC; - tangential = TANGENTIAL_MINDLIN; - roll = ROLL_NONE; - twist = TWIST_NONE; - - tangential_history = 1; - roll_history = twist_history = 0; - - int normal_set, tangential_set; - normal_set = tangential_set = 0; - - while (iarg < narg){ - if (strcmp(arg[iarg], "hooke") == 0){ - if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); - normal = HOOKE; - memory->create(normal_coeffs_global, 2, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - iarg += 3; - } - else if (strcmp(arg[iarg], "hertz") == 0){ - int num_coeffs = 2; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal = HERTZ; - normal_set = 1; - memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "hertz/material") == 0){ - int num_coeffs = 3; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal = HERTZ_MATERIAL; - normal_set = 1; - memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E (Young's modulus) - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (shear modulus) - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "dmt") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal = DMT; - normal_set = 1; - memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //4/3 E - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion - iarg += 5; - } - else if (strcmp(arg[iarg], "jkr") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for JKR option"); - beyond_contact = 1; - normal = JKR; - normal_set = 1; - memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion - iarg += 5; - } - else if (strcmp(arg[iarg], "damp_velocity") == 0){ - damping = VELOCITY; - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ - damping = VISCOELASTIC; - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_tsuji") == 0){ - damping = TSUJI; - iarg += 1; - } - else if (strstr(arg[iarg], "tangential") != NULL){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - tangential = TANGENTIAL_NOHISTORY; - tangential_set = 1; - } - else if (strstr(arg[iarg+1], "mindlin") != NULL){ - tangential = TANGENTIAL_MINDLIN; - tangential_history = 1; - tangential_set = 1; - } - else{ - error->all(FLERR, "Illegal pair_style command, unrecognized sliding friction model"); - } - memory->create(tangential_coeffs_global, 3, "pair:tangential_coeffs_global"); - tangential_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kt - tangential_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - else if (strstr(arg[iarg], "roll") != NULL){ - if (strstr(arg[iarg+1], "none") != NULL){ - roll = ROLL_NONE; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - roll = ROLL_NOHISTORY; - } - else if (strstr(arg[iarg+1], "sds") != NULL){ - roll = ROLL_SDS; - roll_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_style command, unrecognized rolling friction model"); - } - memory->create(roll_coeffs_global, 3, "pair:roll_coeffs_global"); - roll_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kR - roll_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR - roll_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - } - else if (strstr(arg[iarg], "twist") != NULL){ - if (strstr(arg[iarg+1], "none") != NULL){ - twist = TWIST_NONE; - iarg += 2; - } - else if (strstr(arg[iarg+1], "marshall") != NULL){ - twist = TWIST_MARSHALL; - twist_history = 1; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); - memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later - if (strstr(arg[iarg+1], "nohistory") != NULL){ - twist = TWIST_NOHISTORY; - } - else if (strstr(arg[iarg+1], "sds") != NULL){ - twist = TWIST_SDS; - twist_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_style command, unrecognized twisting friction model"); - } - memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); - twist_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //ktwist - twist_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammatwist - twist_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - } - else error->all(FLERR, "Illegal pair_style granular command"); + if (narg == 1){ + cutoff_global = force->numeric(FLERR,arg[0]) } - - //Set all i-i entries, which may be replaced by pair coeff commands - //It may also make sense to consider removing all of the above, and only - // having the option for pair_coeff to set the parameters, similar to most LAMMPS pair styles - // The reason for the current setup is to remain true to existing pair gran/hooke etc. syntax, - // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. - - allocate(); - double damp; - if (damping == TSUJI){ - double cor = normal_coeffs_global[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_global[1]; - - for (int i = 1; i <= atom->ntypes; i++){ - if (normal_set){ - normal_coeffs[i][i][0] = normal_coeffs_global[0]; - normal_coeffs[i][i][1] = damp; - if (normal != HOOKE && normal != HERTZ){ - normal_coeffs[i][i][2] = normal_coeffs_global[2]; - } - if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][i][3] = normal_coeffs_global[3]; - } - if(tangential_set){ - for (int k = 0; k < 3; k++) - tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; - } - if (roll != ROLL_NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][i][k] = roll_coeffs_global[k]; - - if (twist != TWIST_NONE && twist != TWIST_MARSHALL) - for (int k = 0; k < 3; k++) - twist_coeffs[i][i][k] = twist_coeffs_global[k]; - - if (normal_set && tangential_set) setflag[i][i] = 1; + else{ + cutoff_global = -1; //Will be set based on particle sizes, model choice } + tangential_history = 0; + roll_history = twist_history = 0; + normal_set = tangential_set = damping_set = roll_set = twist_set = 0; } /* ---------------------------------------------------------------------- @@ -1567,12 +1377,6 @@ void PairGranular::settings(int narg, char **arg) void PairGranular::coeff(int narg, char **arg) { - int normal_set, damping_set, tangential_set, roll_set, twist_set; - double *normal_coeffs_local; - double *tangential_coeffs_local; - double *roll_coeffs_local; - double *twist_coeffs_local; - normal_coeffs_local = new double[4]; tangential_coeffs_local = new double[4]; roll_coeffs_local = new double[4]; @@ -1587,13 +1391,12 @@ void PairGranular::coeff(int narg, char **arg) force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - normal_set = damping_set = tangential_set = roll_set = twist_set = 0; - int iarg = 2; while (iarg < narg){ if (strcmp(arg[iarg], "hooke") == 0){ if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); - if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); + if (!normal_set) normal = HOOKE; + else if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_set = 1; @@ -1602,7 +1405,8 @@ void PairGranular::coeff(int narg, char **arg) else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); + if (!normal_set) normal = HERTZ; + else if (normal_set && normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_set = 1; @@ -1611,7 +1415,8 @@ void PairGranular::coeff(int narg, char **arg) else if (strcmp(arg[iarg], "hertz/material") == 0){ int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); + if (!normal_set) normal = HERTZ/MATERIAL; + else if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G @@ -1620,7 +1425,8 @@ void PairGranular::coeff(int narg, char **arg) } else if (strcmp(arg[iarg], "dmt") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (normal != DMT) if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); + if (!normal_set) normal = DMT; + else if (normal != DMT) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G @@ -1631,7 +1437,8 @@ void PairGranular::coeff(int narg, char **arg) else if (strcmp(arg[iarg], "jkr") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); beyond_contact = 1; - if (normal != JKR) if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be consistent"); + if (!normal_set) normal = JKR; + else if (normal != JKR) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G @@ -1639,25 +1446,32 @@ void PairGranular::coeff(int narg, char **arg) normal_set = 1; iarg += 5; } - else if (strcmp(arg[iarg], "damp_velocity") == 0){ - if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be consistent"); - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ - if (damping != VISCOELASTIC) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be consistent"); - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_tsuji") == 0){ - if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be consistent"); + else if (strcmp(arg[iarg], "damp") == 0){ + if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); + if (strcmp(arg[iarg+1]), "velocity") == 0){ + if (!damping_set) damping = VELOCITY; + else if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ + if (!damping_set) damping = VISCOELASTIC; + else if (damping != VISCOELASTIC) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "tsuji") == 0){ + if (!damping_set) damping = TSUJI; + if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + } + damping_set = 1; iarg += 1; } - else if (strstr(arg[iarg], "tangential") != NULL){ + else if (strcmp(arg[iarg], "tangential") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - if (tangential != TANGENTIAL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be consistent"); + if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (!tangential_set) tangential = TANGENTIAL_NOHISTORY; + else if (tangential != TANGENTIAL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types"); } - else if (strstr(arg[iarg+1], "mindlin") != NULL){ - if (tangential != TANGENTIAL_MINDLIN) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be consistent");; + else if (strcmp(arg[iarg+1], "mindlin") == 0){ + if (!tangential_set) tangential = TANGENTIAL_MINDLIN; + else if (tangential != TANGENTIAL_MINDLIN) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types");; tangential_history = 1; } else{ @@ -1669,19 +1483,22 @@ void PairGranular::coeff(int narg, char **arg) tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; } - else if (strstr(arg[iarg], "rolling") != NULL){ + else if (strcmp(arg[iarg], "rolling") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strstr(arg[iarg+1], "none") != NULL){ - if (roll != ROLL_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be consistent"); + if (strcmp(arg[iarg+1], "none") == 0){ + if (!roll_set) roll = ROLL_NONE; + else if (roll != ROLL_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - if (roll != ROLL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be consistent"); + if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (!roll_set) roll = ROLL_NOHISTORY; + else if (roll != ROLL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); } - else if (strstr(arg[iarg+1], "sds") != NULL){ - if (roll != ROLL_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be consistent"); + else if (strcmp(arg[iarg+1], "sds") == 0){ + if (!roll_set) roll = ROLL_SDS; + else if (roll != ROLL_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); roll_history = 1; } else{ @@ -1694,24 +1511,28 @@ void PairGranular::coeff(int narg, char **arg) iarg += 5; } } - else if (strstr(arg[iarg], "twist") != NULL){ + else if (strcmp(arg[iarg], "twisting") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strstr(arg[iarg+1], "none") != NULL){ - if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); + if (strcmp(arg[iarg+1], "none") == 0){ + if (!twist_set) twist = TWIST_NOHISTORY; + else if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); iarg += 2; } - else if (strstr(arg[iarg+1], "marshall") != NULL){ - if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); + else if (strcmp(arg[iarg+1], "marshall") == 0){ + if (!twist_set) twist = TWIST_MARSHALL; + else if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); twist_history = 1; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); + if (!twist_set) twist = TWIST_NOHISTORY; + else if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); } - else if (strstr(arg[iarg+1], "sds") != NULL){ - if (twist != TWIST_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be consistent"); + else if (strcmp(arg[iarg+1], "sds") == 0){ + if (!twist_set) twist = TWIST_SDS; + else if (twist != TWIST_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); twist_history = 1; } else{ @@ -1727,6 +1548,15 @@ void PairGranular::coeff(int narg, char **arg) else error->all(FLERR, "Illegal pair coeff command"); } + //It is an error not to specify normal or tangential model + if (!normal_set) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); + if (!tangential_set) error->all(FLERR, "Illegal pair coeff command, must specify tangential contact model"); + + //If unspecified, set damping to VISCOELASTIC, twist/roll to NONE (cannot be changed by subsequent pair_coeff commands) + if (!damping_set) damping = VISCOELASTIC; + if (!roll_set) roll = ROLL_NONE; + if (!twist_set) twist = TWIST_NONE; + int count = 0; double damp; if (damping == TSUJI){ @@ -1740,37 +1570,28 @@ void PairGranular::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - if (normal_set){ - normal_coeffs[i][j][0] = normal_coeffs_local[0]; - normal_coeffs[i][j][1] = damp; - if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][j][3] = normal_coeffs_local[3]; - } - if (tangential_set){ + normal_coeffs[i][j][0] = normal_coeffs_local[0]; + normal_coeffs[i][j][1] = damp; + if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal == JKR) || (normal == DMT)) + normal_coeffs[i][j][3] = normal_coeffs_local[3]; + + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; + + if (roll != ROLL_NONE) for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; - } - if (roll_set){ - if (roll != ROLL_NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs_local[k]; - } - if (twist_set){ - if (twist != TWIST_NONE && twist != TWIST_MARSHALL) - for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs_local[k]; - } + roll_coeffs[i][j][k] = roll_coeffs_local[k]; + + if (twist != TWIST_NONE && twist != TWIST_MARSHALL) + for (int k = 0; k < 3; k++) + twist_coeffs[i][j][k] = twist_coeffs_local[k]; + setflag[i][j] = 1; count++; } } - delete[] normal_coeffs_local; - delete[] tangential_coeffs_local; - delete[] roll_coeffs_local; - delete[] twist_coeffs_local; - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -1959,20 +1780,25 @@ double PairGranular::init_one(int i, int j) // if there is no current information about radius/cutoff of type i and j). // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || - ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + if (cutoff_global < 0){ + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; } - cutoff = cutmax; + } + else{ + cutoff = cutoff_global; } return cutoff; } diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 897316c907..f3a9d4dcbe 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -86,19 +86,18 @@ private: //Indices of history entries int tangential_history_index, roll_history_index, twist_history_index; - //Coefficients declared in pair style command, used as default unless - // overwritten in pair coeff command - double *normal_coeffs_global; - double *tangential_coeffs_global; - double *roll_coeffs_global; - double *twist_coeffs_global; - - //Per-type coefficients declared in pair coeff command + //Flags for whether model choices have been set + int normal_set, tangential_set, damping_set, roll_set, twist_set; + + //Per-type coefficients, set in pair coeff command double ***normal_coeffs; double ***tangential_coeffs; double ***roll_coeffs; double ***twist_coeffs; + //Optional user-specified global cutoff + double global_cutoff; + double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); double mix_geom(double valii, double valjj); diff --git a/src/GRANULAR/pair_granular_multi.cpp b/src/GRANULAR/pair_granular_multi.cpp index 11381444a2..5fee363872 100644 --- a/src/GRANULAR/pair_granular_multi.cpp +++ b/src/GRANULAR/pair_granular_multi.cpp @@ -654,217 +654,15 @@ void PairGranularMulti::allocate() void PairGranularMulti::settings(int narg, char **arg) { - if (narg < 5) error->all(FLERR,"Illegal pair_style command"); - - int iarg = 0; - - //Some defaults - normal_global = HERTZ; - damping_global = VISCOELASTIC; - tangential_global = TANGENTIAL_MINDLIN; - roll_global = ROLL_NONE; - twist_global = TWIST_NONE; - - tangential_history = 1; - roll_history = twist_history = 0; - - int normal_set, tangential_set; - normal_set = tangential_set = 0; - - while (iarg < narg){ - if (strcmp(arg[iarg], "hooke") == 0){ - if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hooke option"); - normal_global = HOOKE; - normal_set = 1; - memory->create(normal_coeffs_global, 2, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - iarg += 3; - } - else if (strcmp(arg[iarg], "hertz") == 0){ - int num_coeffs = 2; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal_global = HERTZ; - normal_set = 1; - memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "hertz/material") == 0){ - int num_coeffs = 3; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal_global = HERTZ_MATERIAL; - normal_set = 1; - memory->create(normal_coeffs_global, num_coeffs, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E (Young's modulus) - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G (shear modulus) - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "dmt") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for Hertz option"); - normal_global = DMT; - normal_set = 1; - memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //4/3 E - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion - iarg += 5; - } - else if (strcmp(arg[iarg], "jkr") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for JKR option"); - beyond_contact = 1; - normal_global = JKR; - normal_set = 1; - memory->create(normal_coeffs_global, 4, "pair:normal_coeffs_global"); - normal_coeffs_global[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_global[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_global[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_global[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion - iarg += 5; - } - else if (strcmp(arg[iarg], "damp_velocity") == 0){ - damping_global = VELOCITY; - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ - damping_global = VISCOELASTIC; - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_tsuji") == 0){ - damping_global = TSUJI; - iarg += 1; - } - else if (strstr(arg[iarg], "tangential") != NULL){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for tangential model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - tangential_global = TANGENTIAL_NOHISTORY; - tangential_set = 1; - } - else if (strstr(arg[iarg+1], "mindlin") != NULL){ - tangential_global = TANGENTIAL_MINDLIN; - tangential_history = 1; - tangential_set = 1; - } - else{ - error->all(FLERR, "Illegal pair_style command, unrecognized sliding friction model"); - } - memory->create(tangential_coeffs_global, 3, "pair:tangential_coeffs_global"); - tangential_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kt - tangential_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - tangential_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - else if (strstr(arg[iarg], "roll") != NULL){ - if (strstr(arg[iarg+1], "none") != NULL){ - roll_global = ROLL_NONE; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for rolling model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ - roll_global = ROLL_NOHISTORY; - } - else if (strstr(arg[iarg+1], "sds") != NULL){ - roll_global = ROLL_SDS; - roll_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_style command, unrecognized rolling friction model"); - } - memory->create(roll_coeffs_global, 3, "pair:roll_coeffs_global"); - roll_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //kR - roll_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR - roll_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - } - else if (strstr(arg[iarg], "twist") != NULL){ - if (strstr(arg[iarg+1], "none") != NULL){ - twist_global = TWIST_NONE; - iarg += 2; - } - else if (strstr(arg[iarg+1], "marshall") != NULL){ - twist_global = TWIST_MARSHALL; - twist_history = 1; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_style command, not enough parameters provided for twist model"); - memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); //To be filled later - if (strstr(arg[iarg+1], "nohistory") != NULL){ - twist_global = TWIST_NOHISTORY; - } - else if (strstr(arg[iarg+1], "sds") != NULL){ - twist_global = TWIST_SDS; - twist_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_style command, unrecognized twisting friction model"); - } - memory->create(twist_coeffs_global, 3, "pair:twist_coeffs_global"); - twist_coeffs_global[0] = force->numeric(FLERR,arg[iarg+2]); //ktwist - twist_coeffs_global[1] = force->numeric(FLERR,arg[iarg+3]); //gammatwist - twist_coeffs_global[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - } - else error->all(FLERR, "Illegal pair_style granular command"); + if (narg == 1){ + cutoff_global = force->numeric(FLERR,arg[0]) } - - //Set all i-i entries, which may be replaced by pair coeff commands - //It may also make sense to consider removing all of the above, and only - // having the option for pair_coeff to set the parameters, similar to most LAMMPS pair styles - // The reason for the current setup is to remain true to existing pair gran/hooke etc. syntax, - // where coeffs are set in the pair_style command, and a pair_coeff * * command is issued. - - //Other option is to have two pair styles, e.g. pair granular and pair granular/multi, - // where granular/multi allows per-type coefficients, pair granular does not (this would also - // allow minor speed-up by templating pair granular) - allocate(); - double damp; - for (int i = 1; i <= atom->ntypes; i++){ - normal[i][i] = normal_global; - damping[i][i] = damping_global; - tangential[i][i] = tangential_global; - roll[i][i] = roll_global; - twist[i][i] = twist_global; - - if (normal_set){ - if (damping_global == TSUJI){ - double cor = normal_coeffs_global[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_global[1]; - normal_coeffs[i][i][0] = normal_coeffs_global[0]; - normal_coeffs[i][i][1] = damp; - if (normal[i][i] != HOOKE && normal[i][i] != HERTZ){ - normal_coeffs[i][i][2] = normal_coeffs_global[2]; - } - if ((normal_global == JKR) || (normal_global == DMT)) - normal_coeffs[i][i][3] = normal_coeffs_global[3]; - } - if(tangential_set){ - tangential[i][i] = tangential_global; - for (int k = 0; k < 3; k++) - tangential_coeffs[i][i][k] = tangential_coeffs_global[k]; - } - roll[i][i] = roll_global; - if (roll_global != ROLL_NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][i][k] = roll_coeffs_global[k]; - - twist[i][i] = twist_global; - if (twist_global != TWIST_NONE && twist_global != TWIST_MARSHALL) - for (int k = 0; k < 3; k++) - twist_coeffs[i][i][k] = twist_coeffs_global[k]; - - if (normal_set && tangential_set) setflag[i][i] = 1; + else{ + cutoff_global = -1; //Will be set based on particle sizes, model choice } + + tangential_history = 0; + roll_history = twist_history = 0; } /* ---------------------------------------------------------------------- @@ -874,10 +672,6 @@ void PairGranularMulti::settings(int narg, char **arg) void PairGranularMulti::coeff(int narg, char **arg) { int normal_local, damping_local, tangential_local, roll_local, twist_local; - double *normal_coeffs_local; - double *tangential_coeffs_local; - double *roll_coeffs_local; - double *twist_coeffs_local; normal_coeffs_local = new double[4]; tangential_coeffs_local = new double[4]; @@ -893,8 +687,10 @@ void PairGranularMulti::coeff(int narg, char **arg) force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - normal_local = tangential_local = roll_local = twist_local = -1; - damping_local = -1; + //Defaults + normal_local = tangential_local = -1; + roll_local = twist_local = 0; + damping_local = VISCOELASTIC; int iarg = 2; while (iarg < narg){ @@ -941,24 +737,27 @@ void PairGranularMulti::coeff(int narg, char **arg) normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; } - else if (strcmp(arg[iarg], "damp_velocity") == 0){ - damping_local = VELOCITY; - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_viscoelastic") == 0){ - damping_local = VISCOELASTIC; - iarg += 1; - } - else if (strcmp(arg[iarg], "damp_tsuji") == 0){ - damping_local = TSUJI; - iarg += 1; + else if (strcmp(arg[iarg], "damp") == 0){ + if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); + if (strcmp(arg[iarg+1]), "velocity") == 0){ + damping_local = VELOCITY; + iarg += 1; + } + else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ + damping_local = VISCOELASTIC; + iarg += 1; + } + else if (strcmp(arg[iarg], "tsuji") == 0){ + damping_local = TSUJI; + iarg += 1; + } } - else if (strstr(arg[iarg], "tangential") != NULL){ + else if (strcmp(arg[iarg], "tangential") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ + if (strcmp(arg[iarg+1], "nohistory") == 0){ tangential_local = TANGENTIAL_NOHISTORY; } - else if (strstr(arg[iarg+1], "mindlin") != NULL){ + else if (strcmp(arg[iarg+1], "mindlin") == 0){ tangential_local = TANGENTIAL_MINDLIN; tangential_history = 1; } @@ -970,18 +769,18 @@ void PairGranularMulti::coeff(int narg, char **arg) tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; } - else if (strstr(arg[iarg], "rolling") != NULL){ + else if (strcmp(arg[iarg], "rolling") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strstr(arg[iarg+1], "none") != NULL){ + if (strcmp(arg[iarg+1], "none") == 0){ roll_local = ROLL_NONE; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ + if (strcmp(arg[iarg+1], "nohistory") == 0){ roll_local = ROLL_NOHISTORY; } - else if (strstr(arg[iarg+1], "sds") != NULL){ + else if (strcmp(arg[iarg+1], "sds") == 0){ roll_local = ROLL_SDS; roll_history = 1; } @@ -994,23 +793,23 @@ void PairGranularMulti::coeff(int narg, char **arg) iarg += 5; } } - else if (strstr(arg[iarg], "twist") != NULL){ + else if (strcmp(arg[iarg], "twisting") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strstr(arg[iarg+1], "none") != NULL){ + if (strcmp(arg[iarg+1], "none") == 0){ twist_local = TWIST_NONE; iarg += 2; } - else if (strstr(arg[iarg+1], "marshall") != NULL){ + else if (strcmp(arg[iarg+1], "marshall") == 0){ twist_local = TWIST_MARSHALL; twist_history = 1; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - if (strstr(arg[iarg+1], "nohistory") != NULL){ + if (strcmp(arg[iarg+1], "nohistory") == 0){ twist_local = TWIST_NOHISTORY; } - else if (strstr(arg[iarg+1], "sds") != NULL){ + else if (strcmp(arg[iarg+1], "sds") == 0){ twist_local = TWIST_SDS; twist_history = 1; } @@ -1026,66 +825,49 @@ void PairGranularMulti::coeff(int narg, char **arg) else error->all(FLERR, "Illegal pair coeff command"); } + //It is an error not to specify normal or tangential model + if ((normal_set < 0) || (tangential_set < 0)) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model");)) + int count = 0; double damp; - if (damping_local >= 0){ - if (normal_local == -1) - error->all(FLERR, "Illegal pair_coeff command, must specify normal model when setting damping model"); - if (damping_local == TSUJI){ - double cor; - cor = normal_coeffs_local[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_local[1]; + if (damping_local == TSUJI){ + double cor; + cor = normal_coeffs_local[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); } + else damp = normal_coeffs_local[1]; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - if (normal_local >= 0){ - normal[i][j] = normal_local; - normal_coeffs[i][j][0] = normal_coeffs_local[0]; - if (damping_local == -1){ - damp = normal_coeffs_global[1]; - } - normal_coeffs[i][j][1] = damp; - if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal_local == JKR) || (normal_local == DMT)) - normal_coeffs[i][j][3] = normal_coeffs_local[3]; - } - if (damping_local >= 0){ - damping[i][j] = damping_local; - } - if (tangential_local >= 0){ - tangential[i][j] = tangential_local; + normal[i][j] = normal_local; + normal_coeffs[i][j][0] = normal_coeffs_local[0]; + normal_coeffs[i][j][1] = damp; + if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal_local == JKR) || (normal_local == DMT)) + normal_coeffs[i][j][3] = normal_coeffs_local[3]; + + damping[i][j] = damping_local; + + tangential[i][j] = tangential_local; for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; - } - if (roll_local >= 0){ - roll[i][j] = roll_local; - if (roll_local != ROLL_NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs_local[k]; - } - if (twist_local >= 0){ - twist[i][j] = twist_local; + + roll[i][j] = roll_local; + if (roll_local != ROLL_NONE) + for (int k = 0; k < 3; k++) + roll_coeffs[i][j][k] = roll_coeffs_local[k]; + + twist[i][j] = twist_local; if (twist_local != TWIST_NONE && twist_local != TWIST_MARSHALL) for (int k = 0; k < 3; k++) twist_coeffs[i][j][k] = twist_coeffs_local[k]; - } - - if (normal_local >= 0 && tangential_local >= 0) setflag[i][j] = 1; + setflag[i][j] = 1; count++; } } - - delete[] normal_coeffs_local; - delete[] tangential_coeffs_local; - delete[] roll_coeffs_local; - delete[] twist_coeffs_local; - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -1286,20 +1068,25 @@ double PairGranularMulti::init_one(int i, int j) // if there is no current information about radius/cutoff of type i and j). // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || - ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + if (cutoff_global < 0){ + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; } - cutoff = cutmax; + } + else{ + cutoff = cutoff_global; } return cutoff; } diff --git a/src/GRANULAR/pair_granular_multi.h b/src/GRANULAR/pair_granular_multi.h index e853e564df..95beb950f4 100644 --- a/src/GRANULAR/pair_granular_multi.h +++ b/src/GRANULAR/pair_granular_multi.h @@ -65,27 +65,26 @@ public: private: int size_history; - //Per-type models + //Models int **normal, **damping, **tangential, **roll, **twist; - int normal_global, damping_global; - int tangential_global, roll_global, twist_global; - + //History flags int tangential_history, roll_history, twist_history; + + //Indices of history entries int tangential_history_index; int roll_history_index; int twist_history_index; - double *normal_coeffs_global; - double *tangential_coeffs_global; - double *roll_coeffs_global; - double *twist_coeffs_global; - + //Per-type coefficients, set in pair coeff command double ***normal_coeffs; double ***tangential_coeffs; double ***roll_coeffs; double ***twist_coeffs; + //Optional user-specified global cutoff + double cutoff_global; + double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); double mix_geom(double valii, double valjj); -- GitLab From 6e4e244e65ac89f4fc248442c85b451c2ce9080e Mon Sep 17 00:00:00 2001 From: dsbolin Date: Tue, 15 Jan 2019 13:31:16 -0700 Subject: [PATCH 0088/1243] More doc page additions --- doc/src/pair_granular.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 19c16cc6ea..35b64bf29d 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -92,7 +92,11 @@ and their required arguments are: {no_history}: k_t, tangential_damping, friction coefficient {mindlin}: k_t, tangential_damping, friction coefficient -For {no_history}, the tangential force is computed according to +For {no_history}, the tangential force is computed according to: +:c,image{Eqs/tangential_nohistory.jpg} + +For {mindlin}, tangential force is: +:c,image{Eqs/tangential_mindlin.jpg} The total force on a particle is the sum of the normal and tangential forces from all interactions. The tangential force also induces a torque on both particles in a contacting pair. Additionally, rolling and twisting friction -- GitLab From 26eb17aa506f0c39995533e6b14255c6d4f83537 Mon Sep 17 00:00:00 2001 From: Dan Stefan Bolintineanu Date: Tue, 15 Jan 2019 16:42:06 -0700 Subject: [PATCH 0089/1243] Fixed tangential damping in pair granular; fixed order of template arguments, so that pair gran and gran/multi now produce identical results for same settings (as they should) --- src/GRANULAR/pair_granular.cpp | 41 ++++++++++++++-------------- src/GRANULAR/pair_granular.h | 2 +- src/GRANULAR/pair_granular_multi.cpp | 28 +++++++++---------- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 9fe4bd8415..c2f202ac9c 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -825,12 +825,12 @@ void PairGranular::compute(int eflag, int vflag){ #ifdef TEMPLATED_PAIR_GRANULAR template < int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_roll, int Tp_twist > + int Tp_twist, int Tp_roll > void PairGranular::compute_templated(int eflag, int vflag) #else void PairGranular::compute_untemplated (int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_roll, int Tp_twist, int eflag, int vflag) + int Tp_twist, int Tp_roll, int eflag, int vflag) #endif { int i,j,ii,jj,inum,jnum,itype,jtype; @@ -1040,17 +1040,17 @@ void PairGranular::compute_untemplated //Consider restricting Hooke to only have 'velocity' as an option for damping? if (Tp_damping == VELOCITY){ - damp_normal = normal_coeffs[itype][jtype][1]; + damp_normal = 1; } else if (Tp_damping == VISCOELASTIC){ if (Tp_normal == HOOKE) a = sqrt(dR); - damp_normal = normal_coeffs[itype][jtype][1]*a*meff; + damp_normal = a*meff; } else if (Tp_damping == TSUJI){ - damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); + damp_normal = sqrt(meff*knfac); } - Fdamp = -damp_normal*vnnr; + Fdamp = -normal_coeffs[itype][jtype][1]*damp_normal*vnnr; Fntot = Fne + Fdamp; @@ -1197,7 +1197,6 @@ void PairGranular::compute_untemplated history[rhist2] += vrl3*dt; } - k_roll = roll_coeffs[itype][jtype][0]; damp_roll = roll_coeffs[itype][jtype][1]; fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; @@ -1361,7 +1360,7 @@ void PairGranular::allocate() void PairGranular::settings(int narg, char **arg) { if (narg == 1){ - cutoff_global = force->numeric(FLERR,arg[0]) + cutoff_global = force->numeric(FLERR,arg[0]); } else{ cutoff_global = -1; //Will be set based on particle sizes, model choice @@ -1377,10 +1376,10 @@ void PairGranular::settings(int narg, char **arg) void PairGranular::coeff(int narg, char **arg) { - normal_coeffs_local = new double[4]; - tangential_coeffs_local = new double[4]; - roll_coeffs_local = new double[4]; - twist_coeffs_local = new double[4]; + double normal_coeffs_local[4]; + double tangential_coeffs_local[4]; + double roll_coeffs_local[4]; + double twist_coeffs_local[4]; if (narg < 2) error->all(FLERR,"Incorrect args for pair coefficients"); @@ -1415,7 +1414,7 @@ void PairGranular::coeff(int narg, char **arg) else if (strcmp(arg[iarg], "hertz/material") == 0){ int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = HERTZ/MATERIAL; + if (!normal_set) normal = HERTZ_MATERIAL; else if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping @@ -1448,7 +1447,7 @@ void PairGranular::coeff(int narg, char **arg) } else if (strcmp(arg[iarg], "damp") == 0){ if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); - if (strcmp(arg[iarg+1]), "velocity") == 0){ + if (strcmp(arg[iarg+1], "velocity") == 0){ if (!damping_set) damping = VELOCITY; else if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); } @@ -1461,7 +1460,7 @@ void PairGranular::coeff(int narg, char **arg) if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); } damping_set = 1; - iarg += 1; + iarg += 2; } else if (strcmp(arg[iarg], "tangential") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); @@ -1505,16 +1504,16 @@ void PairGranular::coeff(int narg, char **arg) error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); } roll_set =1 ; - roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. iarg += 5; } } else if (strcmp(arg[iarg], "twisting") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); if (strcmp(arg[iarg+1], "none") == 0){ - if (!twist_set) twist = TWIST_NOHISTORY; + if (!twist_set) twist = TWIST_NONE; else if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); iarg += 2; } @@ -1522,12 +1521,13 @@ void PairGranular::coeff(int narg, char **arg) if (!twist_set) twist = TWIST_MARSHALL; else if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); twist_history = 1; + twist_set = 1; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - if (!twist_set) twist = TWIST_NOHISTORY; else if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (!twist_set) twist = TWIST_NOHISTORY; if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); } else if (strcmp(arg[iarg+1], "sds") == 0){ @@ -1556,6 +1556,7 @@ void PairGranular::coeff(int narg, char **arg) if (!damping_set) damping = VISCOELASTIC; if (!roll_set) roll = ROLL_NONE; if (!twist_set) twist = TWIST_NONE; + damping_set = roll_set = twist_set = 1; int count = 0; double damp; diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index f3a9d4dcbe..f39f31e4cb 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -96,7 +96,7 @@ private: double ***twist_coeffs; //Optional user-specified global cutoff - double global_cutoff; + double cutoff_global; double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); diff --git a/src/GRANULAR/pair_granular_multi.cpp b/src/GRANULAR/pair_granular_multi.cpp index 5fee363872..09b8ea9709 100644 --- a/src/GRANULAR/pair_granular_multi.cpp +++ b/src/GRANULAR/pair_granular_multi.cpp @@ -329,17 +329,17 @@ void PairGranularMulti::compute(int eflag, int vflag) //Consider restricting Hooke to only have 'velocity' as an option for damping? if (damping[itype][jtype] == VELOCITY){ - damp_normal = normal_coeffs[itype][jtype][1]; + damp_normal = 1; } else if (damping[itype][jtype] == VISCOELASTIC){ if (normal[itype][jtype] == HOOKE) a = sqrt(dR); - damp_normal = normal_coeffs[itype][jtype][1]*a*meff; + damp_normal = a*meff; } else if (damping[itype][jtype] == TSUJI){ - damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); + damp_normal = sqrt(meff*knfac); } - Fdamp = -damp_normal*vnnr; + Fdamp = -normal_coeffs[itype][jtype][1]*damp_normal*vnnr; Fntot = Fne + Fdamp; @@ -655,7 +655,7 @@ void PairGranularMulti::allocate() void PairGranularMulti::settings(int narg, char **arg) { if (narg == 1){ - cutoff_global = force->numeric(FLERR,arg[0]) + cutoff_global = force->numeric(FLERR,arg[0]); } else{ cutoff_global = -1; //Will be set based on particle sizes, model choice @@ -673,10 +673,10 @@ void PairGranularMulti::coeff(int narg, char **arg) { int normal_local, damping_local, tangential_local, roll_local, twist_local; - normal_coeffs_local = new double[4]; - tangential_coeffs_local = new double[4]; - roll_coeffs_local = new double[4]; - twist_coeffs_local = new double[4]; + double normal_coeffs_local[4]; + double tangential_coeffs_local[4]; + double roll_coeffs_local[4]; + double twist_coeffs_local[4]; if (narg < 2) error->all(FLERR,"Incorrect args for pair coefficients"); @@ -739,7 +739,7 @@ void PairGranularMulti::coeff(int narg, char **arg) } else if (strcmp(arg[iarg], "damp") == 0){ if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); - if (strcmp(arg[iarg+1]), "velocity") == 0){ + if (strcmp(arg[iarg+1], "velocity") == 0){ damping_local = VELOCITY; iarg += 1; } @@ -787,9 +787,9 @@ void PairGranularMulti::coeff(int narg, char **arg) else{ error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); } - roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. iarg += 5; } } @@ -826,7 +826,7 @@ void PairGranularMulti::coeff(int narg, char **arg) } //It is an error not to specify normal or tangential model - if ((normal_set < 0) || (tangential_set < 0)) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model");)) + if ((normal_local < 0) || (tangential_local < 0)) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); int count = 0; double damp; -- GitLab From 9de0262155461bcaee5132df2c0719486812d5d3 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 23 Jan 2019 14:49:52 -0700 Subject: [PATCH 0090/1243] added rendezvous via all2all --- src/RIGID/fix_rigid_small.cpp | 5 +- src/RIGID/fix_shake.cpp | 30 ++-- src/comm.cpp | 318 +++++++++++++++++++++++++++++++--- src/comm.h | 12 +- src/irregular.cpp | 185 +++++++++++++++++++- src/irregular.h | 2 + src/special.cpp | 119 +++++++------ 7 files changed, 566 insertions(+), 105 deletions(-) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index e20c64487b..957438fc55 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -1576,8 +1576,9 @@ void FixRigidSmall::create_bodies(tagint *bodyID) // func = compute bbox of each body, find atom closest to geometric center char *buf; - int nreturn = comm->rendezvous(ncount,proclist,(char *) inbuf,sizeof(InRvous), - rendezvous_body,buf,sizeof(OutRvous), + int nreturn = comm->rendezvous(1,ncount,(char *) inbuf,sizeof(InRvous), + 0,proclist, + rendezvous_body,0,buf,sizeof(OutRvous), (void *) this); OutRvous *outbuf = (OutRvous *) buf; diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 51121f0853..35153de839 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -1068,9 +1068,9 @@ void FixShake::atom_owners() // each proc assigned every 1/Pth atom char *buf; - comm->rendezvous(nlocal,proclist, - (char *) idbuf,sizeof(IDRvous), - rendezvous_ids,buf,0,(void *) this); + comm->rendezvous(1,nlocal,(char *) idbuf,sizeof(IDRvous), + 0,proclist, + rendezvous_ids,0,buf,0,(void *) this); memory->destroy(proclist); memory->sfree(idbuf); @@ -1174,9 +1174,10 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag, // receives all data needed to populate un-owned partner 4 values char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(PartnerInfo), - rendezvous_partners_info,buf,sizeof(PartnerInfo), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PartnerInfo), + 0,proclist, + rendezvous_partners_info, + 0,buf,sizeof(PartnerInfo), (void *) this); PartnerInfo *outbuf = (PartnerInfo *) buf; @@ -1194,7 +1195,8 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag, partner_type[i][j] = outbuf[m].type; partner_massflag[i][j] = outbuf[m].massflag; - // only set partner_bondtype if my atom did not set it when setting up rendezvous + // only set partner_bondtype if my atom did not set it + // when setting up rendezvous // if this proc set it, then sender of this datum set outbuf.bondtype = 0 if (partner_bondtype[i][j] == 0) @@ -1261,9 +1263,9 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag, // receives all data needed to populate un-owned partner nshake char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(NShakeInfo), - rendezvous_nshake,buf,sizeof(NShakeInfo), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(NShakeInfo), + 0,proclist, + rendezvous_nshake,0,buf,sizeof(NShakeInfo), (void *) this); NShakeInfo *outbuf = (NShakeInfo *) buf; @@ -1354,9 +1356,9 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag, // receives all data needed to populate un-owned shake info char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(ShakeInfo), - rendezvous_shake,buf,sizeof(ShakeInfo), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(ShakeInfo), + 0,proclist, + rendezvous_shake,0,buf,sizeof(ShakeInfo), (void *) this); ShakeInfo *outbuf = (ShakeInfo *) buf; @@ -1412,7 +1414,7 @@ int FixShake::rendezvous_ids(int n, char *inbuf, fsptr->atomIDs = atomIDs; fsptr->procowner = procowner; - // flag = 0: no 2nd irregular comm needed in comm->rendezvous + // flag = 0: no second comm needed in rendezvous flag = 0; return 0; diff --git a/src/comm.cpp b/src/comm.cpp index 9bdaf0798a..39d4311aa2 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -729,34 +729,78 @@ void Comm::ring(int n, int nper, void *inbuf, int messtag, /* ---------------------------------------------------------------------- rendezvous communication operation three stages: - first Irregular converts inbuf from caller decomp to rvous decomp + first comm sends inbuf from caller decomp to rvous decomp callback operates on data in rendevous decomp - last Irregular converts outbuf from rvous decomp back to caller decomp + second comm sends outbuf from rvous decomp back to caller decomp inputs: - n = # of input datums - proclist = proc that owns each input datum in rendezvous decomposition - inbuf = list of input datums - insize = size in bytes of each input datum + which = perform (0) irregular or (1) MPI_All2allv communication + n = # of datums in inbuf + inbuf = vector of input datums + insize = byte size of each input datum + inorder = 0 for inbuf in random proc order, 1 for datums ordered by proc + procs: inorder 0 = proc to send each datum to, 1 = # of datums/proc, callback = caller function to invoke in rendezvous decomposition + takes input datums, returns output datums + outorder = same as inorder, but for datums returned by callback() + ptr = pointer to caller class, passed to callback() outputs: nout = # of output datums (function return) - outbuf = list of output datums - outsize = size in bytes of each output datum + outbuf = vector of output datums + outsize = byte size of each output datum + callback inputs: + nrvous = # of rvous decomp datums in inbuf_rvous + inbuf_rvous = vector of rvous decomp input datums + ptr = pointer to caller class + callback outputs: + nrvous_out = # of rvous decomp output datums (function return) + flag = 0 for no second comm, 1 for outbuf_rvous = inbuf_rvous, + 2 for second comm with new outbuf_rvous + procs_rvous = outorder 0 = proc to send each datum to, 1 = # of datums/proc + allocated + outbuf_rvous = vector of rvous decomp output datums + NOTE: could use MPI_INT or MPI_DOUBLE insead of MPI_CHAR + to avoid checked-for overflow in MPI_Alltoallv? ------------------------------------------------------------------------- */ -int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, - int (*callback)(int, char *, int &, int *&, char *&, void *), - char *&outbuf, int outsize, void *ptr) +int Comm:: +rendezvous(int which, int n, char *inbuf, int insize, + int inorder, int *procs, + int (*callback)(int, char *, int &, int *&, char *&, void *), + int outorder, char *&outbuf, int outsize, void *ptr) { - // comm inbuf from caller decomposition to rendezvous decomposition + int nout; + + if (which == 0) + nout = rendezvous_irregular(n,inbuf,insize,inorder,procs,callback, + outorder,outbuf,outsize,ptr); + else + nout = rendezvous_all2all(n,inbuf,insize,inorder,procs,callback, + outorder,outbuf,outsize,ptr); + + return nout; +} +/* ---------------------------------------------------------------------- */ + +int Comm:: +rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, + int (*callback)(int, char *, int &, int *&, char *&, void *), + int outorder, char *&outbuf, + int outsize, void *ptr) +{ + // irregular comm of inbuf from caller decomp to rendezvous decomp + Irregular *irregular = new Irregular(lmp); - int n_rvous = irregular->create_data(n,proclist); // add sort - char *inbuf_rvous = (char *) memory->smalloc((bigint) n_rvous*insize, - "rendezvous:inbuf_rvous"); + int nrvous; + if (inorder) nrvous = irregular->create_data_grouped(n,procs); + else nrvous = irregular->create_data(n,procs); + + char *inbuf_rvous = (char *) memory->smalloc((bigint) nrvous*insize, + "rendezvous:inbuf"); irregular->exchange_data(inbuf,insize,inbuf_rvous); + bigint irregular1_bytes = 0; //irregular->irregular_bytes; irregular->destroy_data(); delete irregular; @@ -764,29 +808,253 @@ int Comm::rendezvous(int n, int *proclist, char *inbuf, int insize, // callback() allocates/populates proclist_rvous and outbuf_rvous int flag; - int *proclist_rvous; + int *procs_rvous; char *outbuf_rvous; - - int nout_rvous = - callback(n_rvous,inbuf_rvous,flag,proclist_rvous,outbuf_rvous,ptr); + int nrvous_out = callback(nrvous,inbuf_rvous,flag, + procs_rvous,outbuf_rvous,ptr); if (flag != 1) memory->sfree(inbuf_rvous); // outbuf_rvous = inbuf_vous - if (flag == 0) return 0; // all nout_rvous are 0, no 2nd irregular + if (flag == 0) return 0; // all nout_rvous are 0, no 2nd comm stage - // comm outbuf from rendezvous decomposition back to caller + // irregular comm of outbuf from rendezvous decomp back to caller decomp // caller will free outbuf irregular = new Irregular(lmp); - int nout = irregular->create_data(nout_rvous,proclist_rvous); - outbuf = (char *) memory->smalloc((bigint) nout*outsize,"rendezvous:outbuf"); + int nout; + if (outorder) + nout = irregular->create_data_grouped(nrvous_out,procs_rvous); + else nout = irregular->create_data(nrvous_out,procs_rvous); + + outbuf = (char *) memory->smalloc((bigint) nout*outsize, + "rendezvous:outbuf"); irregular->exchange_data(outbuf_rvous,outsize,outbuf); - + + bigint irregular2_bytes = 0; //irregular->irregular_bytes; irregular->destroy_data(); delete irregular; - memory->destroy(proclist_rvous); + + memory->destroy(procs_rvous); memory->sfree(outbuf_rvous); + // approximate memory tally + + bigint rvous_bytes = 0; + rvous_bytes += n*insize; // inbuf + rvous_bytes += nout*outsize; // outbuf + rvous_bytes += nrvous*insize; // inbuf_rvous + rvous_bytes += nrvous_out*outsize; // outbuf_rvous + rvous_bytes += nrvous_out*sizeof(int); // procs_rvous + rvous_bytes += MAX(irregular1_bytes,irregular2_bytes); // max of 2 comms + + // return number of output datums + + return nout; +} + +/* ---------------------------------------------------------------------- */ + +int Comm:: +rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, + int (*callback)(int, char *, int &, int *&, char *&, void *), + int outorder, char *&outbuf, int outsize, void *ptr) +{ + int iproc; + bigint all2all1_bytes,all2all2_bytes; + int *sendcount,*sdispls,*recvcount,*rdispls; + int *procs_a2a; + bigint *offsets; + char *inbuf_a2a,*outbuf_a2a; + + // create procs and inbuf for All2all if necesary + + if (!inorder) { + memory->create(procs_a2a,nprocs,"rendezvous:procs"); + inbuf_a2a = (char *) memory->smalloc((bigint) n*insize, + "rendezvous:inbuf"); + memory->create(offsets,nprocs,"rendezvous:offsets"); + + for (int i = 0; i < nprocs; i++) procs_a2a[i] = 0; + for (int i = 0; i < n; i++) procs_a2a[procs[i]]++; + + offsets[0] = 0; + for (int i = 1; i < nprocs; i++) + offsets[i] = offsets[i-1] + insize*procs_a2a[i-1]; + + bigint offset = 0; + for (int i = 0; i < n; i++) { + iproc = procs[i]; + memcpy(&inbuf_a2a[offsets[iproc]],&inbuf[offset],insize); + offsets[iproc] += insize; + offset += insize; + } + + all2all1_bytes = nprocs*sizeof(int) + nprocs*sizeof(bigint) + n*insize; + + } else { + procs_a2a = procs; + inbuf_a2a = inbuf; + all2all1_bytes = 0; + } + + // create args for MPI_Alltoallv() on input data + + memory->create(sendcount,nprocs,"rendezvous:sendcount"); + memcpy(sendcount,procs_a2a,nprocs*sizeof(int)); + + memory->create(recvcount,nprocs,"rendezvous:recvcount"); + MPI_Alltoall(sendcount,1,MPI_INT,recvcount,1,MPI_INT,world); + + memory->create(sdispls,nprocs,"rendezvous:sdispls"); + memory->create(rdispls,nprocs,"rendezvous:rdispls"); + sdispls[0] = rdispls[0] = 0; + for (int i = 1; i < nprocs; i++) { + sdispls[i] = sdispls[i-1] + sendcount[i-1]; + rdispls[i] = rdispls[i-1] + recvcount[i-1]; + } + int nrvous = rdispls[nprocs-1] + recvcount[nprocs-1]; + + // test for overflow of input data due to imbalance or insize + // means that individual sdispls or rdispls values overflow + + int overflow = 0; + if ((bigint) n*insize > MAXSMALLINT) overflow = 1; + if ((bigint) nrvous*insize > MAXSMALLINT) overflow = 1; + int overflowall; + MPI_Allreduce(&overflow,&overflowall,1,MPI_INT,MPI_MAX,world); + if (overflowall) error->all(FLERR,"Overflow input size in rendezvous_a2a"); + + for (int i = 0; i < nprocs; i++) { + sendcount[i] *= insize; + sdispls[i] *= insize; + recvcount[i] *= insize; + rdispls[i] *= insize; + } + + // all2all comm of inbuf from caller decomp to rendezvous decomp + + char *inbuf_rvous = (char *) memory->smalloc((bigint) nrvous*insize, + "rendezvous:inbuf"); + + MPI_Alltoallv(inbuf_a2a,sendcount,sdispls,MPI_CHAR, + inbuf_rvous,recvcount,rdispls,MPI_CHAR,world); + + if (!inorder) { + memory->destroy(procs_a2a); + memory->sfree(inbuf_a2a); + memory->destroy(offsets); + } + + // peform rendezvous computation via callback() + // callback() allocates/populates proclist_rvous and outbuf_rvous + + int flag; + int *procs_rvous; + char *outbuf_rvous; + + int nrvous_out = callback(nrvous,inbuf_rvous,flag, + procs_rvous,outbuf_rvous,ptr); + + if (flag != 1) memory->sfree(inbuf_rvous); // outbuf_rvous = inbuf_vous + if (flag == 0) return 0; // all nout_rvous are 0, no 2nd irregular + + // create procs and outbuf for All2all if necesary + + if (!outorder) { + memory->create(procs_a2a,nprocs,"rendezvous_a2a:procs"); + + outbuf_a2a = (char *) memory->smalloc((bigint) nrvous_out*outsize, + "rendezvous:outbuf"); + memory->create(offsets,nprocs,"rendezvous:offsets"); + + for (int i = 0; i < nprocs; i++) procs_a2a[i] = 0; + for (int i = 0; i < nrvous_out; i++) procs_a2a[procs_rvous[i]]++; + + offsets[0] = 0; + for (int i = 1; i < nprocs; i++) + offsets[i] = offsets[i-1] + outsize*procs_a2a[i-1]; + + bigint offset = 0; + for (int i = 0; i < nrvous_out; i++) { + iproc = procs_rvous[i]; + memcpy(&outbuf_a2a[offsets[iproc]],&outbuf_rvous[offset],outsize); + offsets[iproc] += outsize; + offset += outsize; + } + + all2all2_bytes = nprocs*sizeof(int) + nprocs*sizeof(bigint) + + nrvous_out*outsize; + + } else { + procs_a2a = procs_rvous; + outbuf_a2a = outbuf_rvous; + all2all2_bytes = 0; + } + + // comm outbuf from rendezvous decomposition back to caller + + memcpy(sendcount,procs_a2a,nprocs*sizeof(int)); + + MPI_Alltoall(sendcount,1,MPI_INT,recvcount,1,MPI_INT,world); + + sdispls[0] = rdispls[0] = 0; + for (int i = 1; i < nprocs; i++) { + sdispls[i] = sdispls[i-1] + sendcount[i-1]; + rdispls[i] = rdispls[i-1] + recvcount[i-1]; + } + int nout = rdispls[nprocs-1] + recvcount[nprocs-1]; + + // test for overflow of outbuf due to imbalance or outsize + // means that individual sdispls or rdispls values overflow + + overflow = 0; + if ((bigint) nrvous*outsize > MAXSMALLINT) overflow = 1; + if ((bigint) nout*outsize > MAXSMALLINT) overflow = 1; + MPI_Allreduce(&overflow,&overflowall,1,MPI_INT,MPI_MAX,world); + if (overflowall) error->all(FLERR,"Overflow output in rendezvous_a2a"); + + for (int i = 0; i < nprocs; i++) { + sendcount[i] *= outsize; + sdispls[i] *= outsize; + recvcount[i] *= outsize; + rdispls[i] *= outsize; + } + + // all2all comm of outbuf from rendezvous decomp back to caller decomp + // caller will free outbuf + + outbuf = (char *) memory->smalloc((bigint) nout*outsize,"rendezvous:outbuf"); + + MPI_Alltoallv(outbuf_a2a,sendcount,sdispls,MPI_CHAR, + outbuf,recvcount,rdispls,MPI_CHAR,world); + + memory->destroy(procs_rvous); + memory->sfree(outbuf_rvous); + + if (!outorder) { + memory->destroy(procs_a2a); + memory->sfree(outbuf_a2a); + memory->destroy(offsets); + } + + // clean up + + memory->destroy(sendcount); + memory->destroy(recvcount); + memory->destroy(sdispls); + memory->destroy(rdispls); + + // approximate memory tally + + bigint rvous_bytes = 0; + rvous_bytes += n*insize; // inbuf + rvous_bytes += nout*outsize; // outbuf + rvous_bytes += nrvous*insize; // inbuf_rvous + rvous_bytes += nrvous_out*outsize; // outbuf_rvous + rvous_bytes += nrvous_out*sizeof(int); // procs_rvous + rvous_bytes += 4*nprocs*sizeof(int); // all2all vectors + rvous_bytes += MAX(all2all1_bytes,all2all2_bytes); // reorder ops + // return number of datums return nout; diff --git a/src/comm.h b/src/comm.h index a1bac53ac8..807da9bf0d 100644 --- a/src/comm.h +++ b/src/comm.h @@ -109,9 +109,9 @@ class Comm : protected Pointers { void ring(int, int, void *, int, void (*)(int, char *, void *), void *, void *, int self = 1); - int rendezvous(int, int *, char *, int, + int rendezvous(int, int, char *, int, int, int *, int (*)(int, char *, int &, int *&, char *&, void *), - char *&, int, void *); + int, char *&, int, void *); int read_lines_from_file(FILE *, int, int, char *); int read_lines_from_file_universe(FILE *, int, int, char *); @@ -146,6 +146,14 @@ class Comm : protected Pointers { int ncores; // # of cores per node int coregrid[3]; // 3d grid of cores within a node int user_coregrid[3]; // user request for cores in each dim + + int rendezvous_irregular(int, char *, int, int, int *, + int (*)(int, char *, int &, int *&, char *&, void *), + int, char *&, int, void *); + int rendezvous_all2all(int, char *, int, int, int *, + int (*)(int, char *, int &, int *&, char *&, void *), + int, char *&, int, void *); + public: enum{MULTIPLE}; }; diff --git a/src/irregular.cpp b/src/irregular.cpp index 60025249cf..77278ec4c5 100644 --- a/src/irregular.cpp +++ b/src/irregular.cpp @@ -622,6 +622,7 @@ int Irregular::create_data(int n, int *proclist, int sortflag) num_send = new int[nsend_proc]; index_send = new int[n-work1[me]]; index_self = new int[work1[me]]; + maxindex = n; // proc_send = procs I send to // num_send = # of datums I send to each proc @@ -679,8 +680,182 @@ int Irregular::create_data(int n, int *proclist, int sortflag) // receive incoming messages // proc_recv = procs I recv from - // num_recv = total size of message each proc sends me - // nrecvdatum = total size of data I recv + // num_recv = # of datums each proc sends me + // nrecvdatum = total # of datums I recv + + int nrecvdatum = 0; + for (i = 0; i < nrecv_proc; i++) { + MPI_Recv(&num_recv[i],1,MPI_INT,MPI_ANY_SOURCE,0,world,status); + proc_recv[i] = status->MPI_SOURCE; + nrecvdatum += num_recv[i]; + } + nrecvdatum += num_self; + + // sort proc_recv and num_recv by proc ID if requested + // useful for debugging to insure reproducible ordering of received datums + + if (sortflag) { + int *order = new int[nrecv_proc]; + int *proc_recv_ordered = new int[nrecv_proc]; + int *num_recv_ordered = new int[nrecv_proc]; + + for (i = 0; i < nrecv_proc; i++) order[i] = i; + +#if defined(LMP_QSORT) + proc_recv_copy = proc_recv; + qsort(order,nrecv_proc,sizeof(int),compare_standalone); +#else + merge_sort(order,nrecv_proc,(void *)proc_recv,compare_standalone); +#endif + + int j; + for (i = 0; i < nrecv_proc; i++) { + j = order[i]; + proc_recv_ordered[i] = proc_recv[j]; + num_recv_ordered[i] = num_recv[j]; + } + + memcpy(proc_recv,proc_recv_ordered,nrecv_proc*sizeof(int)); + memcpy(num_recv,num_recv_ordered,nrecv_proc*sizeof(int)); + delete [] order; + delete [] proc_recv_ordered; + delete [] num_recv_ordered; + } + + // barrier to insure all MPI_ANY_SOURCE messages are received + // else another proc could proceed to exchange_data() and send to me + + MPI_Barrier(world); + + // return # of datums I will receive + + return nrecvdatum; +} + +/* ---------------------------------------------------------------------- + create communication plan based on list of datums of uniform size + n = # of datums to send + procs = how many datums to send to each proc, must include self + sort = flag for sorting order of received messages by proc ID + return total # of datums I will recv, including any to self +------------------------------------------------------------------------- */ + +int Irregular::create_data_grouped(int n, int *procs, int sortflag) +{ + int i,j,k,m; + + // setup for collective comm + // work1 = # of datums I send to each proc, set self to 0 + // work2 = 1 for all procs, used for ReduceScatter + + for (i = 0; i < nprocs; i++) { + work1[i] = procs[i]; + work2[i] = 1; + } + work1[me] = 0; + + // nrecv_proc = # of procs I receive messages from, not including self + // options for performing ReduceScatter operation + // some are more efficient on some machines at big sizes + +#ifdef LAMMPS_RS_ALLREDUCE_INPLACE + MPI_Allreduce(MPI_IN_PLACE,work1,nprocs,MPI_INT,MPI_SUM,world); + nrecv_proc = work1[me]; +#else +#ifdef LAMMPS_RS_ALLREDUCE + MPI_Allreduce(work1,work2,nprocs,MPI_INT,MPI_SUM,world); + nrecv_proc = work2[me]; +#else + MPI_Reduce_scatter(work1,&nrecv_proc,work2,MPI_INT,MPI_SUM,world); +#endif +#endif + + // allocate receive arrays + + proc_recv = new int[nrecv_proc]; + num_recv = new int[nrecv_proc]; + request = new MPI_Request[nrecv_proc]; + status = new MPI_Status[nrecv_proc]; + + // work1 = # of datums I send to each proc, including self + // nsend_proc = # of procs I send messages to, not including self + + for (i = 0; i < nprocs; i++) work1[i] = procs[i]; + + nsend_proc = 0; + for (i = 0; i < nprocs; i++) + if (work1[i]) nsend_proc++; + if (work1[me]) nsend_proc--; + + // allocate send and self arrays + + proc_send = new int[nsend_proc]; + num_send = new int[nsend_proc]; + index_send = new int[n-work1[me]]; + index_self = new int[work1[me]]; + maxindex = n; + + // proc_send = procs I send to + // num_send = # of datums I send to each proc + // num_self = # of datums I copy to self + // to balance pattern of send messages: + // each proc begins with iproc > me, continues until iproc = me + // reset work1 to store which send message each proc corresponds to + + int iproc = me; + int isend = 0; + for (i = 0; i < nprocs; i++) { + iproc++; + if (iproc == nprocs) iproc = 0; + if (iproc == me) { + num_self = work1[iproc]; + work1[iproc] = 0; + } else if (work1[iproc] > 0) { + proc_send[isend] = iproc; + num_send[isend] = work1[iproc]; + work1[iproc] = isend; + isend++; + } + } + + // work2 = offsets into index_send for each proc I send to + // m = ptr into index_self + // index_send = list of which datums to send to each proc + // 1st N1 values are datum indices for 1st proc, + // next N2 values are datum indices for 2nd proc, etc + // index_self = list of which datums to copy to self + + work2[0] = 0; + for (i = 1; i < nsend_proc; i++) work2[i] = work2[i-1] + num_send[i-1]; + + m = 0; + i = 0; + for (iproc = 0; iproc < nprocs; iproc++) { + k = procs[iproc]; + for (j = 0; j < k; j++) { + if (iproc == me) index_self[m++] = i++; + else { + isend = work1[iproc]; + index_send[work2[isend]++] = i++; + } + } + } + + // tell receivers how much data I send + // sendmax_proc = largest # of datums I send in a single message + + sendmax_proc = 0; + for (i = 0; i < nsend_proc; i++) { + MPI_Request tmpReq; // Use non-blocking send to avoid possible deadlock + MPI_Isend(&num_send[i],1,MPI_INT,proc_send[i],0,world,&tmpReq); + MPI_Request_free(&tmpReq); // the MPI_Barrier below marks completion + sendmax_proc = MAX(sendmax_proc,num_send[i]); + } + + // receive incoming messages + // proc_recv = procs I recv from + // num_recv = # of datums each proc sends me + // nrecvdatum = total # of datums I recv int nrecvdatum = 0; for (i = 0; i < nrecv_proc; i++) { @@ -789,6 +964,12 @@ void Irregular::exchange_data(char *sendbuf, int nbytes, char *recvbuf) // wait on all incoming messages if (nrecv_proc) MPI_Waitall(nrecv_proc,request,status); + + // approximate memory tally + + bigint irregular_bytes = 2*nprocs*sizeof(int); + irregular_bytes += maxindex*sizeof(int); + irregular_bytes += maxbuf; } /* ---------------------------------------------------------------------- diff --git a/src/irregular.h b/src/irregular.h index 1f74fe801b..d56bcb253d 100644 --- a/src/irregular.h +++ b/src/irregular.h @@ -33,6 +33,7 @@ class Irregular : protected Pointers { int *procassign = NULL); int migrate_check(); int create_data(int, int *, int sortflag = 0); + int create_data_grouped(int, int *, int sortflag = 0); void exchange_data(char *, int, char *); void destroy_data(); bigint memory_usage(); @@ -48,6 +49,7 @@ class Irregular : protected Pointers { double *dbuf; // double buf for largest single atom send int maxbuf; // size of char buf in bytes char *buf; // char buf for largest single data send + int maxindex; // combined size of index_send + index_self int *mproclist,*msizes; // persistent vectors in migrate_atoms int maxlocal; // allocated size of mproclist and msizes diff --git a/src/special.cpp b/src/special.cpp index b0d5bc7dca..34685d8c65 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -172,10 +172,9 @@ void Special::atom_owners() IDRvous *idbuf = (IDRvous *) memory->smalloc((bigint) nlocal*sizeof(IDRvous),"special:idbuf"); - // setup input buf to rendezvous comm - // input datums = pairs of bonded atoms - // owning proc for each datum = random hash of atomID + // setup input buf for rendezvous comm // one datum for each owned atom: datum = owning proc, atomID + // each proc assigned every 1/Pth atom for (int i = 0; i < nlocal; i++) { proclist[i] = tag[i] % nprocs; @@ -184,19 +183,18 @@ void Special::atom_owners() } // perform rendezvous operation - // each proc assigned every 1/Pth atom char *buf; - comm->rendezvous(nlocal,proclist, - (char *) idbuf,sizeof(IDRvous), - rendezvous_ids,buf,0,(void *) this); + comm->rendezvous(1,nlocal,(char *) idbuf,sizeof(IDRvous),0,proclist, + rendezvous_ids,0,buf,0,(void *) this); memory->destroy(proclist); memory->sfree(idbuf); } /* ---------------------------------------------------------------------- - onetwo build + onetwo build when newton_bond flag on + uses rendezvous comm ------------------------------------------------------------------------- */ void Special::onetwo_build_newton() @@ -225,9 +223,8 @@ void Special::onetwo_build_newton() memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm - // input datums = pairs of bonded atoms - // owning proc for each datum = atomID % nprocs - // one datum for each bond partner: bond partner ID, atomID + // one datum for each unowned bond partner: bond partner ID, atomID + // owning proc for each datum = bond partner ID % nprocs nsend = 0; for (i = 0; i < nlocal; i++) { @@ -242,19 +239,19 @@ void Special::onetwo_build_newton() } // perform rendezvous operation - // each proc owns random subset of atoms char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(PairRvous), - rendezvous_pairs,buf,sizeof(PairRvous), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); - // set nspecial[0] and onetwo for all owned atoms based on output info + // set nspecial[0] and onetwo for all owned atoms + // based on owned info plus rendezvous output info // output datums = pairs of atoms that are 1-2 neighbors for (i = 0; i < nlocal; i++) { @@ -327,8 +324,8 @@ void Special::onetwo_build_newton_off() } /* ---------------------------------------------------------------------- - onetwo build with newton_bond flag off - no need for rendezvous comm + onethree build + uses rendezvous comm ------------------------------------------------------------------------- */ void Special::onethree_build() @@ -355,10 +352,10 @@ void Special::onethree_build() memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm - // input datums = all pairs of onetwo atoms (they are 1-3 neighbors) - // owning proc for each datum = random hash of atomID - // one datum for each owned atom: datum = owning proc, atomID - // one datum for each onetwo pair: datum = atomID1, atomID2 + // datums = pairs of onetwo partners where either is unknown + // these pairs are onethree neighbors + // datum = onetwo ID, onetwo ID + // owning proc for each datum = onetwo ID % nprocs nsend = 0; for (i = 0; i < nlocal; i++) { @@ -377,20 +374,19 @@ void Special::onethree_build() } // perform rendezvous operation - // each proc owns random subset of atoms - // receives all info to form and return their onethree lists char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(PairRvous), - rendezvous_pairs,buf,sizeof(PairRvous), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); - // set nspecial[1] and onethree for all owned atoms based on output info + // set nspecial[1] and onethree for all owned atoms + // based on owned info plus rendezvous output info // output datums = pairs of atoms that are 1-3 neighbors for (i = 0; i < nlocal; i++) { @@ -434,7 +430,8 @@ void Special::onethree_build() } /* ---------------------------------------------------------------------- - remove duplicates within each of onetwo, onethree, onefour individually + onefour build + uses rendezvous comm ------------------------------------------------------------------------- */ void Special::onefour_build() @@ -446,7 +443,6 @@ void Special::onefour_build() int nlocal = atom->nlocal; // nsend = # of my datums to send - // include nlocal datums with owner of each atom int nsend = 0; for (i = 0; i < nlocal; i++) { @@ -462,10 +458,10 @@ void Special::onefour_build() memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm - // input datums = all pairs of onethree and onetwo atoms (they're 1-4 neighbors) - // owning proc for each datum = random hash of atomID - // one datum for each owned atom: datum = owning proc, atomID - // one datum for each onethree/onetwo pair: datum = atomID1, atomID2 + // datums = pairs of onethree and onetwo partners where onethree is unknown + // these pairs are onefour neighbors + // datum = onetwo ID, onetwo ID + // owning proc for each datum = onethree ID % nprocs nsend = 0; for (i = 0; i < nlocal; i++) { @@ -483,20 +479,19 @@ void Special::onefour_build() } // perform rendezvous operation - // each proc owns random subset of atoms - // receives all info to form and return their onefour lists char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(PairRvous), - rendezvous_pairs,buf,sizeof(PairRvous), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); - // set nspecial[2] and onefour for all owned atoms based on output info + // set nspecial[2] and onefour for all owned atoms + // based on owned info plus rendezvous output info // output datums = pairs of atoms that are 1-4 neighbors for (i = 0; i < nlocal; i++) { @@ -780,6 +775,7 @@ void Special::combine() trim list of 1-3 neighbors by checking defined angles delete a 1-3 neigh if they are not end atoms of a defined angle and if they are not 1,3 or 2,4 atoms of a defined dihedral + uses rendezvous comm ------------------------------------------------------------------------- */ void Special::angle_trim() @@ -849,6 +845,10 @@ void Special::angle_trim() memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm + // datums = pairs of onetwo partners where either is unknown + // these pairs are onethree neighbors + // datum = onetwo ID, onetwo ID + // owning proc for each datum = onetwo ID % nprocs nsend = 0; for (i = 0; i < nlocal; i++) { @@ -902,14 +902,11 @@ void Special::angle_trim() } // perform rendezvous operation - // each proc owns random subset of atoms - // func = compute bbox of each body, flag atom closest to geometric center - // when done: each atom has atom ID of owning atom of its body char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(PairRvous), - rendezvous_pairs,buf,sizeof(PairRvous), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; @@ -931,6 +928,8 @@ void Special::angle_trim() flag[i][j] = 0; // reset nspecial[1] and onethree for all owned atoms based on output info + // based on owned info plus rendezvous output info + // output datums = pairs of atoms that are 1-3 neighbors for (i = 0; i < nlocal; i++) { for (j = 0; j < num_angle[i]; j++) { @@ -1036,8 +1035,9 @@ void Special::angle_trim() } /* ---------------------------------------------------------------------- - trim list of 1-4 neighbors by checking defined dihedrals + trim list of 1-4 neighbors by checking all defined dihedrals delete a 1-4 neigh if they are not end atoms of a defined dihedral + uses rendezvous comm ------------------------------------------------------------------------- */ void Special::dihedral_trim() @@ -1068,12 +1068,11 @@ void Special::dihedral_trim() " %g = # of 1-4 neighbors before dihedral trim\n",allcount); } - // if dihedrals are defined, rendezvous dihedral 1-4 pairs + // if dihedrals are defined, rendezvous the dihedral 1-4 pairs if (num_dihedral && atom->ndihedrals) { // nsend = # of my datums to send - // latter is only for dihedrals where I own atom2 (newton bond off) int nsend = 0; for (i = 0; i < nlocal; i++) { @@ -1092,6 +1091,11 @@ void Special::dihedral_trim() memory->smalloc((bigint) nsend*sizeof(PairRvous),"special:inbuf"); // setup input buf to rendezvous comm + // datums = pairs of onefour atom IDs in a dihedral defined for my atoms + // only dihedrals where I own atom2 (in case newton_bond off) + // datum = atom1 ID and atom4 ID + // send the datum twice, to owner of atom1 ID and atom4 ID + // owning procs for each datum = atom1 or atom4 ID % nprocs nsend = 0; for (i = 0; i < nlocal; i++) { @@ -1117,21 +1121,18 @@ void Special::dihedral_trim() } // perform rendezvous operation - // each proc owns random subset of atoms - // func = compute bbox of each body, flag atom closest to geometric center - // when done: each atom has atom ID of owning atom of its body char *buf; - int nreturn = comm->rendezvous(nsend,proclist, - (char *) inbuf,sizeof(PairRvous), - rendezvous_pairs,buf,sizeof(PairRvous), + int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + 0,proclist, + rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); memory->sfree(inbuf); - // flag all onefour atoms to keep + // flag all of my onefour IDs to keep int max = 0; for (i = 0; i < nlocal; i++) @@ -1145,8 +1146,6 @@ void Special::dihedral_trim() for (j = 0; j < nspecial[i][2]; j++) flag[i][j] = 0; - // reset nspecial[2] and onefour for all owned atoms based on output info - for (i = 0; i < nlocal; i++) { for (j = 0; j < num_dihedral[i]; j++) { if (tag[i] != dihedral_atom2[i][j]) continue; @@ -1251,7 +1250,7 @@ int Special::rendezvous_ids(int n, char *inbuf, sptr->procowner = procowner; sptr->atomIDs = atomIDs; - // flag = 0: no 2nd irregular comm needed in comm->rendezvous + // flag = 0: no second comm needed in rendezvous flag = 0; return 0; @@ -1272,7 +1271,7 @@ int Special::rendezvous_pairs(int n, char *inbuf, Atom *atom = sptr->atom; Memory *memory = sptr->memory; - // clear atom map so it can be here as a hash table + // clear atom map so it can be used here as a hash table // faster than an STL map for large atom counts atom->map_clear(); -- GitLab From 4ce68cf5fd776bd52a07befb93de7f197be49b69 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 23 Jan 2019 16:01:10 -0700 Subject: [PATCH 0091/1243] added diagnostic info for memory and balance info --- src/RIGID/fix_shake.cpp | 8 +- src/comm.cpp | 185 ++++++++++++++++++++++++++++++++++++---- src/comm.h | 6 +- src/irregular.cpp | 7 +- src/special.cpp | 12 +-- 5 files changed, 184 insertions(+), 34 deletions(-) diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 35153de839..46e478064c 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -1070,7 +1070,7 @@ void FixShake::atom_owners() char *buf; comm->rendezvous(1,nlocal,(char *) idbuf,sizeof(IDRvous), 0,proclist, - rendezvous_ids,0,buf,0,(void *) this); + rendezvous_ids,0,buf,0,(void *) this,1); memory->destroy(proclist); memory->sfree(idbuf); @@ -1178,7 +1178,7 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag, 0,proclist, rendezvous_partners_info, 0,buf,sizeof(PartnerInfo), - (void *) this); + (void *) this,1); PartnerInfo *outbuf = (PartnerInfo *) buf; memory->destroy(proclist); @@ -1266,7 +1266,7 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag, int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(NShakeInfo), 0,proclist, rendezvous_nshake,0,buf,sizeof(NShakeInfo), - (void *) this); + (void *) this,1); NShakeInfo *outbuf = (NShakeInfo *) buf; memory->destroy(proclist); @@ -1359,7 +1359,7 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag, int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(ShakeInfo), 0,proclist, rendezvous_shake,0,buf,sizeof(ShakeInfo), - (void *) this); + (void *) this,1); ShakeInfo *outbuf = (ShakeInfo *) buf; memory->destroy(proclist); diff --git a/src/comm.cpp b/src/comm.cpp index 39d4311aa2..54476078be 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -766,18 +766,14 @@ int Comm:: rendezvous(int which, int n, char *inbuf, int insize, int inorder, int *procs, int (*callback)(int, char *, int &, int *&, char *&, void *), - int outorder, char *&outbuf, int outsize, void *ptr) + int outorder, char *&outbuf, int outsize, void *ptr, int statflag) { - int nout; - if (which == 0) - nout = rendezvous_irregular(n,inbuf,insize,inorder,procs,callback, - outorder,outbuf,outsize,ptr); + return rendezvous_irregular(n,inbuf,insize,inorder,procs,callback, + outorder,outbuf,outsize,ptr,statflag); else - nout = rendezvous_all2all(n,inbuf,insize,inorder,procs,callback, - outorder,outbuf,outsize,ptr); - - return nout; + return rendezvous_all2all(n,inbuf,insize,inorder,procs,callback, + outorder,outbuf,outsize,ptr,statflag); } /* ---------------------------------------------------------------------- */ @@ -786,7 +782,7 @@ int Comm:: rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, int (*callback)(int, char *, int &, int *&, char *&, void *), int outorder, char *&outbuf, - int outsize, void *ptr) + int outsize, void *ptr, int statflag) { // irregular comm of inbuf from caller decomp to rendezvous decomp @@ -837,8 +833,82 @@ rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, memory->destroy(procs_rvous); memory->sfree(outbuf_rvous); - // approximate memory tally + // return number of output datums + + if (!statflag) return nout; + + // memory info for caller and rendezvous decompositions + + bigint size_in_all,size_in_max,size_in_min; + bigint size_out_all,size_out_max,size_out_min; + bigint size_inrvous_all,size_inrvous_max,size_inrvous_min; + bigint size_outrvous_all,size_outrvous_max,size_outrvous_min; + + bigint size = (bigint) n*insize; + MPI_Allreduce(&size,&size_in_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_in_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_in_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + size = (bigint) nout*outsize; + MPI_Allreduce(&size,&size_out_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_out_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_out_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + size = (bigint) nrvous*insize; + MPI_Allreduce(&size,&size_inrvous_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_inrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_inrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + size = (bigint) nrvous_out*insize; + MPI_Allreduce(&size,&size_outrvous_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_outrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_outrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + int mbytes = 1024*1024; + + if (me == 0) { + if (screen) { + fprintf(screen,"Rendezvous balance and memory info:\n"); + fprintf(screen," input datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_in_all/insize,1.0*size_in_all/nprocs/insize, + size_in_max/insize,size_in_min/insize); + fprintf(screen," input data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_in_all/mbytes,1.0*size_in_all/nprocs/mbytes, + 1.0*size_in_max/mbytes,1.0*size_in_min/mbytes); + fprintf(screen," output datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_out_all/outsize,1.0*size_out_all/nprocs/outsize, + size_out_max/outsize,size_out_min/outsize); + fprintf(screen," output data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_out_all/mbytes,1.0*size_out_all/nprocs/mbytes, + 1.0*size_out_max/mbytes,1.0*size_out_min/mbytes); + fprintf(screen," input rvous datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_inrvous_all/insize,1.0*size_inrvous_all/nprocs/insize, + size_inrvous_max/insize,size_inrvous_min/insize); + fprintf(screen," input rvous data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_inrvous_all/mbytes,1.0*size_inrvous_all/nprocs/mbytes, + 1.0*size_inrvous_max/mbytes,1.0*size_inrvous_min/mbytes); + fprintf(screen," output rvous datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_outrvous_all/outsize,1.0*size_outrvous_all/nprocs/outsize, + size_outrvous_max/outsize,size_outrvous_min/outsize); + fprintf(screen," output rvous data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_outrvous_all/mbytes,1.0*size_outrvous_all/nprocs/mbytes, + 1.0*size_outrvous_max/mbytes,1.0*size_outrvous_min/mbytes); + } + } + /* bigint rvous_bytes = 0; rvous_bytes += n*insize; // inbuf rvous_bytes += nout*outsize; // outbuf @@ -846,8 +916,7 @@ rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, rvous_bytes += nrvous_out*outsize; // outbuf_rvous rvous_bytes += nrvous_out*sizeof(int); // procs_rvous rvous_bytes += MAX(irregular1_bytes,irregular2_bytes); // max of 2 comms - - // return number of output datums + */ return nout; } @@ -857,7 +926,8 @@ rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, int Comm:: rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, int (*callback)(int, char *, int &, int *&, char *&, void *), - int outorder, char *&outbuf, int outsize, void *ptr) + int outorder, char *&outbuf, int outsize, void *ptr, + int statflag) { int iproc; bigint all2all1_bytes,all2all2_bytes; @@ -956,7 +1026,13 @@ rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, procs_rvous,outbuf_rvous,ptr); if (flag != 1) memory->sfree(inbuf_rvous); // outbuf_rvous = inbuf_vous - if (flag == 0) return 0; // all nout_rvous are 0, no 2nd irregular + if (flag == 0) { + memory->destroy(sendcount); + memory->destroy(recvcount); + memory->destroy(sdispls); + memory->destroy(rdispls); + return 0; // all nout_rvous are 0, no 2nd irregular + } // create procs and outbuf for All2all if necesary @@ -1044,8 +1120,82 @@ rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, memory->destroy(sdispls); memory->destroy(rdispls); - // approximate memory tally + // return number of output datums + + if (!statflag) return nout; + + // memory info for caller and rendezvous decompositions + + bigint size_in_all,size_in_max,size_in_min; + bigint size_out_all,size_out_max,size_out_min; + bigint size_inrvous_all,size_inrvous_max,size_inrvous_min; + bigint size_outrvous_all,size_outrvous_max,size_outrvous_min; + + bigint size = (bigint) n*insize; + MPI_Allreduce(&size,&size_in_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_in_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_in_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + size = (bigint) nout*outsize; + MPI_Allreduce(&size,&size_out_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_out_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_out_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + size = (bigint) nrvous*insize; + MPI_Allreduce(&size,&size_inrvous_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_inrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_inrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + size = (bigint) nrvous_out*insize; + MPI_Allreduce(&size,&size_outrvous_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_outrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_outrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + + int mbytes = 1024*1024; + + if (me == 0) { + if (screen) { + fprintf(screen,"Rendezvous balance and memory info:\n"); + fprintf(screen," input datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_in_all/insize,1.0*size_in_all/nprocs/insize, + size_in_max/insize,size_in_min/insize); + fprintf(screen," input data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_in_all/mbytes,1.0*size_in_all/nprocs/mbytes, + 1.0*size_in_max/mbytes,1.0*size_in_min/mbytes); + fprintf(screen," output datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_out_all/outsize,1.0*size_out_all/nprocs/outsize, + size_out_max/outsize,size_out_min/outsize); + fprintf(screen," output data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_out_all/mbytes,1.0*size_out_all/nprocs/mbytes, + 1.0*size_out_max/mbytes,1.0*size_out_min/mbytes); + fprintf(screen," input rvous datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_inrvous_all/insize,1.0*size_inrvous_all/nprocs/insize, + size_inrvous_max/insize,size_inrvous_min/insize); + fprintf(screen," input rvous data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_inrvous_all/mbytes,1.0*size_inrvous_all/nprocs/mbytes, + 1.0*size_inrvous_max/mbytes,1.0*size_inrvous_min/mbytes); + fprintf(screen," output rvous datum count " + "(tot,ave,max,min): " BIGINT_FORMAT " %g " + BIGINT_FORMAT " " BIGINT_FORMAT "\n", + size_outrvous_all/outsize,1.0*size_outrvous_all/nprocs/outsize, + size_outrvous_max/outsize,size_outrvous_min/outsize); + fprintf(screen," output rvous data (MB) " + "(tot,ave,max,min): %g %g %g %g\n", + 1.0*size_outrvous_all/mbytes,1.0*size_outrvous_all/nprocs/mbytes, + 1.0*size_outrvous_max/mbytes,1.0*size_outrvous_min/mbytes); + } + } + + /* bigint rvous_bytes = 0; rvous_bytes += n*insize; // inbuf rvous_bytes += nout*outsize; // outbuf @@ -1054,8 +1204,7 @@ rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, rvous_bytes += nrvous_out*sizeof(int); // procs_rvous rvous_bytes += 4*nprocs*sizeof(int); // all2all vectors rvous_bytes += MAX(all2all1_bytes,all2all2_bytes); // reorder ops - - // return number of datums + */ return nout; } diff --git a/src/comm.h b/src/comm.h index 807da9bf0d..89889e3ebe 100644 --- a/src/comm.h +++ b/src/comm.h @@ -111,7 +111,7 @@ class Comm : protected Pointers { void *, void *, int self = 1); int rendezvous(int, int, char *, int, int, int *, int (*)(int, char *, int &, int *&, char *&, void *), - int, char *&, int, void *); + int, char *&, int, void *, int statflag=0); int read_lines_from_file(FILE *, int, int, char *); int read_lines_from_file_universe(FILE *, int, int, char *); @@ -149,10 +149,10 @@ class Comm : protected Pointers { int rendezvous_irregular(int, char *, int, int, int *, int (*)(int, char *, int &, int *&, char *&, void *), - int, char *&, int, void *); + int, char *&, int, void *, int); int rendezvous_all2all(int, char *, int, int, int *, int (*)(int, char *, int &, int *&, char *&, void *), - int, char *&, int, void *); + int, char *&, int, void *, int); public: enum{MULTIPLE}; diff --git a/src/irregular.cpp b/src/irregular.cpp index 77278ec4c5..c27a8c8e18 100644 --- a/src/irregular.cpp +++ b/src/irregular.cpp @@ -966,10 +966,11 @@ void Irregular::exchange_data(char *sendbuf, int nbytes, char *recvbuf) if (nrecv_proc) MPI_Waitall(nrecv_proc,request,status); // approximate memory tally + // DEBUG lines - bigint irregular_bytes = 2*nprocs*sizeof(int); - irregular_bytes += maxindex*sizeof(int); - irregular_bytes += maxbuf; + //bigint irregular_bytes = 2*nprocs*sizeof(int); + //irregular_bytes += maxindex*sizeof(int); + //irregular_bytes += maxbuf; } /* ---------------------------------------------------------------------- diff --git a/src/special.cpp b/src/special.cpp index 34685d8c65..5e0f865488 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -186,7 +186,7 @@ void Special::atom_owners() char *buf; comm->rendezvous(1,nlocal,(char *) idbuf,sizeof(IDRvous),0,proclist, - rendezvous_ids,0,buf,0,(void *) this); + rendezvous_ids,0,buf,0,(void *) this,1); memory->destroy(proclist); memory->sfree(idbuf); @@ -244,7 +244,7 @@ void Special::onetwo_build_newton() int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + (void *) this,1); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -379,7 +379,7 @@ void Special::onethree_build() int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + (void *) this,1); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -484,7 +484,7 @@ void Special::onefour_build() int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + (void *) this,1); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -907,7 +907,7 @@ void Special::angle_trim() int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + (void *) this,1); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); @@ -1126,7 +1126,7 @@ void Special::dihedral_trim() int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), - (void *) this); + (void *) this,1); PairRvous *outbuf = (PairRvous *) buf; memory->destroy(proclist); -- GitLab From a278df586d72850c71a318b550d8f3f9de69e5f0 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 24 Jan 2019 09:56:21 -0700 Subject: [PATCH 0092/1243] cleanup up rendezvous diagnostic output --- src/RIGID/fix_rigid_small.cpp | 19 +++- src/RIGID/fix_shake.cpp | 10 ++- src/comm.cpp | 163 +++++++++------------------------- src/comm.h | 1 + src/special.cpp | 14 +-- 5 files changed, 73 insertions(+), 134 deletions(-) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index 957438fc55..bee5570316 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -28,6 +28,7 @@ #include "modify.h" #include "group.h" #include "comm.h" +#include "neighbor.h" #include "force.h" #include "input.h" #include "output.h" @@ -44,6 +45,8 @@ using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; +#define RVOUS 1 // 0 for irregular, 1 for all2all + #define MAXLINE 1024 #define CHUNK 1024 #define ATTRIBUTE_PERBODY 20 @@ -585,12 +588,22 @@ void FixRigidSmall::init() if (rflag && (modify->fmask[i] & POST_FORCE) && !modify->fix[i]->rigid_flag) { char str[128]; - snprintf(str,128,"Fix %s alters forces after fix rigid",modify->fix[i]->id); + snprintf(str,128,"Fix %s alters forces after fix rigid", + modify->fix[i]->id); error->warning(FLERR,str); } } } + // error if maxextent > comm->cutghost + // NOTE: could just warn if an override flag set + // NOTE: this could fail for comm multi mode if user sets a wrong cutoff + // for atom types in rigid bodies - need a more careful test + + double cutghost = MAX(neighbor->cutneighmax,comm->cutghostuser); + if (maxextent > cutghost) + error->all(FLERR,"Rigid body extent > ghost cutoff - use comm_modify cutoff"); + // error if npt,nph fix comes before rigid fix for (i = 0; i < modify->nfix; i++) { @@ -1576,10 +1589,10 @@ void FixRigidSmall::create_bodies(tagint *bodyID) // func = compute bbox of each body, find atom closest to geometric center char *buf; - int nreturn = comm->rendezvous(1,ncount,(char *) inbuf,sizeof(InRvous), + int nreturn = comm->rendezvous(RVOUS,ncount,(char *) inbuf,sizeof(InRvous), 0,proclist, rendezvous_body,0,buf,sizeof(OutRvous), - (void *) this); + (void *) this,1); OutRvous *outbuf = (OutRvous *) buf; memory->destroy(proclist); diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 46e478064c..2d3244885d 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -39,6 +39,8 @@ using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; +#define RVOUS 1 // 0 for irregular, 1 for all2all + #define BIG 1.0e20 #define MASSDELTA 0.1 @@ -1068,7 +1070,7 @@ void FixShake::atom_owners() // each proc assigned every 1/Pth atom char *buf; - comm->rendezvous(1,nlocal,(char *) idbuf,sizeof(IDRvous), + comm->rendezvous(RVOUS,nlocal,(char *) idbuf,sizeof(IDRvous), 0,proclist, rendezvous_ids,0,buf,0,(void *) this,1); @@ -1174,7 +1176,7 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag, // receives all data needed to populate un-owned partner 4 values char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PartnerInfo), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PartnerInfo), 0,proclist, rendezvous_partners_info, 0,buf,sizeof(PartnerInfo), @@ -1263,7 +1265,7 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag, // receives all data needed to populate un-owned partner nshake char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(NShakeInfo), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(NShakeInfo), 0,proclist, rendezvous_nshake,0,buf,sizeof(NShakeInfo), (void *) this,1); @@ -1356,7 +1358,7 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag, // receives all data needed to populate un-owned shake info char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(ShakeInfo), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(ShakeInfo), 0,proclist, rendezvous_shake,0,buf,sizeof(ShakeInfo), (void *) this,1); diff --git a/src/comm.cpp b/src/comm.cpp index 54476078be..e8a796036c 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -796,7 +796,7 @@ rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, "rendezvous:inbuf"); irregular->exchange_data(inbuf,insize,inbuf_rvous); - bigint irregular1_bytes = 0; //irregular->irregular_bytes; + bigint irregular1_bytes = irregular->memory_usage(); irregular->destroy_data(); delete irregular; @@ -826,7 +826,7 @@ rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, "rendezvous:outbuf"); irregular->exchange_data(outbuf_rvous,outsize,outbuf); - bigint irregular2_bytes = 0; //irregular->irregular_bytes; + bigint irregular2_bytes = irregular->memory_usage(); irregular->destroy_data(); delete irregular; @@ -834,90 +834,11 @@ rendezvous_irregular(int n, char *inbuf, int insize, int inorder, int *procs, memory->sfree(outbuf_rvous); // return number of output datums + // last arg to stats() = memory for procs_rvous + irregular comm - if (!statflag) return nout; - - // memory info for caller and rendezvous decompositions - - bigint size_in_all,size_in_max,size_in_min; - bigint size_out_all,size_out_max,size_out_min; - bigint size_inrvous_all,size_inrvous_max,size_inrvous_min; - bigint size_outrvous_all,size_outrvous_max,size_outrvous_min; - - bigint size = (bigint) n*insize; - MPI_Allreduce(&size,&size_in_all,1,MPI_LMP_BIGINT,MPI_SUM,world); - MPI_Allreduce(&size,&size_in_max,1,MPI_LMP_BIGINT,MPI_MAX,world); - MPI_Allreduce(&size,&size_in_min,1,MPI_LMP_BIGINT,MPI_MIN,world); - - size = (bigint) nout*outsize; - MPI_Allreduce(&size,&size_out_all,1,MPI_LMP_BIGINT,MPI_SUM,world); - MPI_Allreduce(&size,&size_out_max,1,MPI_LMP_BIGINT,MPI_MAX,world); - MPI_Allreduce(&size,&size_out_min,1,MPI_LMP_BIGINT,MPI_MIN,world); - - size = (bigint) nrvous*insize; - MPI_Allreduce(&size,&size_inrvous_all,1,MPI_LMP_BIGINT,MPI_SUM,world); - MPI_Allreduce(&size,&size_inrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); - MPI_Allreduce(&size,&size_inrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); - - size = (bigint) nrvous_out*insize; - MPI_Allreduce(&size,&size_outrvous_all,1,MPI_LMP_BIGINT,MPI_SUM,world); - MPI_Allreduce(&size,&size_outrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); - MPI_Allreduce(&size,&size_outrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); - - int mbytes = 1024*1024; - - if (me == 0) { - if (screen) { - fprintf(screen,"Rendezvous balance and memory info:\n"); - fprintf(screen," input datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", - size_in_all/insize,1.0*size_in_all/nprocs/insize, - size_in_max/insize,size_in_min/insize); - fprintf(screen," input data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", - 1.0*size_in_all/mbytes,1.0*size_in_all/nprocs/mbytes, - 1.0*size_in_max/mbytes,1.0*size_in_min/mbytes); - fprintf(screen," output datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", - size_out_all/outsize,1.0*size_out_all/nprocs/outsize, - size_out_max/outsize,size_out_min/outsize); - fprintf(screen," output data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", - 1.0*size_out_all/mbytes,1.0*size_out_all/nprocs/mbytes, - 1.0*size_out_max/mbytes,1.0*size_out_min/mbytes); - fprintf(screen," input rvous datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", - size_inrvous_all/insize,1.0*size_inrvous_all/nprocs/insize, - size_inrvous_max/insize,size_inrvous_min/insize); - fprintf(screen," input rvous data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", - 1.0*size_inrvous_all/mbytes,1.0*size_inrvous_all/nprocs/mbytes, - 1.0*size_inrvous_max/mbytes,1.0*size_inrvous_min/mbytes); - fprintf(screen," output rvous datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", - size_outrvous_all/outsize,1.0*size_outrvous_all/nprocs/outsize, - size_outrvous_max/outsize,size_outrvous_min/outsize); - fprintf(screen," output rvous data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", - 1.0*size_outrvous_all/mbytes,1.0*size_outrvous_all/nprocs/mbytes, - 1.0*size_outrvous_max/mbytes,1.0*size_outrvous_min/mbytes); - } - } - - /* - bigint rvous_bytes = 0; - rvous_bytes += n*insize; // inbuf - rvous_bytes += nout*outsize; // outbuf - rvous_bytes += nrvous*insize; // inbuf_rvous - rvous_bytes += nrvous_out*outsize; // outbuf_rvous - rvous_bytes += nrvous_out*sizeof(int); // procs_rvous - rvous_bytes += MAX(irregular1_bytes,irregular2_bytes); // max of 2 comms - */ - + if (statflag) rendezvous_stats(n,nout,nrvous,nrvous_out,insize,outsize, + (bigint) nrvous_out*sizeof(int) + + MAX(irregular1_bytes,irregular2_bytes)); return nout; } @@ -1121,15 +1042,28 @@ rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, memory->destroy(rdispls); // return number of output datums + // last arg to stats() = mem for procs_rvous + per-proc vecs + reordering ops - if (!statflag) return nout; + if (statflag) rendezvous_stats(n,nout,nrvous,nrvous_out,insize,outsize, + (bigint) nrvous_out*sizeof(int) + + 4*nprocs*sizeof(int) + + MAX(all2all1_bytes,all2all2_bytes)); + return nout; +} - // memory info for caller and rendezvous decompositions +/* ---------------------------------------------------------------------- + print balance and memory info for rendezvous operation + useful for debugging +------------------------------------------------------------------------- */ +void Comm::rendezvous_stats(int n, int nout, int nrvous, int nrvous_out, + int insize, int outsize, bigint commsize) +{ bigint size_in_all,size_in_max,size_in_min; bigint size_out_all,size_out_max,size_out_min; bigint size_inrvous_all,size_inrvous_max,size_inrvous_min; bigint size_outrvous_all,size_outrvous_max,size_outrvous_min; + bigint size_comm_all,size_comm_max,size_comm_min; bigint size = (bigint) n*insize; MPI_Allreduce(&size,&size_in_all,1,MPI_LMP_BIGINT,MPI_SUM,world); @@ -1151,62 +1085,49 @@ rendezvous_all2all(int n, char *inbuf, int insize, int inorder, int *procs, MPI_Allreduce(&size,&size_outrvous_max,1,MPI_LMP_BIGINT,MPI_MAX,world); MPI_Allreduce(&size,&size_outrvous_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + size = commsize; + MPI_Allreduce(&size,&size_comm_all,1,MPI_LMP_BIGINT,MPI_SUM,world); + MPI_Allreduce(&size,&size_comm_max,1,MPI_LMP_BIGINT,MPI_MAX,world); + MPI_Allreduce(&size,&size_comm_min,1,MPI_LMP_BIGINT,MPI_MIN,world); + int mbytes = 1024*1024; if (me == 0) { if (screen) { - fprintf(screen,"Rendezvous balance and memory info:\n"); - fprintf(screen," input datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", + fprintf(screen,"Rendezvous balance and memory info: (tot,ave,max,min) \n"); + fprintf(screen," input datum count: " + BIGINT_FORMAT " %g " BIGINT_FORMAT " " BIGINT_FORMAT "\n", size_in_all/insize,1.0*size_in_all/nprocs/insize, size_in_max/insize,size_in_min/insize); - fprintf(screen," input data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", + fprintf(screen," input data (MB): %g %g %g %g\n", 1.0*size_in_all/mbytes,1.0*size_in_all/nprocs/mbytes, 1.0*size_in_max/mbytes,1.0*size_in_min/mbytes); - fprintf(screen," output datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", + fprintf(screen," output datum count: " + BIGINT_FORMAT " %g " BIGINT_FORMAT " " BIGINT_FORMAT "\n", size_out_all/outsize,1.0*size_out_all/nprocs/outsize, size_out_max/outsize,size_out_min/outsize); - fprintf(screen," output data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", + fprintf(screen," output data (MB): %g %g %g %g\n", 1.0*size_out_all/mbytes,1.0*size_out_all/nprocs/mbytes, 1.0*size_out_max/mbytes,1.0*size_out_min/mbytes); - fprintf(screen," input rvous datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", + fprintf(screen," input rvous datum count: " + BIGINT_FORMAT " %g " BIGINT_FORMAT " " BIGINT_FORMAT "\n", size_inrvous_all/insize,1.0*size_inrvous_all/nprocs/insize, size_inrvous_max/insize,size_inrvous_min/insize); - fprintf(screen," input rvous data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", + fprintf(screen," input rvous data (MB): %g %g %g %g\n", 1.0*size_inrvous_all/mbytes,1.0*size_inrvous_all/nprocs/mbytes, 1.0*size_inrvous_max/mbytes,1.0*size_inrvous_min/mbytes); - fprintf(screen," output rvous datum count " - "(tot,ave,max,min): " BIGINT_FORMAT " %g " - BIGINT_FORMAT " " BIGINT_FORMAT "\n", + fprintf(screen," output rvous datum count: " + BIGINT_FORMAT " %g " BIGINT_FORMAT " " BIGINT_FORMAT "\n", size_outrvous_all/outsize,1.0*size_outrvous_all/nprocs/outsize, size_outrvous_max/outsize,size_outrvous_min/outsize); - fprintf(screen," output rvous data (MB) " - "(tot,ave,max,min): %g %g %g %g\n", + fprintf(screen," output rvous data (MB): %g %g %g %g\n", 1.0*size_outrvous_all/mbytes,1.0*size_outrvous_all/nprocs/mbytes, 1.0*size_outrvous_max/mbytes,1.0*size_outrvous_min/mbytes); + fprintf(screen," rvous comm (MB): %g %g %g %g\n", + 1.0*size_comm_all/mbytes,1.0*size_comm_all/nprocs/mbytes, + 1.0*size_comm_max/mbytes,1.0*size_comm_min/mbytes); } } - - /* - bigint rvous_bytes = 0; - rvous_bytes += n*insize; // inbuf - rvous_bytes += nout*outsize; // outbuf - rvous_bytes += nrvous*insize; // inbuf_rvous - rvous_bytes += nrvous_out*outsize; // outbuf_rvous - rvous_bytes += nrvous_out*sizeof(int); // procs_rvous - rvous_bytes += 4*nprocs*sizeof(int); // all2all vectors - rvous_bytes += MAX(all2all1_bytes,all2all2_bytes); // reorder ops - */ - - return nout; } /* ---------------------------------------------------------------------- diff --git a/src/comm.h b/src/comm.h index 89889e3ebe..9c0112b4c4 100644 --- a/src/comm.h +++ b/src/comm.h @@ -153,6 +153,7 @@ class Comm : protected Pointers { int rendezvous_all2all(int, char *, int, int, int *, int (*)(int, char *, int &, int *&, char *&, void *), int, char *&, int, void *, int); + void rendezvous_stats(int, int, int, int, int, int, bigint); public: enum{MULTIPLE}; diff --git a/src/special.cpp b/src/special.cpp index 5e0f865488..a0739d6ccc 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -27,6 +27,8 @@ using namespace LAMMPS_NS; +#define RVOUS 1 // 0 for irregular, 1 for all2all + /* ---------------------------------------------------------------------- */ Special::Special(LAMMPS *lmp) : Pointers(lmp) @@ -185,7 +187,7 @@ void Special::atom_owners() // perform rendezvous operation char *buf; - comm->rendezvous(1,nlocal,(char *) idbuf,sizeof(IDRvous),0,proclist, + comm->rendezvous(RVOUS,nlocal,(char *) idbuf,sizeof(IDRvous),0,proclist, rendezvous_ids,0,buf,0,(void *) this,1); memory->destroy(proclist); @@ -241,7 +243,7 @@ void Special::onetwo_build_newton() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this,1); @@ -376,7 +378,7 @@ void Special::onethree_build() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this,1); @@ -481,7 +483,7 @@ void Special::onefour_build() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this,1); @@ -904,7 +906,7 @@ void Special::angle_trim() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this,1); @@ -1123,7 +1125,7 @@ void Special::dihedral_trim() // perform rendezvous operation char *buf; - int nreturn = comm->rendezvous(1,nsend,(char *) inbuf,sizeof(PairRvous), + int nreturn = comm->rendezvous(RVOUS,nsend,(char *) inbuf,sizeof(PairRvous), 0,proclist, rendezvous_pairs,0,buf,sizeof(PairRvous), (void *) this,1); -- GitLab From 08b1728a963aac4361fcb5031f29f0640b0303e4 Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 29 Jan 2019 13:05:03 -0700 Subject: [PATCH 0093/1243] Commit JT 012919 - commit tuesday evening, second day imp. - dev. fix_neb_spin --- examples/SPIN/gneb_bfo/README | 5 + examples/SPIN/gneb_bfo/Si.sw | 18 + examples/SPIN/gneb_bfo/final.hop1 | 2 + examples/SPIN/gneb_bfo/final.iron_spin | 68 + examples/SPIN/gneb_bfo/final.iron_spin_data | 82 ++ examples/SPIN/gneb_bfo/in.neb.hop1 | 66 + examples/SPIN/gneb_bfo/in.neb.spin_iron | 100 ++ examples/SPIN/gneb_bfo/in.spin.bfo | 56 + examples/SPIN/gneb_bfo/in.spin.iron | 56 + examples/SPIN/gneb_bfo/in.spin.single_spin | 57 + examples/SPIN/gneb_bfo/in.tad | 110 ++ examples/SPIN/gneb_bfo/initial.hop1 | 860 +++++++++++++ examples/SPIN/gneb_bfo/initial.iron_spin | 82 ++ src/REPLICA/fix_neb_spin.cpp | 1226 +++++++++++++++++++ src/REPLICA/fix_neb_spin.h | 115 ++ src/REPLICA/neb_spin.cpp | 722 +++++++++++ src/REPLICA/neb_spin.h | 137 +++ 17 files changed, 3762 insertions(+) create mode 100644 examples/SPIN/gneb_bfo/README create mode 100644 examples/SPIN/gneb_bfo/Si.sw create mode 100644 examples/SPIN/gneb_bfo/final.hop1 create mode 100644 examples/SPIN/gneb_bfo/final.iron_spin create mode 100644 examples/SPIN/gneb_bfo/final.iron_spin_data create mode 100644 examples/SPIN/gneb_bfo/in.neb.hop1 create mode 100644 examples/SPIN/gneb_bfo/in.neb.spin_iron create mode 100644 examples/SPIN/gneb_bfo/in.spin.bfo create mode 100644 examples/SPIN/gneb_bfo/in.spin.iron create mode 100644 examples/SPIN/gneb_bfo/in.spin.single_spin create mode 100644 examples/SPIN/gneb_bfo/in.tad create mode 100644 examples/SPIN/gneb_bfo/initial.hop1 create mode 100644 examples/SPIN/gneb_bfo/initial.iron_spin create mode 100644 src/REPLICA/fix_neb_spin.cpp create mode 100644 src/REPLICA/fix_neb_spin.h create mode 100644 src/REPLICA/neb_spin.cpp create mode 100644 src/REPLICA/neb_spin.h diff --git a/examples/SPIN/gneb_bfo/README b/examples/SPIN/gneb_bfo/README new file mode 100644 index 0000000000..eeb4aa4692 --- /dev/null +++ b/examples/SPIN/gneb_bfo/README @@ -0,0 +1,5 @@ +Run this example as: + +mpirun -np 3 lmp_g++ -partition 3x1 -in in.tad + +You should be able to use any number of replicas >= 3. diff --git a/examples/SPIN/gneb_bfo/Si.sw b/examples/SPIN/gneb_bfo/Si.sw new file mode 100644 index 0000000000..db4be100ef --- /dev/null +++ b/examples/SPIN/gneb_bfo/Si.sw @@ -0,0 +1,18 @@ +# DATE: 2007-06-11 CONTRIBUTOR: Aidan Thompson, athomps@sandia.gov CITATION: Stillinger and Weber, Phys Rev B, 31, 5262, (1985) +# Stillinger-Weber 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: +# epsilon = eV; sigma = Angstroms +# other quantities are unitless + +# format of a single entry (one or more lines): +# element 1, element 2, element 3, +# epsilon, sigma, a, lambda, gamma, costheta0, A, B, p, q, tol + +# Here are the original parameters in metal units, for Silicon from: +# +# Stillinger and Weber, Phys. Rev. B, v. 31, p. 5262, (1985) +# + +Si Si Si 2.1683 2.0951 1.80 21.0 1.20 -0.333333333333 + 7.049556277 0.6022245584 4.0 0.0 0.0 diff --git a/examples/SPIN/gneb_bfo/final.hop1 b/examples/SPIN/gneb_bfo/final.hop1 new file mode 100644 index 0000000000..338e674a9c --- /dev/null +++ b/examples/SPIN/gneb_bfo/final.hop1 @@ -0,0 +1,2 @@ +1 +412 14.0 20.5 0 diff --git a/examples/SPIN/gneb_bfo/final.iron_spin b/examples/SPIN/gneb_bfo/final.iron_spin new file mode 100644 index 0000000000..a921287ccb --- /dev/null +++ b/examples/SPIN/gneb_bfo/final.iron_spin @@ -0,0 +1,68 @@ +32 +2.2000000000000002e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 2.8664999999999998e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 5.7329999999999997e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 8.5994999999999990e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 0.0000000000000000e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 2.8664999999999998e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 5.7329999999999997e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 8.5994999999999990e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.4332499999999999e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 4.2997499999999995e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 7.1662499999999998e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.0032750000000000e+01 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 0.0000000000000000e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.4332499999999999e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 2.8664999999999998e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 4.2997499999999995e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 5.7329999999999997e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 7.1662499999999998e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 8.5994999999999990e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.0032750000000000e+01 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 0.0000000000000000e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 2.8664999999999998e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 5.7329999999999997e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 8.5994999999999990e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.4332499999999999e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 4.2997499999999995e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 7.1662499999999998e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2.2000000000000002e+00 1.0032750000000000e+01 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/SPIN/gneb_bfo/final.iron_spin_data b/examples/SPIN/gneb_bfo/final.iron_spin_data new file mode 100644 index 0000000000..b337bac188 --- /dev/null +++ b/examples/SPIN/gneb_bfo/final.iron_spin_data @@ -0,0 +1,82 @@ +LAMMPS data file via write_data, version 4 Jan 2019, timestep = 0 + +32 atoms +1 atom types + +0.0000000000000000e+00 1.1465999999999999e+01 xlo xhi +0.0000000000000000e+00 1.1465999999999999e+01 ylo yhi +0.0000000000000000e+00 2.8664999999999998e+00 zlo zhi + +Masses + +1 55.845 + +Atoms # spin + +1 1 2.2000000000000002e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +2 1 2.2000000000000002e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +3 1 2.2000000000000002e+00 2.8664999999999998e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +4 1 2.2000000000000002e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +5 1 2.2000000000000002e+00 5.7329999999999997e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +6 1 2.2000000000000002e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +7 1 2.2000000000000002e+00 8.5994999999999990e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +8 1 2.2000000000000002e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +9 1 2.2000000000000002e+00 0.0000000000000000e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +11 1 2.2000000000000002e+00 2.8664999999999998e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +13 1 2.2000000000000002e+00 5.7329999999999997e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +15 1 2.2000000000000002e+00 8.5994999999999990e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +10 1 2.2000000000000002e+00 1.4332499999999999e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +12 1 2.2000000000000002e+00 4.2997499999999995e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +14 1 2.2000000000000002e+00 7.1662499999999998e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +16 1 2.2000000000000002e+00 1.0032750000000000e+01 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +17 1 2.2000000000000002e+00 0.0000000000000000e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +18 1 2.2000000000000002e+00 1.4332499999999999e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +19 1 2.2000000000000002e+00 2.8664999999999998e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +20 1 2.2000000000000002e+00 4.2997499999999995e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +21 1 2.2000000000000002e+00 5.7329999999999997e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +22 1 2.2000000000000002e+00 7.1662499999999998e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +23 1 2.2000000000000002e+00 8.5994999999999990e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +24 1 2.2000000000000002e+00 1.0032750000000000e+01 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +25 1 2.2000000000000002e+00 0.0000000000000000e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +27 1 2.2000000000000002e+00 2.8664999999999998e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +29 1 2.2000000000000002e+00 5.7329999999999997e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +31 1 2.2000000000000002e+00 8.5994999999999990e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +26 1 2.2000000000000002e+00 1.4332499999999999e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +28 1 2.2000000000000002e+00 4.2997499999999995e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +30 1 2.2000000000000002e+00 7.1662499999999998e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +32 1 2.2000000000000002e+00 1.0032750000000000e+01 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 + +Velocities + +1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 diff --git a/examples/SPIN/gneb_bfo/in.neb.hop1 b/examples/SPIN/gneb_bfo/in.neb.hop1 new file mode 100644 index 0000000000..4e203afd82 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.neb.hop1 @@ -0,0 +1,66 @@ +# 2d NEB surface simulation, hop from surface to become adatom + +dimension 2 +boundary p s p + +atom_style atomic +neighbor 0.3 bin +neigh_modify delay 5 +atom_modify map array sort 0 0.0 + +variable u uloop 20 + +# create geometry with flat surface + +lattice hex 0.9 +region box block 0 20 0 10 -0.25 0.25 + +#create_box 3 box +#create_atoms 1 box +#mass * 1.0 +#write_data initial.hop1 + +read_data ../examples/SPIN/gneb_bfo/initial.hop1 + +# LJ potentials + +pair_style lj/cut 2.5 +pair_coeff * * 1.0 1.0 2.5 +pair_modify shift yes + +# initial minimization to relax surface + +minimize 1.0e-6 1.0e-4 1000 10000 +reset_timestep 0 + +# define groups + +region 1 block INF INF INF 1.25 INF INF +group lower region 1 +group mobile subtract all lower +set group lower type 2 + +timestep 0.05 + +# group of NEB atoms - either block or single atom ID 412 + +region surround block 10 18 17 20 0 0 units box +group nebatoms region surround +#group nebatoms id 412 +set group nebatoms type 3 +group nonneb subtract all nebatoms + +fix 1 lower setforce 0.0 0.0 0.0 +fix 2 nebatoms neb 1.0 parallel ideal +fix 3 all enforce2d + +thermo 100 + +#dump 1 nebatoms atom 10 dump.neb.$u +#dump 2 nonneb atom 10 dump.nonneb.$u + +# run NEB for 2000 steps or to force tolerance + +min_style quickmin + +neb 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.hop1 diff --git a/examples/SPIN/gneb_bfo/in.neb.spin_iron b/examples/SPIN/gneb_bfo/in.neb.spin_iron new file mode 100644 index 0000000000..6b99cd4639 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.neb.spin_iron @@ -0,0 +1,100 @@ +# bcc iron in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary p p f + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice bcc 2.8665 +region box block 0.0 4.0 0.0 4.0 0.0 1.0 +#create_box 1 box +#create_atoms 1 box + +read_data ../examples/SPIN/gneb_bfo/initial.iron_spin + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 55.845 +set group all spin 2.2 -1.0 0.0 0.0 + +pair_style spin/exchange 3.5 +pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.0 21 +fix 2 nebatoms neb_spin 1.0 +#parallel ideal + +min_style quickmin +neb 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin + + +############################################################# + +# 2d NEB surface simulation, hop from surface to become adatom + + +variable u uloop 20 + +# create geometry with flat surface + +lattice hex 0.9 +region box block 0 20 0 10 -0.25 0.25 + +#create_box 3 box +#create_atoms 1 box +#mass * 1.0 +#write_data initial.hop1 + +read_data ../examples/SPIN/gneb_bfo/initial.hop1 + +# LJ potentials + +pair_style lj/cut 2.5 +pair_coeff * * 1.0 1.0 2.5 +pair_modify shift yes + +# initial minimization to relax surface + +minimize 1.0e-6 1.0e-4 1000 10000 +reset_timestep 0 + +# define groups + +region 1 block INF INF INF 1.25 INF INF +group lower region 1 +group mobile subtract all lower +set group lower type 2 + +timestep 0.05 + +# group of NEB atoms - either block or single atom ID 412 + +region surround block 10 18 17 20 0 0 units box +group nebatoms region surround +#group nebatoms id 412 +set group nebatoms type 3 +group nonneb subtract all nebatoms + +fix 1 lower setforce 0.0 0.0 0.0 +fix 2 nebatoms neb 1.0 parallel ideal +fix 3 all enforce2d + +thermo 100 + +#dump 1 nebatoms atom 10 dump.neb.$u +#dump 2 nonneb atom 10 dump.nonneb.$u + +# run NEB for 2000 steps or to force tolerance + +min_style quickmin + +neb 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.hop1 diff --git a/examples/SPIN/gneb_bfo/in.spin.bfo b/examples/SPIN/gneb_bfo/in.spin.bfo new file mode 100644 index 0000000000..e3c88b0f06 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.spin.bfo @@ -0,0 +1,56 @@ +# layer sc iron atoms (in the [001] plane) in bismuth oxide + +clear +units metal +atom_style spin + +dimension 3 +boundary p p f + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice sc 3.96 +region box block 0.0 34.0 0.0 34.0 0.0 5.0 +create_box 1 box +create_atoms 1 box + +# setting mass, mag. moments, and interactions for bfo + +mass 1 1.0 + +set group all spin/random 11 2.50 + +#pair_style hybrid/overlay spin/exchange 6.0 spin/magelec 4.5 +pair_style hybrid/overlay spin/exchange 6.0 spin/magelec 4.5 spin/dmi 4.5 +pair_coeff * * spin/exchange exchange 6.0 -0.01575 0.0 1.965 +pair_coeff * * spin/magelec magelec 4.5 0.000109 1.0 1.0 1.0 +pair_coeff * * spin/dmi dmi 4.5 0.00005 1.0 1.0 1.0 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +fix 1 all precession/spin anisotropy 0.0000033 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.1 21 +fix 3 all nve/spin lattice no + +timestep 0.0002 + +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +#thermo_style custom step time v_magnorm v_emag temp etotal +thermo_style custom step time v_magnorm pe ke v_emag temp etotal +thermo 10 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +run 2000 diff --git a/examples/SPIN/gneb_bfo/in.spin.iron b/examples/SPIN/gneb_bfo/in.spin.iron new file mode 100644 index 0000000000..6d291c633b --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.spin.iron @@ -0,0 +1,56 @@ +# bcc iron in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary p p p + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice bcc 2.8665 +region box block 0.0 4.0 0.0 4.0 0.0 1.0 +create_box 1 box +create_atoms 1 box + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 55.845 + +set group all spin 2.2 -1.0 0.0 0.0 +#velocity all create 100 4928459 rot yes dist gaussian + +pair_style spin/exchange 3.5 +pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 +fix 2 all langevin/spin 0.0 0.0 21 + +fix 3 all nve/spin lattice yes +timestep 0.0001 + +# compute and output options + +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo_style custom step time v_magnorm v_tmag temp v_emag ke pe etotal +thermo 50 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +run 0 +write_data final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spin.single_spin b/examples/SPIN/gneb_bfo/in.spin.single_spin new file mode 100644 index 0000000000..3a63c87b8c --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.spin.single_spin @@ -0,0 +1,57 @@ +# bcc iron in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary f f f +#boundary p p p + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice sc 2.8665 +region box block 0.0 1.0 0.0 1.0 0.0 1.0 +create_box 1 box +create_atoms 1 box + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 55.845 + +set group all spin 2.2 0.0 0.0 1.0 +#velocity all create 100 4928459 rot yes dist gaussian + +pair_style spin/exchange 3.5 +pair_coeff * * exchange 3.4 0.0 0.2171 1.841 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +fix 1 all precession/spin zeeman 0.01 0.0 1.0 0.0 anisotropy 0.005 0.0 0.0 1.0 +fix 2 all langevin/spin 50.0 0.1 21 + +fix 3 all nve/spin lattice no +timestep 0.0001 + +# compute and output options + +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo_style custom step time v_magz v_magnorm v_tmag temp v_emag ke pe etotal +thermo 100 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +run 50000 +write_data final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.tad b/examples/SPIN/gneb_bfo/in.tad new file mode 100644 index 0000000000..674fdc8172 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.tad @@ -0,0 +1,110 @@ +# temperature accelerated dynamics model for a single vacancy in bulk Si +# events occur when a neighboring atom diffuses to the vacant site +# run this on multiple partitions as +# mpirun -np 3 lmp_g++ -partition 3x1 -in in.tad + +units metal + +atom_style atomic +atom_modify map array +boundary p p p +atom_modify sort 0 0.0 + +# temperatures +variable tlo equal 1800.0 +variable thi equal 2400.0 + +# coordination number cutoff + +variable r equal 2.835 + +# minimization parameters + +variable etol equal 1.0e-5 +variable ftol equal 1.0e-5 +variable maxiter equal 100 +variable maxeval equal 100 +variable dmax equal 1.0e-1 + +# diamond unit cell + +variable a equal 5.431 +lattice custom $a & + a1 1.0 0.0 0.0 & + a2 0.0 1.0 0.0 & + a3 0.0 0.0 1.0 & + basis 0.0 0.0 0.0 & + basis 0.0 0.5 0.5 & + basis 0.5 0.0 0.5 & + basis 0.5 0.5 0.0 & + basis 0.25 0.25 0.25 & + basis 0.25 0.75 0.75 & + basis 0.75 0.25 0.75 & + basis 0.75 0.75 0.25 + +region myreg block 0 4 & + 0 4 & + 0 4 +create_box 1 myreg +create_atoms 1 region myreg + +mass 1 28.06 + +group Si type 1 + +velocity all create ${thi} 5287286 mom yes rot yes dist gaussian + +# make a vacancy + +group del id 300 +delete_atoms group del + +pair_style sw +pair_coeff * * ../examples/SPIN/gneb_bfo/Si.sw Si + +thermo 10 + +fix 1 all nve +fix 2 all langevin ${thi} ${thi} 0.1 48278 + +timestep 1.0e-3 +neighbor 1.0 bin +neigh_modify every 1 delay 10 check yes + +# equilibrate + +run 1000 + +# Eliminate COM motion +velocity all zero linear + +# only output atoms near vacancy + +compute coord all coord/atom cutoff $r + +#dump events all custom 1 dump.prd id type x y z +#dump_modify events thresh c_coord != 4 + +compute patom all pe/atom +compute pe all reduce sum c_patom +compute satom all stress/atom NULL +compute str all reduce sum c_satom[1] c_satom[2] c_satom[3] +variable press equal (c_str[1]+c_str[2]+c_str[3])/(3*vol) + +thermo_style custom step temp pe c_pe press v_press + +compute event all event/displace 1.0 + +unfix 1 +unfix 2 +fix 1 all nvt temp ${thi} ${thi} 0.1 + +# tad nsteps nevent tlo thi delta_conf tmax compute +# [min etol ftol niter neval] +# [neb etol_neb ftol_neb n1steps n2steps nevery] +# [neb_style min_style] +# [neb_log logfile] + +tad 2000 50 ${tlo} ${thi} 0.05 1.0 event & + min ${etol} ${ftol} ${maxiter} ${maxeval} & + neb 0.0 0.01 200 200 20 neb_style fire neb_log log.neb diff --git a/examples/SPIN/gneb_bfo/initial.hop1 b/examples/SPIN/gneb_bfo/initial.hop1 new file mode 100644 index 0000000000..228708c314 --- /dev/null +++ b/examples/SPIN/gneb_bfo/initial.hop1 @@ -0,0 +1,860 @@ +LAMMPS data file via write_data, version 27 Sep 2016, timestep = 0 + +420 atoms +3 atom types + +0.0000000000000000e+00 2.2653923264628304e+01 xlo xhi +-1.9618873042551413e-03 1.9620834929855668e+01 ylo yhi +-2.8317404080785380e-01 2.8317404080785380e-01 zlo zhi + +Masses + +1 1 +2 1 +3 1 + +Atoms # atomic + +1 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +2 1 5.6634808161570760e-01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +3 1 1.1326961632314152e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +4 1 1.6990442448471228e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +5 1 2.2653923264628304e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +6 1 2.8317404080785380e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +7 1 3.3980884896942456e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +8 1 3.9644365713099532e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +9 1 4.5307846529256608e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +10 1 5.0971327345413684e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +11 1 5.6634808161570760e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +12 1 6.2298288977727836e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +13 1 6.7961769793884912e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +14 1 7.3625250610041988e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +15 1 7.9288731426199064e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +16 1 8.4952212242356140e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +17 1 9.0615693058513216e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +18 1 9.6279173874670292e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +19 1 1.0194265469082737e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +20 1 1.0760613550698444e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +21 1 1.1326961632314152e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +22 1 1.1893309713929860e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +23 1 1.2459657795545567e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +24 1 1.3026005877161275e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +25 1 1.3592353958776982e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +26 1 1.4158702040392690e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +27 1 1.4725050122008398e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +28 1 1.5291398203624105e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +29 1 1.5857746285239813e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +30 1 1.6424094366855520e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +31 1 1.6990442448471228e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +32 1 1.7556790530086936e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +33 1 1.8123138611702643e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +34 1 1.8689486693318351e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +35 1 1.9255834774934058e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +36 1 1.9822182856549766e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +37 1 2.0388530938165474e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +38 1 2.0954879019781181e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +39 1 2.1521227101396889e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +40 1 2.2087575183012596e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 +41 1 0.0000000000000000e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +42 1 5.6634808161570760e-01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +43 1 1.1326961632314152e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +44 1 1.6990442448471228e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +45 1 2.2653923264628304e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +46 1 2.8317404080785380e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +47 1 3.3980884896942456e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +48 1 3.9644365713099532e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +49 1 4.5307846529256608e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +50 1 5.0971327345413684e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +51 1 5.6634808161570760e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +52 1 6.2298288977727836e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +53 1 6.7961769793884912e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +54 1 7.3625250610041988e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +55 1 7.9288731426199064e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +56 1 8.4952212242356140e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +57 1 9.0615693058513216e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +58 1 9.6279173874670292e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +59 1 1.0194265469082737e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +60 1 1.0760613550698444e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +61 1 1.1326961632314152e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +62 1 1.1893309713929860e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +63 1 1.2459657795545567e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +64 1 1.3026005877161275e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +65 1 1.3592353958776982e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +66 1 1.4158702040392690e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +67 1 1.4725050122008398e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +68 1 1.5291398203624105e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +69 1 1.5857746285239813e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +70 1 1.6424094366855520e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +71 1 1.6990442448471228e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +72 1 1.7556790530086936e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +73 1 1.8123138611702643e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +74 1 1.8689486693318351e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +75 1 1.9255834774934058e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +76 1 1.9822182856549766e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +77 1 2.0388530938165474e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +78 1 2.0954879019781181e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +79 1 2.1521227101396889e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 +80 1 2.2087575183012596e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 +81 1 0.0000000000000000e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +82 1 5.6634808161570760e-01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +83 1 1.1326961632314152e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +84 1 1.6990442448471228e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +85 1 2.2653923264628304e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +86 1 2.8317404080785380e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +87 1 3.3980884896942456e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +88 1 3.9644365713099532e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +89 1 4.5307846529256608e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +90 1 5.0971327345413684e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +91 1 5.6634808161570760e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +92 1 6.2298288977727836e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +93 1 6.7961769793884912e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +94 1 7.3625250610041988e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +95 1 7.9288731426199064e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +96 1 8.4952212242356140e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +97 1 9.0615693058513216e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +98 1 9.6279173874670292e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +99 1 1.0194265469082737e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +100 1 1.0760613550698444e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +101 1 1.1326961632314152e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +102 1 1.1893309713929860e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +103 1 1.2459657795545567e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +104 1 1.3026005877161275e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +105 1 1.3592353958776982e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +106 1 1.4158702040392690e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +107 1 1.4725050122008398e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +108 1 1.5291398203624105e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +109 1 1.5857746285239813e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +110 1 1.6424094366855520e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +111 1 1.6990442448471228e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +112 1 1.7556790530086936e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +113 1 1.8123138611702643e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +114 1 1.8689486693318351e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +115 1 1.9255834774934058e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +116 1 1.9822182856549766e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +117 1 2.0388530938165474e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +118 1 2.0954879019781181e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +119 1 2.1521227101396889e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 +120 1 2.2087575183012596e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 +121 1 0.0000000000000000e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +122 1 5.6634808161570760e-01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +123 1 1.1326961632314152e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +124 1 1.6990442448471228e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +125 1 2.2653923264628304e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +126 1 2.8317404080785380e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +127 1 3.3980884896942456e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +128 1 3.9644365713099532e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +129 1 4.5307846529256608e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +130 1 5.0971327345413684e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +131 1 5.6634808161570760e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +132 1 6.2298288977727836e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +133 1 6.7961769793884912e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +134 1 7.3625250610041988e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +135 1 7.9288731426199064e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +136 1 8.4952212242356140e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +137 1 9.0615693058513216e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +138 1 9.6279173874670292e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +139 1 1.0194265469082737e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +140 1 1.0760613550698444e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +141 1 1.1326961632314152e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +142 1 1.1893309713929860e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +143 1 1.2459657795545567e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +144 1 1.3026005877161275e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +145 1 1.3592353958776982e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +146 1 1.4158702040392690e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +147 1 1.4725050122008398e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +148 1 1.5291398203624105e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +149 1 1.5857746285239813e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +150 1 1.6424094366855520e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +151 1 1.6990442448471228e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +152 1 1.7556790530086936e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +153 1 1.8123138611702643e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +154 1 1.8689486693318351e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +155 1 1.9255834774934058e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +156 1 1.9822182856549766e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +157 1 2.0388530938165474e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +158 1 2.0954879019781181e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +159 1 2.1521227101396889e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 +160 1 2.2087575183012596e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 +161 1 0.0000000000000000e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +162 1 5.6634808161570760e-01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +163 1 1.1326961632314152e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +164 1 1.6990442448471228e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +165 1 2.2653923264628304e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +166 1 2.8317404080785380e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +167 1 3.3980884896942456e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +168 1 3.9644365713099532e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +169 1 4.5307846529256608e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +170 1 5.0971327345413684e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +171 1 5.6634808161570760e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +172 1 6.2298288977727836e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +173 1 6.7961769793884912e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +174 1 7.3625250610041988e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +175 1 7.9288731426199064e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +176 1 8.4952212242356140e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +177 1 9.0615693058513216e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +178 1 9.6279173874670292e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +179 1 1.0194265469082737e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +180 1 1.0760613550698444e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +181 1 1.1326961632314152e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +182 1 1.1893309713929860e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +183 1 1.2459657795545567e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +184 1 1.3026005877161275e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +185 1 1.3592353958776982e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +186 1 1.4158702040392690e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +187 1 1.4725050122008398e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +188 1 1.5291398203624105e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +189 1 1.5857746285239813e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +190 1 1.6424094366855520e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +191 1 1.6990442448471228e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +192 1 1.7556790530086936e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +193 1 1.8123138611702643e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +194 1 1.8689486693318351e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +195 1 1.9255834774934058e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +196 1 1.9822182856549766e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +197 1 2.0388530938165474e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +198 1 2.0954879019781181e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +199 1 2.1521227101396889e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 +200 1 2.2087575183012596e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 +201 1 0.0000000000000000e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +202 1 5.6634808161570760e-01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +203 1 1.1326961632314152e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +204 1 1.6990442448471228e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +205 1 2.2653923264628304e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +206 1 2.8317404080785380e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +207 1 3.3980884896942456e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +208 1 3.9644365713099532e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +209 1 4.5307846529256608e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +210 1 5.0971327345413684e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +211 1 5.6634808161570760e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +212 1 6.2298288977727836e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +213 1 6.7961769793884912e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +214 1 7.3625250610041988e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +215 1 7.9288731426199064e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +216 1 8.4952212242356140e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +217 1 9.0615693058513216e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +218 1 9.6279173874670292e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +219 1 1.0194265469082737e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +220 1 1.0760613550698444e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +221 1 1.1326961632314152e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +222 1 1.1893309713929860e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +223 1 1.2459657795545567e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +224 1 1.3026005877161275e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +225 1 1.3592353958776982e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +226 1 1.4158702040392690e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +227 1 1.4725050122008398e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +228 1 1.5291398203624105e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +229 1 1.5857746285239813e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +230 1 1.6424094366855520e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +231 1 1.6990442448471228e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +232 1 1.7556790530086936e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +233 1 1.8123138611702643e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +234 1 1.8689486693318351e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +235 1 1.9255834774934058e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +236 1 1.9822182856549766e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +237 1 2.0388530938165474e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +238 1 2.0954879019781181e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +239 1 2.1521227101396889e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 +240 1 2.2087575183012596e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 +241 1 0.0000000000000000e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +242 1 5.6634808161570760e-01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +243 1 1.1326961632314152e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +244 1 1.6990442448471228e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +245 1 2.2653923264628304e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +246 1 2.8317404080785380e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +247 1 3.3980884896942456e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +248 1 3.9644365713099532e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +249 1 4.5307846529256608e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +250 1 5.0971327345413684e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +251 1 5.6634808161570760e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +252 1 6.2298288977727836e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +253 1 6.7961769793884912e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +254 1 7.3625250610041988e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +255 1 7.9288731426199064e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +256 1 8.4952212242356140e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +257 1 9.0615693058513216e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +258 1 9.6279173874670292e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +259 1 1.0194265469082737e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +260 1 1.0760613550698444e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +261 1 1.1326961632314152e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +262 1 1.1893309713929860e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +263 1 1.2459657795545567e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +264 1 1.3026005877161275e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +265 1 1.3592353958776982e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +266 1 1.4158702040392690e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +267 1 1.4725050122008398e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +268 1 1.5291398203624105e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +269 1 1.5857746285239813e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +270 1 1.6424094366855520e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +271 1 1.6990442448471228e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +272 1 1.7556790530086936e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +273 1 1.8123138611702643e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +274 1 1.8689486693318351e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +275 1 1.9255834774934058e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +276 1 1.9822182856549766e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +277 1 2.0388530938165474e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +278 1 2.0954879019781181e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +279 1 2.1521227101396889e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 +280 1 2.2087575183012596e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 +281 1 0.0000000000000000e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +282 1 5.6634808161570760e-01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +283 1 1.1326961632314152e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +284 1 1.6990442448471228e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +285 1 2.2653923264628304e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +286 1 2.8317404080785380e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +287 1 3.3980884896942456e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +288 1 3.9644365713099532e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +289 1 4.5307846529256608e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +290 1 5.0971327345413684e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +291 1 5.6634808161570760e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +292 1 6.2298288977727836e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +293 1 6.7961769793884912e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +294 1 7.3625250610041988e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +295 1 7.9288731426199064e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +296 1 8.4952212242356140e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +297 1 9.0615693058513216e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +298 1 9.6279173874670292e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +299 1 1.0194265469082737e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +300 1 1.0760613550698444e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +301 1 1.1326961632314152e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +302 1 1.1893309713929860e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +303 1 1.2459657795545567e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +304 1 1.3026005877161275e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +305 1 1.3592353958776982e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +306 1 1.4158702040392690e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +307 1 1.4725050122008398e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +308 1 1.5291398203624105e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +309 1 1.5857746285239813e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +310 1 1.6424094366855520e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +311 1 1.6990442448471228e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +312 1 1.7556790530086936e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +313 1 1.8123138611702643e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +314 1 1.8689486693318351e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +315 1 1.9255834774934058e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +316 1 1.9822182856549766e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +317 1 2.0388530938165474e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +318 1 2.0954879019781181e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +319 1 2.1521227101396889e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 +320 1 2.2087575183012596e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 +321 1 0.0000000000000000e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +322 1 5.6634808161570760e-01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +323 1 1.1326961632314152e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +324 1 1.6990442448471228e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +325 1 2.2653923264628304e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +326 1 2.8317404080785380e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +327 1 3.3980884896942456e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +328 1 3.9644365713099532e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +329 1 4.5307846529256608e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +330 1 5.0971327345413684e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +331 1 5.6634808161570760e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +332 1 6.2298288977727836e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +333 1 6.7961769793884912e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +334 1 7.3625250610041988e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +335 1 7.9288731426199064e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +336 1 8.4952212242356140e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +337 1 9.0615693058513216e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +338 1 9.6279173874670292e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +339 1 1.0194265469082737e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +340 1 1.0760613550698444e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +341 1 1.1326961632314152e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +342 1 1.1893309713929860e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +343 1 1.2459657795545567e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +344 1 1.3026005877161275e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +345 1 1.3592353958776982e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +346 1 1.4158702040392690e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +347 1 1.4725050122008398e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +348 1 1.5291398203624105e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +349 1 1.5857746285239813e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +350 1 1.6424094366855520e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +351 1 1.6990442448471228e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +352 1 1.7556790530086936e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +353 1 1.8123138611702643e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +354 1 1.8689486693318351e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +355 1 1.9255834774934058e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +356 1 1.9822182856549766e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +357 1 2.0388530938165474e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +358 1 2.0954879019781181e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +359 1 2.1521227101396889e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 +360 1 2.2087575183012596e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 +361 1 0.0000000000000000e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +362 1 5.6634808161570760e-01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +363 1 1.1326961632314152e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +364 1 1.6990442448471228e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +365 1 2.2653923264628304e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +366 1 2.8317404080785380e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +367 1 3.3980884896942456e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +368 1 3.9644365713099532e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +369 1 4.5307846529256608e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +370 1 5.0971327345413684e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +371 1 5.6634808161570760e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +372 1 6.2298288977727836e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +373 1 6.7961769793884912e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +374 1 7.3625250610041988e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +375 1 7.9288731426199064e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +376 1 8.4952212242356140e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +377 1 9.0615693058513216e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +378 1 9.6279173874670292e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +379 1 1.0194265469082737e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +380 1 1.0760613550698444e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +381 1 1.1326961632314152e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +382 1 1.1893309713929860e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +383 1 1.2459657795545567e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +384 1 1.3026005877161275e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +385 1 1.3592353958776982e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +386 1 1.4158702040392690e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +387 1 1.4725050122008398e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +388 1 1.5291398203624105e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +389 1 1.5857746285239813e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +390 1 1.6424094366855520e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +391 1 1.6990442448471228e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +392 1 1.7556790530086936e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +393 1 1.8123138611702643e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +394 1 1.8689486693318351e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +395 1 1.9255834774934058e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +396 1 1.9822182856549766e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +397 1 2.0388530938165474e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +398 1 2.0954879019781181e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +399 1 2.1521227101396889e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 +400 1 2.2087575183012596e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 +401 1 0.0000000000000000e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +402 1 1.1326961632314152e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +403 1 2.2653923264628304e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +404 1 3.3980884896942456e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +405 1 4.5307846529256608e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +406 1 5.6634808161570760e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +407 1 6.7961769793884912e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +408 1 7.9288731426199064e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +409 1 9.0615693058513216e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +410 1 1.0194265469082737e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +411 1 1.1326961632314152e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +412 1 1.2459657795545567e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +413 1 1.3592353958776982e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +414 1 1.4725050122008398e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +415 1 1.5857746285239813e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +416 1 1.6990442448471228e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +417 1 1.8123138611702643e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +418 1 1.9255834774934058e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +419 1 2.0388530938165474e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 +420 1 2.1521227101396889e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 + +Velocities + +1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +33 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +34 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +35 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +36 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +37 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +38 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +39 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +40 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +41 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +42 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +43 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +44 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +45 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +46 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +47 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +48 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +49 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +50 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +51 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +52 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +53 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +54 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +55 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +56 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +57 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +58 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +59 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +60 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +61 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +62 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +63 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +64 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +65 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +66 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +67 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +68 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +69 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +70 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +71 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +72 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +73 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +74 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +75 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +76 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +77 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +78 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +79 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +80 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +81 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +82 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +83 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +84 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +85 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +86 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +87 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +88 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +89 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +90 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +91 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +92 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +93 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +94 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +95 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +96 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +97 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +98 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +99 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +100 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +101 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +102 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +103 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +104 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +105 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +106 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +107 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +108 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +109 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +110 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +111 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +112 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +113 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +114 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +115 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +116 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +117 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +118 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +119 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +120 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +121 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +122 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +123 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +124 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +125 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +126 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +127 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +128 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +129 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +130 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +131 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +132 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +133 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +134 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +135 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +136 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +137 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +138 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +139 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +140 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +141 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +142 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +143 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +144 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +145 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +146 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +147 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +148 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +149 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +150 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +151 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +152 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +153 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +154 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +155 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +156 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +157 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +158 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +159 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +160 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +161 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +162 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +163 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +164 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +165 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +166 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +167 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +168 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +169 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +170 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +171 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +172 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +173 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +174 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +175 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +176 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +177 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +178 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +179 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +180 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +181 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +182 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +183 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +184 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +185 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +186 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +187 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +188 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +189 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +190 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +191 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +192 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +193 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +194 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +195 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +196 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +197 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +198 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +199 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +200 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +201 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +202 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +203 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +204 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +205 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +206 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +207 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +208 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +209 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +210 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +211 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +212 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +213 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +214 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +215 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +216 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +217 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +218 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +219 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +220 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +221 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +222 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +223 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +224 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +225 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +226 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +227 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +228 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +229 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +230 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +231 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +232 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +233 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +234 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +235 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +236 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +237 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +238 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +239 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +240 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +241 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +242 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +243 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +244 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +245 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +246 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +247 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +248 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +249 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +250 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +251 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +252 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +253 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +254 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +255 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +256 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +257 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +258 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +259 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +260 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +261 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +262 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +263 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +264 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +265 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +266 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +267 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +268 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +269 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +270 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +271 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +272 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +273 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +274 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +275 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +276 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +277 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +278 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +279 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +280 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +281 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +282 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +283 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +284 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +285 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +286 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +287 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +288 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +289 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +290 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +291 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +292 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +293 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +294 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +295 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +296 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +297 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +298 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +299 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +300 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +301 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +302 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +303 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +304 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +305 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +306 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +307 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +308 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +309 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +310 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +311 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +312 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +313 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +314 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +315 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +316 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +317 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +318 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +319 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +320 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +321 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +322 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +323 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +324 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +325 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +326 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +327 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +328 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +329 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +330 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +331 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +332 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +333 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +334 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +335 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +336 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +337 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +338 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +339 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +340 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +341 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +342 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +343 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +344 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +345 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +346 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +347 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +348 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +349 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +350 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +351 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +352 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +353 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +354 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +355 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +356 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +357 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +358 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +359 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +360 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +361 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +362 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +363 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +364 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +365 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +366 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +367 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +368 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +369 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +370 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +371 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +372 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +373 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +374 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +375 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +376 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +377 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +378 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +379 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +380 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +381 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +382 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +383 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +384 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +385 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +386 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +387 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +388 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +389 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +390 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +391 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +392 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +393 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +394 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +395 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +396 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +397 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +398 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +399 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +400 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +401 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +402 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +403 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +404 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +405 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +406 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +407 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +408 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +409 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +410 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +411 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +412 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +413 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +414 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +415 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +416 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +417 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +418 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +419 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +420 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 diff --git a/examples/SPIN/gneb_bfo/initial.iron_spin b/examples/SPIN/gneb_bfo/initial.iron_spin new file mode 100644 index 0000000000..1d28afe400 --- /dev/null +++ b/examples/SPIN/gneb_bfo/initial.iron_spin @@ -0,0 +1,82 @@ +LAMMPS data file via write_data, version 4 Jan 2019, timestep = 0 + +32 atoms +1 atom types + +0.0000000000000000e+00 1.1465999999999999e+01 xlo xhi +0.0000000000000000e+00 1.1465999999999999e+01 ylo yhi +0.0000000000000000e+00 2.8664999999999998e+00 zlo zhi + +Masses + +1 55.845 + +Atoms # spin + +1 1 2.2000000000000002e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +2 1 2.2000000000000002e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +3 1 2.2000000000000002e+00 2.8664999999999998e+00 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +4 1 2.2000000000000002e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +5 1 2.2000000000000002e+00 5.7329999999999997e+00 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +6 1 2.2000000000000002e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +7 1 2.2000000000000002e+00 8.5994999999999990e+00 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +8 1 2.2000000000000002e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +9 1 2.2000000000000002e+00 0.0000000000000000e+00 2.8664999999999998e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +11 1 2.2000000000000002e+00 2.8664999999999998e+00 2.8664999999999998e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +13 1 2.2000000000000002e+00 5.7329999999999997e+00 2.8664999999999998e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +15 1 2.2000000000000002e+00 8.5994999999999990e+00 2.8664999999999998e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +10 1 2.2000000000000002e+00 1.4332499999999999e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +12 1 2.2000000000000002e+00 4.2997499999999995e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +14 1 2.2000000000000002e+00 7.1662499999999998e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +16 1 2.2000000000000002e+00 1.0032750000000000e+01 4.2997499999999995e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +17 1 2.2000000000000002e+00 0.0000000000000000e+00 5.7329999999999997e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +18 1 2.2000000000000002e+00 1.4332499999999999e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +19 1 2.2000000000000002e+00 2.8664999999999998e+00 5.7329999999999997e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +20 1 2.2000000000000002e+00 4.2997499999999995e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +21 1 2.2000000000000002e+00 5.7329999999999997e+00 5.7329999999999997e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +22 1 2.2000000000000002e+00 7.1662499999999998e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +23 1 2.2000000000000002e+00 8.5994999999999990e+00 5.7329999999999997e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +24 1 2.2000000000000002e+00 1.0032750000000000e+01 7.1662499999999998e+00 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +25 1 2.2000000000000002e+00 0.0000000000000000e+00 8.5994999999999990e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +27 1 2.2000000000000002e+00 2.8664999999999998e+00 8.5994999999999990e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +29 1 2.2000000000000002e+00 5.7329999999999997e+00 8.5994999999999990e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +31 1 2.2000000000000002e+00 8.5994999999999990e+00 8.5994999999999990e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +26 1 2.2000000000000002e+00 1.4332499999999999e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +28 1 2.2000000000000002e+00 4.2997499999999995e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +30 1 2.2000000000000002e+00 7.1662499999999998e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 +32 1 2.2000000000000002e+00 1.0032750000000000e+01 1.0032750000000000e+01 1.4332499999999999e+00 1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 + +Velocities + +1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp new file mode 100644 index 0000000000..a96af45267 --- /dev/null +++ b/src/REPLICA/fix_neb_spin.cpp @@ -0,0 +1,1226 @@ +/* ---------------------------------------------------------------------- + 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 for: Emile Maras (CEA, France) + new options for inter-replica forces, first/last replica treatment +------------------------------------------------------------------------- */ + +#include +#include +#include +#include +//#include "fix_neb.h" +#include "fix_neb_spin.h" +#include "universe.h" +#include "update.h" +#include "atom.h" +#include "domain.h" +#include "comm.h" +#include "modify.h" +#include "compute.h" +#include "group.h" +#include "memory.h" +#include "error.h" +#include "force.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + +enum{SINGLE_PROC_DIRECT,SINGLE_PROC_MAP,MULTI_PROC}; + +#define BUFSIZE 8 + +/* ---------------------------------------------------------------------- */ + +FixNEB_spin::FixNEB_spin(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), + id_pe(NULL), pe(NULL), nlenall(NULL), xprev(NULL), xnext(NULL), + fnext(NULL), + spprev(NULL), spnext(NULL), fmnext(NULL), + springF(NULL), tangent(NULL), + xsend(NULL), xrecv(NULL), fsend(NULL), frecv(NULL), + spsend(NULL), sprecv(NULL), fmsend(NULL), fmrecv(NULL), + tagsend(NULL), tagrecv(NULL), + xsendall(NULL), xrecvall(NULL), fsendall(NULL), frecvall(NULL), + spsendall(NULL), sprecvall(NULL), fmsendall(NULL), fmrecvall(NULL), + tagsendall(NULL), tagrecvall(NULL), counts(NULL), + displacements(NULL) +{ + + if (narg < 4) error->all(FLERR,"Illegal fix neb_spin command"); + + kspring = force->numeric(FLERR,arg[3]); + if (kspring <= 0.0) error->all(FLERR,"Illegal fix neb command"); + + // optional params + + NEBLongRange = false; // see if needed (comb. with pppm/spin?) + StandardNEB = true; // only option for now + PerpSpring = FreeEndIni = FreeEndFinal = false; + FreeEndFinalWithRespToEIni = FinalAndInterWithRespToEIni = false; + kspringPerp = 0.0; + kspringIni = 1.0; + kspringFinal = 1.0; + // only regular neb for now + SpinLattice = false; + + + + int iarg = 4; + while (iarg < narg) { + if (strcmp(arg[iarg],"lattice") == 0) + error->all(FLERR,"Illegal fix neb command"); + } + + /* + if (strcmp(arg[iarg],"parallel") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal fix neb command"); + if (strcmp(arg[iarg+1],"ideal") == 0) { + NEBLongRange = true; + StandardNEB = false; + } else if (strcmp(arg[iarg+1],"neigh") == 0) { + NEBLongRange = false; + StandardNEB = true; + } else error->all(FLERR,"Illegal fix neb command"); + iarg += 2; + + } else if (strcmp(arg[iarg],"perp") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal fix neb command"); + PerpSpring = true; + kspringPerp = force->numeric(FLERR,arg[iarg+1]); + if (kspringPerp == 0.0) PerpSpring = false; + if (kspringPerp < 0.0) error->all(FLERR,"Illegal fix neb command"); + iarg += 2; + + } else if (strcmp (arg[iarg],"end") == 0) { + if (iarg+3 > narg) error->all(FLERR,"Illegal fix neb command"); + if (strcmp(arg[iarg+1],"first") == 0) { + FreeEndIni = true; + kspringIni = force->numeric(FLERR,arg[iarg+2]); + } else if (strcmp(arg[iarg+1],"last") == 0) { + FreeEndFinal = true; + FinalAndInterWithRespToEIni = false; + FreeEndFinalWithRespToEIni = false; + kspringFinal = force->numeric(FLERR,arg[iarg+2]); + } else if (strcmp(arg[iarg+1],"last/efirst") == 0) { + FreeEndFinal = false; + FinalAndInterWithRespToEIni = false; + FreeEndFinalWithRespToEIni = true; + kspringFinal = force->numeric(FLERR,arg[iarg+2]); + } else if (strcmp(arg[iarg+1],"last/efirst/middle") == 0) { + FreeEndFinal = false; + FinalAndInterWithRespToEIni = true; + FreeEndFinalWithRespToEIni = true; + kspringFinal = force->numeric(FLERR,arg[iarg+2]); + } else error->all(FLERR,"Illegal fix neb command"); + + iarg += 3; + + } else error->all(FLERR,"Illegal fix neb command"); + } + */ + + // nreplica = number of partitions + // ireplica = which world I am in universe + // nprocs_universe = # of procs in all replicase + // procprev,procnext = root proc in adjacent replicas + + me = comm->me; + nprocs = comm->nprocs; + + nprocs_universe = universe->nprocs; + nreplica = universe->nworlds; + ireplica = universe->iworld; + + if (ireplica > 0) procprev = universe->root_proc[ireplica-1]; + else procprev = -1; + if (ireplica < nreplica-1) procnext = universe->root_proc[ireplica+1]; + else procnext = -1; + + uworld = universe->uworld; + int *iroots = new int[nreplica]; + MPI_Group uworldgroup,rootgroup; + if (NEBLongRange) { + for (int i=0; iroot_proc[i]; + MPI_Comm_group(uworld, &uworldgroup); + MPI_Group_incl(uworldgroup, nreplica, iroots, &rootgroup); + MPI_Comm_create(uworld, rootgroup, &rootworld); + } + delete [] iroots; + + // create a new compute pe style + // id = fix-ID + pe, compute group = all + + int n = strlen(id) + 4; + id_pe = new char[n]; + strcpy(id_pe,id); + strcat(id_pe,"_pe"); + + char **newarg = new char*[3]; + newarg[0] = id_pe; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "pe"; + modify->add_compute(3,newarg); + delete [] newarg; + + // might need a test + // => check if pe does not compute mech potentials + + + // initialize local storage + + maxlocal = -1; + ntotal = -1; +} + +/* ---------------------------------------------------------------------- */ + +FixNEB_spin::~FixNEB_spin() +{ + modify->delete_compute(id_pe); + delete [] id_pe; + + memory->destroy(xprev); + memory->destroy(xnext); + memory->destroy(tangent); + memory->destroy(fnext); + // spin quantities + memory->destroy(spprev); + memory->destroy(spnext); + memory->destroy(fmnext); + memory->destroy(springF); + memory->destroy(xsend); + memory->destroy(xrecv); + memory->destroy(fsend); + memory->destroy(frecv); + // spin quantities + memory->destroy(spsend); + memory->destroy(sprecv); + memory->destroy(fmsend); + memory->destroy(fmrecv); + memory->destroy(tagsend); + memory->destroy(tagrecv); + + memory->destroy(xsendall); + memory->destroy(xrecvall); + memory->destroy(fsendall); + memory->destroy(frecvall); + // spin quantities + memory->destroy(spsendall); + memory->destroy(sprecvall); + memory->destroy(fmsendall); + memory->destroy(fmrecvall); + memory->destroy(tagsendall); + memory->destroy(tagrecvall); + + memory->destroy(counts); + memory->destroy(displacements); + + if (NEBLongRange) { + if (rootworld != MPI_COMM_NULL) MPI_Comm_free(&rootworld); + memory->destroy(nlenall); + } +} + +/* ---------------------------------------------------------------------- */ + +int FixNEB_spin::setmask() +{ + int mask = 0; + mask |= MIN_POST_FORCE; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixNEB_spin::init() +{ + int icompute = modify->find_compute(id_pe); + if (icompute < 0) + 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() + + rclimber = -1; + + // nebatoms = # of atoms in fix group = atoms with inter-replica forces + + bigint count = group->count(igroup); + if (count > MAXSMALLINT) error->all(FLERR,"Too many active NEB atoms"); + nebatoms = count; + + // comm mode for inter-replica exchange of coords + + if (nreplica == nprocs_universe && + nebatoms == atom->natoms && atom->sortfreq == 0) + cmode = SINGLE_PROC_DIRECT; + else if (nreplica == nprocs_universe) cmode = SINGLE_PROC_MAP; + else cmode = MULTI_PROC; + + // ntotal = total # of atoms in system, NEB atoms or not + + if (atom->natoms > MAXSMALLINT) error->all(FLERR,"Too many atoms for NEB"); + ntotal = atom->natoms; + + if (atom->nmax > maxlocal) reallocate(); + + if (MULTI_PROC && counts == NULL) { + memory->create(xsendall,ntotal,3,"neb:xsendall"); + memory->create(xrecvall,ntotal,3,"neb:xrecvall"); + memory->create(fsendall,ntotal,3,"neb:fsendall"); + memory->create(frecvall,ntotal,3,"neb:frecvall"); + memory->create(tagsendall,ntotal,"neb:tagsendall"); + memory->create(tagrecvall,ntotal,"neb:tagrecvall"); + // spin quantities + memory->create(spsendall,ntotal,3,"neb:xsendall"); + memory->create(sprecvall,ntotal,3,"neb:xrecvall"); + memory->create(fmsendall,ntotal,3,"neb:fsendall"); + memory->create(fmrecvall,ntotal,3,"neb:frecvall"); + memory->create(counts,nprocs,"neb:counts"); + memory->create(displacements,nprocs,"neb:displacements"); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixNEB_spin::min_setup(int vflag) +{ + min_post_force(vflag); + + // trigger potential energy computation on next timestep + + pe->addstep(update->ntimestep+1); +} + +/* ---------------------------------------------------------------------- */ + +void FixNEB_spin::min_post_force(int /*vflag*/) +{ + double vprev,vnext; + //double delxp,delyp,delzp,delxn,delyn,delzn; + // spin quantities + double delspxp,delspyp,delspzp; + double delspxn,delspyn,delspzn; + double templen; + double vIni=0.0; + + // local spin values for geo. dist. calc. + double spi[3],spj[3]; + + vprev = vnext = veng = pe->compute_scalar(); + + if (ireplica < nreplica-1 && me == 0) + MPI_Send(&veng,1,MPI_DOUBLE,procnext,0,uworld); + if (ireplica > 0 && me == 0) + MPI_Recv(&vprev,1,MPI_DOUBLE,procprev,0,uworld,MPI_STATUS_IGNORE); + + if (ireplica > 0 && me == 0) + MPI_Send(&veng,1,MPI_DOUBLE,procprev,0,uworld); + if (ireplica < nreplica-1 && me == 0) + MPI_Recv(&vnext,1,MPI_DOUBLE,procnext,0,uworld,MPI_STATUS_IGNORE); + + if (cmode == MULTI_PROC) { + MPI_Bcast(&vprev,1,MPI_DOUBLE,0,world); + MPI_Bcast(&vnext,1,MPI_DOUBLE,0,world); + } + + if (FreeEndFinal && ireplica == nreplica-1 && (update->ntimestep == 0)) EFinalIni = veng; + + if (ireplica == 0) vIni=veng; + + if (FreeEndFinalWithRespToEIni) { + if (cmode == SINGLE_PROC_DIRECT || cmode == SINGLE_PROC_MAP) { + int procFirst; + procFirst=universe->root_proc[0]; + MPI_Bcast(&vIni,1,MPI_DOUBLE,procFirst,uworld); + } else { + if (me == 0) + MPI_Bcast(&vIni,1,MPI_DOUBLE,0,rootworld); + + MPI_Bcast(&vIni,1,MPI_DOUBLE,0,world); + } + } + + if (FreeEndIni && ireplica == 0 && (update->ntimestep == 0)) EIniIni = veng; + /* if (FreeEndIni && ireplica == 0) { + // if (me == 0 ) + if (update->ntimestep == 0) { + EIniIni = veng; + // if (cmode == MULTI_PROC) + // MPI_Bcast(&EIniIni,1,MPI_DOUBLE,0,world); + } + }*/ + + // communicate atoms to/from adjacent replicas to fill xprev,xnext + + inter_replica_comm(); + + // trigger potential energy computation on next timestep + + pe->addstep(update->ntimestep+1); + + double **x = atom->x; + // spin quantities + double **sp = atom->sp; + int *mask = atom->mask; + double dot = 0.0; + double prefactor = 0.0; + + double **f = atom->f; + // spin quantities + double **fm = atom->fm; + int nlocal = atom->nlocal; + + //calculating separation between images + + plen = 0.0; + nlen = 0.0; + double tlen = 0.0; + double gradnextlen = 0.0; + + dotgrad = gradlen = dotpath = dottangrad = 0.0; + + + // computation of the tangent vector + + // final replica + if (ireplica == nreplica-1) { + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + // tangent vector + delspxp = sp[i][0] - spprev[i][0]; + delspyp = sp[i][1] - spprev[i][1]; + delspzp = sp[i][2] - spprev[i][2]; + domain->minimum_image(delspxp,delspyp,delspzp); // check what it does + delsqp = delspxp*delspxp+delspyp*delspyp+delspzp*delspzp; + + // calc. geodesic length + spi[0]=sp[i][0]; + spi[1]=sp[i][1]; + spi[2]=sp[i][2]; + spj[0]=spprev[i][0]; + spj[1]=spprev[i][1]; + spj[2]=spprev[i][2]; + templen = geodesic_distance(spi, spj); + plen += templen*templen; + dottangrad += delxp*fm[i][0]+ delyp*fm[i][1]+delzp*fm[i][2]; + gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; + + //plen += delxp*delxp + delyp*delyp + delzp*delzp; + //dottangrad += delxp* f[i][0]+ delyp*f[i][1]+delzp*f[i][2]; + //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; + + // final replica, no need for the tangent vector + // (unless FreeEnd option) + if (FreeEndFinal||FreeEndFinalWithRespToEIni) { + error->all(FLERR,"Free End option not yet active"); + tangent[i][0]=delspxp; + tangent[i][1]=delspyp; + tangent[i][2]=delspzp; + // if needed, tlen has to be modified + tlen += tangent[i][0]*tangent[i][0] + + tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + dot += fm[i][0]*tangent[i][0] + fm[i][1]*tangent[i][1] + + fm[i][2]*tangent[i][2]; + } + + + //delxp = x[i][0] - xprev[i][0]; + //delyp = x[i][1] - xprev[i][1]; + //delzp = x[i][2] - xprev[i][2]; + //domain->minimum_image(delxp,delyp,delzp); + + //plen += delxp*delxp + delyp*delyp + delzp*delzp; + //dottangrad += delxp* f[i][0]+ delyp*f[i][1]+delzp*f[i][2]; + //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; + //if (FreeEndFinal||FreeEndFinalWithRespToEIni) { + // tangent[i][0]=delxp; + // tangent[i][1]=delyp; + // tangent[i][2]=delzp; + // tlen += tangent[i][0]*tangent[i][0] + + // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + // dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + + // f[i][2]*tangent[i][2]; + //} + } + + // initial replica + } else if (ireplica == 0) { + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + + // tangent vector + delspxn = spnext[i][0]- sp[i][0]; + delspyn = spnext[i][1]- sp[i][1]; + delspzn = spnext[i][2]- sp[i][2]; + domain->minimum_image(delspxn,delspyn,delspzn); // check what it does + delsqn = delspxn*delspxn+delspyn*delspyn+delspzn*delspzn; + + // calc. geodesic length + spi[0]=sp[i][0]; + spi[1]=sp[i][1]; + spi[2]=sp[i][2]; + spj[0]=spnext[i][0]; + spj[1]=spnext[i][1]; + spj[2]=spnext[i][2]; + templen = geodesic_distance(spi, spj); + nlen += templen*templen; + dottangrad += delspxn*fm[i][0] + delspyn*fm[i][1] + delspzp*fm[i][2]; + gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; + if (FreeEndIni) { + error->all(FLERR,"Free End option not yet active"); + tangent[i][0]=delxn; + tangent[i][1]=delyn; + tangent[i][2]=delzn; + // if needed, tlen has to be modified + tlen += tangent[i][0]*tangent[i][0] + + tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + + f[i][2]*tangent[i][2]; + } + + //delxn = xnext[i][0] - x[i][0]; + //delyn = xnext[i][1] - x[i][1]; + //delzn = xnext[i][2] - x[i][2]; + //domain->minimum_image(delxn,delyn,delzn); + //nlen += delxn*delxn + delyn*delyn + delzn*delzn; + //gradnextlen += fnext[i][0]*fnext[i][0] + // + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2]; + //dotgrad += f[i][0]*fnext[i][0] + // + f[i][1]*fnext[i][1] + f[i][2]*fnext[i][2]; + //dottangrad += delxn*f[i][0]+ delyn*f[i][1] + delzn*f[i][2]; + //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; + //if (FreeEndIni) { + // tangent[i][0]=delxn; + // tangent[i][1]=delyn; + // tangent[i][2]=delzn; + // tlen += tangent[i][0]*tangent[i][0] + + // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + // dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + + // f[i][2]*tangent[i][2]; + //} + } + + // in-between replica + } else { + + // not the first or last replica + + double vmax = MAX(fabs(vnext-veng),fabs(vprev-veng)); + double vmin = MIN(fabs(vnext-veng),fabs(vprev-veng)); + + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + delspxp = spx[i][0] - spxprev[i][0]; + delspyp = spx[i][1] - spxprev[i][1]; + delspzp = spx[i][2] - spxprev[i][2]; + domain->minimum_image(delspxp,delspyp,delspzp); + + // calc. geodesic length + spi[0]=sp[i][0]; + spi[1]=sp[i][1]; + spi[2]=sp[i][2]; + spj[0]=spprev[i][0]; + spj[1]=spprev[i][1]; + spj[2]=spprev[i][2]; + templen = geodesic_distance(spi, spj); + plen += templen*templen; + + delspxn = spxnext[i][0] - spx[i][0]; + delspyn = spxnext[i][1] - spx[i][1]; + delspzn = spxnext[i][2] - spx[i][2]; + domain->minimum_image(delspxn,delspyn,delspzn); + + if (vnext > veng && veng > vprev) { + tangent[i][0] = delspxn; + tangent[i][1] = delspyn; + tangent[i][2] = delspzn; + } else if (vnext < veng && veng < vprev) { + tangent[i][0] = delspxp; + tangent[i][1] = delspyp; + tangent[i][2] = delspzp; + } else { + if (vnext > vprev) { + tangent[i][0] = vmax*delspxn + vmin*delspxp; + tangent[i][1] = vmax*delspyn + vmin*delspyp; + tangent[i][2] = vmax*delspzn + vmin*delspzp; + } else if (vnext < vprev) { + tangent[i][0] = vmin*delspxn + vmax*delspxp; + tangent[i][1] = vmin*delspyn + vmax*delspyp; + tangent[i][2] = vmin*delspzn + vmax*delspzp; + } else { // vnext == vprev, e.g. for potentials that do not compute an energy + tangent[i][0] = delspxn + delspxp; + tangent[i][1] = delspyn + delspyp; + tangent[i][2] = delspzn + delspzp; + } + } + + // calc. geodesic length + spi[0]=sp[i][0]; + spi[1]=sp[i][1]; + spi[2]=sp[i][2]; + spj[0]=spnext[i][0]; + spj[1]=spnext[i][1]; + spj[2]=spnext[i][2]; + templen = geodesic_distance(spi, spj); + nlen += templen*templen; + //nlen += delxn*delxn + delyn*delyn + delzn*delzn; + tlen += tangent[i][0]*tangent[i][0] + + tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; + dotpath += delspxp*delspxn + delspyp*delspyn + delspzp*delspzn; + dottangrad += tangent[i][0]*fm[i][0] + + tangent[i][1]*fm[i][1] + tangent[i][2]*fm[i][2]; + gradnextlen += fnext[i][0]*fnext[i][0] + + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2]; + dotgrad += fm[i][0]*fnext[i][0] + fm[i][1]*fnext[i][1] + + fm[i][2]*fnext[i][2]; + + // is this a perpandicular spring force? + if (kspringPerp != 0.0) + error->all(FLERR,"Perpendicular nudging force not yet active"); + //springF[i][0] = kspringPerp*(delxn-delxp); + //springF[i][1] = kspringPerp*(delyn-delyp); + //springF[i][2] = kspringPerp*(delzn-delzp); + + //delxp = x[i][0] - xprev[i][0]; + //delyp = x[i][1] - xprev[i][1]; + //delzp = x[i][2] - xprev[i][2]; + //domain->minimum_image(delxp,delyp,delzp); + //plen += delxp*delxp + delyp*delyp + delzp*delzp; + + //delxn = xnext[i][0] - x[i][0]; + //delyn = xnext[i][1] - x[i][1]; + //delzn = xnext[i][2] - x[i][2]; + //domain->minimum_image(delxn,delyn,delzn); + + //if (vnext > veng && veng > vprev) { + // tangent[i][0] = delxn; + // tangent[i][1] = delyn; + // tangent[i][2] = delzn; + //} else if (vnext < veng && veng < vprev) { + // tangent[i][0] = delxp; + // tangent[i][1] = delyp; + // tangent[i][2] = delzp; + //} else { + // if (vnext > vprev) { + // tangent[i][0] = vmax*delxn + vmin*delxp; + // tangent[i][1] = vmax*delyn + vmin*delyp; + // tangent[i][2] = vmax*delzn + vmin*delzp; + // } else if (vnext < vprev) { + // tangent[i][0] = vmin*delxn + vmax*delxp; + // tangent[i][1] = vmin*delyn + vmax*delyp; + // tangent[i][2] = vmin*delzn + vmax*delzp; + // } else { // vnext == vprev, e.g. for potentials that do not compute an energy + // tangent[i][0] = delxn + delxp; + // tangent[i][1] = delyn + delyp; + // tangent[i][2] = delzn + delzp; + // } + //} + + //nlen += delxn*delxn + delyn*delyn + delzn*delzn; + //tlen += tangent[i][0]*tangent[i][0] + + // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; + //dotpath += delxp*delxn + delyp*delyn + delzp*delzn; + //dottangrad += tangent[i][0]*f[i][0] + + // tangent[i][1]*f[i][1] + tangent[i][2]*f[i][2]; + //gradnextlen += fnext[i][0]*fnext[i][0] + + // fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2]; + //dotgrad += f[i][0]*fnext[i][0] + f[i][1]*fnext[i][1] + + // f[i][2]*fnext[i][2]; + + //springF[i][0] = kspringPerp*(delxn-delxp); + //springF[i][1] = kspringPerp*(delyn-delyp); + //springF[i][2] = kspringPerp*(delzn-delzp); + } + } + + + // MPI reduce if more than one proc for world + + double bufin[BUFSIZE], bufout[BUFSIZE]; + bufin[0] = nlen; + bufin[1] = plen; + bufin[2] = tlen; + bufin[3] = gradlen; + bufin[4] = gradnextlen; + bufin[5] = dotpath; + bufin[6] = dottangrad; + bufin[7] = dotgrad; + MPI_Allreduce(bufin,bufout,BUFSIZE,MPI_DOUBLE,MPI_SUM,world); + nlen = sqrt(bufout[0]); + plen = sqrt(bufout[1]); + tlen = sqrt(bufout[2]); + gradlen = sqrt(bufout[3]); + gradnextlen = sqrt(bufout[4]); + dotpath = bufout[5]; + dottangrad = bufout[6]; + dotgrad = bufout[7]; + + // normalize tangent vector + + if (tlen > 0.0) { + double tleninv = 1.0/tlen; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + tangent[i][0] *= tleninv; + tangent[i][1] *= tleninv; + tangent[i][2] *= tleninv; + } + } + +//////////////////////////////////////////////////////// + + // first or last replica has no change to forces, just return + + if (ireplica > 0 && ireplica < nreplica-1) + dottangrad = dottangrad/(tlen*gradlen); + if (ireplica == 0) + dottangrad = dottangrad/(nlen*gradlen); + if (ireplica == nreplica-1) + dottangrad = dottangrad/(plen*gradlen); + if (ireplica < nreplica-1) + dotgrad = dotgrad /(gradlen*gradnextlen); + + if (FreeEndIni && ireplica == 0) { + if (tlen > 0.0) { + double dotall; + MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); + dot=dotall/tlen; + + if (dot<0) prefactor = -dot - kspringIni*(veng-EIniIni); + else prefactor = -dot + kspringIni*(veng-EIniIni); + + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + f[i][0] += prefactor *tangent[i][0]; + f[i][1] += prefactor *tangent[i][1]; + f[i][2] += prefactor *tangent[i][2]; + } + } + } + + if (FreeEndFinal && ireplica == nreplica -1) { + if (tlen > 0.0) { + double dotall; + MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); + dot=dotall/tlen; + + if (veng 0.0) { + double dotall; + MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); + dot=dotall/tlen; + if (veng0) { + for (int i = 0; i < rclimber; i++) + lenuntilClimber += nlenall[i]; + double meanDistBeforeClimber = lenuntilClimber/rclimber; + double meanDistAfterClimber = + (lentot-lenuntilClimber)/(nreplica-rclimber-1); + if (ireplicanmax > maxlocal) reallocate(); + + double **x = atom->x; + double **f = atom->f; + // spin quantities + double **sp = atom->sp; + double **fm = atom->fm; + tagint *tag = atom->tag; + int *mask = atom->mask; + int nlocal = atom->nlocal; + + // ----------------------------------------------------- + // 3 cases: two for single proc per replica + // one for multiple procs per replica + // ----------------------------------------------------- + + + // case 1 => to be done + + // single proc per replica + // all atoms are NEB atoms and no atom sorting + // direct comm of x -> xprev and x -> xnext + + if (cmode == SINGLE_PROC_DIRECT) { + if (ireplica > 0) + MPI_Irecv(xprev[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld,&request); + if (ireplica < nreplica-1) + MPI_Send(x[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld); + if (ireplica > 0) MPI_Wait(&request,MPI_STATUS_IGNORE); + if (ireplica < nreplica-1) + MPI_Irecv(xnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request); + if (ireplica > 0) + MPI_Send(x[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld); + if (ireplica < nreplica-1) MPI_Wait(&request,MPI_STATUS_IGNORE); + + if (ireplica < nreplica-1) + MPI_Irecv(fnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request); + if (ireplica > 0) + MPI_Send(f[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld); + if (ireplica < nreplica-1) MPI_Wait(&request,MPI_STATUS_IGNORE); + + return; + } + + // single proc per replica + // but only some atoms are NEB atoms or atom sorting is enabled + // send atom IDs and coords of only NEB atoms to prev/next proc + // recv procs use atom->map() to match received coords to owned atoms + + if (cmode == SINGLE_PROC_MAP) { + m = 0; + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + tagsend[m] = tag[i]; + xsend[m][0] = x[i][0]; + xsend[m][1] = x[i][1]; + xsend[m][2] = x[i][2]; + fsend[m][0] = f[i][0]; + fsend[m][1] = f[i][1]; + fsend[m][2] = f[i][2]; + // spin quantities + spsend[m][0] = sp[i][0]; + spsend[m][1] = sp[i][1]; + spsend[m][2] = sp[i][2]; + fmsend[m][0] = fm[i][0]; + fmsend[m][1] = fm[i][1]; + fmsend[m][2] = fm[i][2]; + m++; + } + + if (ireplica > 0) { + MPI_Irecv(xrecv[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); + // spin quantities + MPI_Irecv(sprecv[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); + MPI_Irecv(tagrecv,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld,&requests[1]); + } + if (ireplica < nreplica-1) { + MPI_Send(xsend[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); + // spin quantities + MPI_Send(spsend[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); + MPI_Send(tagsend,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld); + } + + if (ireplica > 0) { + MPI_Waitall(2,requests,statuses); + for (i = 0; i < nebatoms; i++) { + m = atom->map(tagrecv[i]); + xprev[m][0] = xrecv[i][0]; + xprev[m][1] = xrecv[i][1]; + xprev[m][2] = xrecv[i][2]; + // spin quantities + spprev[m][0] = sprecv[i][0]; + spprev[m][1] = sprecv[i][1]; + spprev[m][2] = sprecv[i][2]; + } + } + if (ireplica < nreplica-1) { + MPI_Irecv(xrecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + MPI_Irecv(frecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + // spin quantities + MPI_Irecv(sprecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + MPI_Irecv(fmrecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + MPI_Irecv(tagrecv,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld,&requests[1]); + } + if (ireplica > 0) { + MPI_Send(xsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(fsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + // spin quantities + MPI_Send(spsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(fmsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(tagsend,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld); + } + + if (ireplica < nreplica-1) { + MPI_Waitall(2,requests,statuses); + for (i = 0; i < nebatoms; i++) { + m = atom->map(tagrecv[i]); + xnext[m][0] = xrecv[i][0]; + xnext[m][1] = xrecv[i][1]; + xnext[m][2] = xrecv[i][2]; + fnext[m][0] = frecv[i][0]; + fnext[m][1] = frecv[i][1]; + fnext[m][2] = frecv[i][2]; + // spin quantities + spnext[m][0] = sprecv[i][0]; + spnext[m][1] = sprecv[i][1]; + spnext[m][2] = sprecv[i][2]; + fmnext[m][0] = fmrecv[i][0]; + fmnext[m][1] = fmrecv[i][1]; + fmnext[m][2] = fmrecv[i][2]; + } + } + + return; + } + + // multiple procs per replica + // MPI_Gather all coords and atom IDs to root proc of each replica + // send to root of adjacent replicas + // bcast within each replica + // each proc extracts info for atoms it owns via atom->map() + + m = 0; + for (i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + tagsend[m] = tag[i]; + xsend[m][0] = x[i][0]; + xsend[m][1] = x[i][1]; + xsend[m][2] = x[i][2]; + fsend[m][0] = f[i][0]; + fsend[m][1] = f[i][1]; + fsend[m][2] = f[i][2]; + // spin quantities + spsend[m][0] = sp[i][0]; + spsend[m][1] = sp[i][1]; + spsend[m][2] = sp[i][2]; + fmsend[m][0] = fm[i][0]; + fmsend[m][1] = fm[i][1]; + fmsend[m][2] = fm[i][2]; + m++; + } + + MPI_Gather(&m,1,MPI_INT,counts,1,MPI_INT,0,world); + displacements[0] = 0; + for (i = 0; i < nprocs-1; i++) + displacements[i+1] = displacements[i] + counts[i]; + MPI_Gatherv(tagsend,m,MPI_LMP_TAGINT, + tagsendall,counts,displacements,MPI_LMP_TAGINT,0,world); + for (i = 0; i < nprocs; i++) counts[i] *= 3; + for (i = 0; i < nprocs-1; i++) + displacements[i+1] = displacements[i] + counts[i]; + if (xsend) { + MPI_Gatherv(xsend[0],3*m,MPI_DOUBLE, + xsendall[0],counts,displacements,MPI_DOUBLE,0,world); + MPI_Gatherv(fsend[0],3*m,MPI_DOUBLE, + fsendall[0],counts,displacements,MPI_DOUBLE,0,world); + } else { + MPI_Gatherv(NULL,3*m,MPI_DOUBLE, + xsendall[0],counts,displacements,MPI_DOUBLE,0,world); + MPI_Gatherv(NULL,3*m,MPI_DOUBLE, + fsendall[0],counts,displacements,MPI_DOUBLE,0,world); + } + // spin quantities + if (spsend) { + MPI_Gatherv(spsend[0],3*m,MPI_DOUBLE, + spsendall[0],counts,displacements,MPI_DOUBLE,0,world); + MPI_Gatherv(fmsend[0],3*m,MPI_DOUBLE, + fmsendall[0],counts,displacements,MPI_DOUBLE,0,world); + } else { + MPI_Gatherv(NULL,3*m,MPI_DOUBLE, + xsendall[0],counts,displacements,MPI_DOUBLE,0,world); + MPI_Gatherv(NULL,3*m,MPI_DOUBLE, + fmsendall[0],counts,displacements,MPI_DOUBLE,0,world); + } + + if (ireplica > 0 && me == 0) { + MPI_Irecv(xrecvall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); + // spin quantities + MPI_Irecv(sprecvall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); + MPI_Irecv(tagrecvall,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld, + &requests[1]); + } + if (ireplica < nreplica-1 && me == 0) { + MPI_Send(xsendall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); + // spin quantities + MPI_Send(spsendall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); + MPI_Send(tagsendall,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld); + } + + if (ireplica > 0) { + if (me == 0) MPI_Waitall(2,requests,statuses); + + MPI_Bcast(tagrecvall,nebatoms,MPI_INT,0,world); + MPI_Bcast(xrecvall[0],3*nebatoms,MPI_DOUBLE,0,world); + // spin quantities + MPI_Bcast(sprecvall[0],3*nebatoms,MPI_DOUBLE,0,world); + + for (i = 0; i < nebatoms; i++) { + m = atom->map(tagrecvall[i]); + if (m < 0 || m >= nlocal) continue; + xprev[m][0] = xrecvall[i][0]; + xprev[m][1] = xrecvall[i][1]; + xprev[m][2] = xrecvall[i][2]; + // spin quantities + spprev[m][0] = sprecvall[i][0]; + spprev[m][1] = sprecvall[i][1]; + spprev[m][2] = sprecvall[i][2]; + } + } + + if (ireplica < nreplica-1 && me == 0) { + MPI_Irecv(xrecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + MPI_Irecv(frecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + // spin quantities + MPI_Irecv(sprecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + MPI_Irecv(sprecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); + MPI_Irecv(tagrecvall,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld, + &requests[1]); + } + if (ireplica > 0 && me == 0) { + MPI_Send(xsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(fsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + // spin quantities + MPI_Send(spsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(fmsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(tagsendall,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld); + } + + if (ireplica < nreplica-1) { + if (me == 0) MPI_Waitall(2,requests,statuses); + + MPI_Bcast(tagrecvall,nebatoms,MPI_INT,0,world); + MPI_Bcast(xrecvall[0],3*nebatoms,MPI_DOUBLE,0,world); + MPI_Bcast(frecvall[0],3*nebatoms,MPI_DOUBLE,0,world); + // spin quantities + MPI_Bcast(sprecvall[0],3*nebatoms,MPI_DOUBLE,0,world); + MPI_Bcast(fmrecvall[0],3*nebatoms,MPI_DOUBLE,0,world); + + for (i = 0; i < nebatoms; i++) { + m = atom->map(tagrecvall[i]); + if (m < 0 || m >= nlocal) continue; + xnext[m][0] = xrecvall[i][0]; + xnext[m][1] = xrecvall[i][1]; + xnext[m][2] = xrecvall[i][2]; + fnext[m][0] = frecvall[i][0]; + fnext[m][1] = frecvall[i][1]; + fnext[m][2] = frecvall[i][2]; + // spin quantities + spnext[m][0] = sprecvall[i][0]; + spnext[m][1] = sprecvall[i][1]; + spnext[m][2] = sprecvall[i][2]; + fmnext[m][0] = fmrecvall[i][0]; + fmnext[m][1] = fmrecvall[i][1]; + fmnext[m][2] = fmrecvall[i][2]; + } + } +} + +/* ---------------------------------------------------------------------- + reallocate xprev,xnext,tangent arrays if necessary + reallocate communication arrays if necessary +------------------------------------------------------------------------- */ + +void FixNEB_spin::reallocate() +{ + maxlocal = atom->nmax; + + memory->destroy(xprev); + memory->destroy(xnext); + memory->destroy(tangent); + memory->destroy(fnext); + memory->destroy(springF); + // spin quantities + memory->destroy(spprev); + memory->destroy(spnext); + memory->destroy(fmnext); + + memory->create(xprev,maxlocal,3,"neb:xprev"); + memory->create(xnext,maxlocal,3,"neb:xnext"); + memory->create(tangent,maxlocal,3,"neb:tangent"); + memory->create(fnext,maxlocal,3,"neb:fnext"); + memory->create(springF,maxlocal,3,"neb:springF"); + // spin quantities + memory->create(spprev,maxlocal,3,"neb:xprev"); + memory->create(spnext,maxlocal,3,"neb:xnext"); + memory->create(fmnext,maxlocal,3,"neb:fnext"); + + if (cmode != SINGLE_PROC_DIRECT) { + memory->destroy(xsend); + memory->destroy(fsend); + memory->destroy(xrecv); + memory->destroy(frecv); + // spin quantities + memory->destroy(spsend); + memory->destroy(fmsend); + memory->destroy(sprecv); + memory->destroy(fmrecv); + memory->destroy(tagsend); + memory->destroy(tagrecv); + memory->create(xsend,maxlocal,3,"neb:xsend"); + memory->create(fsend,maxlocal,3,"neb:fsend"); + memory->create(xrecv,maxlocal,3,"neb:xrecv"); + memory->create(frecv,maxlocal,3,"neb:frecv"); + // spin quantities + memory->create(spsend,maxlocal,3,"neb:xsend"); + memory->create(fmsend,maxlocal,3,"neb:fsend"); + memory->create(sprecv,maxlocal,3,"neb:xrecv"); + memory->create(fmrecv,maxlocal,3,"neb:frecv"); + memory->create(tagsend,maxlocal,"neb:tagsend"); + memory->create(tagrecv,maxlocal,"neb:tagrecv"); + } + + if (NEBLongRange) { + memory->destroy(nlenall); + memory->create(nlenall,nreplica,"neb:nlenall"); + } +} diff --git a/src/REPLICA/fix_neb_spin.h b/src/REPLICA/fix_neb_spin.h new file mode 100644 index 0000000000..e3bdd6889d --- /dev/null +++ b/src/REPLICA/fix_neb_spin.h @@ -0,0 +1,115 @@ +/* -*- 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 FIX_CLASS + +FixStyle(neb,FixNEB) +FixStyle(neb_spin,FixNEB_spin) + +#else + +#ifndef LMP_FIX_NEB_SPIN_H +#define LMP_FIX_NEB_SPIN_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixNEB_spin : public Fix { + public: + double veng,plen,nlen,dotpath,dottangrad,gradlen,dotgrad; + int rclimber; + + FixNEB_spin(class LAMMPS *, int, char **); + ~FixNEB_spin(); + int setmask(); + void init(); + void min_setup(int); + void min_post_force(int); + + private: + int me,nprocs,nprocs_universe; + double kspring,kspringIni,kspringFinal,kspringPerp,EIniIni,EFinalIni; + bool StandardNEB,NEBLongRange,PerpSpring,FreeEndIni,FreeEndFinal; + bool FreeEndFinalWithRespToEIni,FinalAndInterWithRespToEIni; + bool SpinLattice; + int ireplica,nreplica; + int procnext,procprev; + int cmode; + MPI_Comm uworld; + MPI_Comm rootworld; + + + char *id_pe; + class Compute *pe; + + int nebatoms; + int ntotal; // total # of atoms, NEB or not + int maxlocal; // size of xprev,xnext,tangent arrays + double *nlenall; + double **xprev,**xnext,**fnext; + // spin quantities + double **spprev,**spnext,**fmnext; + double **springF; + double **tangent; + double **xsend,**xrecv; // coords to send/recv to/from other replica + double **fsend,**frecv; // coords to send/recv to/from other replica + // spin quantities + double **spsend,**sprecv; // sp to send/recv to/from other replica + double **fmsend,**fmrecv; // fm to send/recv to/from other replica + tagint *tagsend,*tagrecv; // ditto for atom IDs + + // info gathered from all procs in my replica + double **xsendall,**xrecvall; // coords to send/recv to/from other replica + double **fsendall,**frecvall; // force to send/recv to/from other replica + // spin quantities + double **spsendall,**sprecvall; // sp to send/recv to/from other replica + double **fmsendall,**fmrecvall; // fm to send/recv to/from other replica + tagint *tagsendall,*tagrecvall; // ditto for atom IDs + + int *counts,*displacements; // used for MPI_Gather + + void inter_replica_comm(); + void reallocate(); +}; + +} + +#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. + +E: Potential energy ID for fix neb does not exist + +Self-explanatory. + +E: Too many active NEB atoms + +UNDOCUMENTED + +E: Too many atoms for NEB + +UNDOCUMENTED + +U: Atom count changed in fix neb + +This is not allowed in a NEB calculation. + +*/ diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp new file mode 100644 index 0000000000..7860553532 --- /dev/null +++ b/src/REPLICA/neb_spin.cpp @@ -0,0 +1,722 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +// lmptype.h must be first b/c this file uses MAXBIGINT and includes mpi.h +// due to OpenMPI bug which sets INT64_MAX via its mpi.h +// before lmptype.h can set flags to insure it is done correctly + +#include "lmptype.h" +#include +#include +#include +#include +//#include "neb.h" +#include "neb_spin.h" +#include "universe.h" +#include "atom.h" +#include "update.h" +#include "domain.h" +#include "comm.h" +#include "min.h" +#include "modify.h" +#include "fix.h" +#include "fix_neb.h" +#include "output.h" +#include "thermo.h" +#include "finish.h" +#include "timer.h" +#include "memory.h" +#include "error.h" +#include "force.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define MAXLINE 256 +#define CHUNK 1024 +//#define ATTRIBUTE_PERLINE 4 +// 8 attributes: tag number, coords, spin norm, spin dir. +#define ATTRIBUTE_PERLINE 8 + +/* ---------------------------------------------------------------------- */ + +NEB_spin::NEB_spin(LAMMPS *lmp) : Pointers(lmp) {} + +/* ---------------------------------------------------------------------- + internal NEB_spin constructor, called from TAD +------------------------------------------------------------------------- */ + +NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, + int n2steps_in, int nevery_in, double *buf_init, double *buf_final) + : Pointers(lmp) +{ + double delx,dely,delz; + + etol = etol_in; + ftol = ftol_in; + n1steps = n1steps_in; + n2steps = n2steps_in; + nevery = nevery_in; + + // replica info + + nreplica = universe->nworlds; + ireplica = universe->iworld; + me_universe = universe->me; + uworld = universe->uworld; + MPI_Comm_rank(world,&me); + + // generate linear interpolate replica + + double fraction = ireplica/(nreplica-1.0); + + double **x = atom->x; + double **sp = atom->sp; + int nlocal = atom->nlocal; + + // modif interp. + int ii = 0; + for (int i = 0; i < nlocal; i++) { + delx = buf_final[ii] - buf_init[ii]; + dely = buf_final[ii+1] - buf_init[ii+1]; + delz = buf_final[ii+2] - buf_init[ii+2]; + domain->minimum_image(delx,dely,delz); + x[i][0] = buf_init[ii] + fraction*delx; + x[i][1] = buf_init[ii+1] + fraction*dely; + x[i][2] = buf_init[ii+2] + fraction*delz; + ii += 3; + } +} + +/* ---------------------------------------------------------------------- */ + +NEB_spin::~NEB_spin() +{ + MPI_Comm_free(&roots); + memory->destroy(all); + delete [] rdist; +} + +/* ---------------------------------------------------------------------- + perform NEB_spin on multiple replicas +------------------------------------------------------------------------- */ + +void NEB_spin::command(int narg, char **arg) +{ + if (domain->box_exist == 0) + error->all(FLERR,"NEB_spin command before simulation box is defined"); + + if (narg < 6) error->universe_all(FLERR,"Illegal NEB_spin command"); + + etol = force->numeric(FLERR,arg[0]); + ftol = force->numeric(FLERR,arg[1]); + n1steps = force->inumeric(FLERR,arg[2]); + n2steps = force->inumeric(FLERR,arg[3]); + nevery = force->inumeric(FLERR,arg[4]); + + // error checks + + if (etol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); + if (ftol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); + if (nevery <= 0) error->universe_all(FLERR,"Illegal NEB_spin command"); + if (n1steps % nevery || n2steps % nevery) + error->universe_all(FLERR,"Illegal NEB_spin command"); + + // replica info + + nreplica = universe->nworlds; + ireplica = universe->iworld; + me_universe = universe->me; + uworld = universe->uworld; + MPI_Comm_rank(world,&me); + + // error checks + + if (nreplica == 1) error->all(FLERR,"Cannot use NEB_spin with a single replica"); + if (atom->map_style == 0) + error->all(FLERR,"Cannot use NEB_spin unless atom map exists"); + + // process file-style setting to setup initial configs for all replicas + + if (strcmp(arg[5],"final") == 0) { + if (narg != 7 && narg !=8) error->universe_all(FLERR,"Illegal NEB_spin command"); + infile = arg[6]; + readfile(infile,0); + } else if (strcmp(arg[5],"each") == 0) { + if (narg != 7 && narg !=8) error->universe_all(FLERR,"Illegal NEB_spin command"); + infile = arg[6]; + readfile(infile,1); + } else if (strcmp(arg[5],"none") == 0) { + if (narg != 6 && narg !=7) error->universe_all(FLERR,"Illegal NEB_spin command"); + } else error->universe_all(FLERR,"Illegal NEB_spin command"); + + verbose=false; + if (strcmp(arg[narg-1],"verbose") == 0) verbose=true; + // run the NEB_spin calculation + + run(); +} + +/* ---------------------------------------------------------------------- + run NEB_spin on multiple replicas +------------------------------------------------------------------------- */ + +void NEB_spin::run() +{ + // create MPI communicator for root proc from each world + + int color; + if (me == 0) color = 0; + else color = 1; + MPI_Comm_split(uworld,color,0,&roots); + + int ineb; + for (ineb = 0; ineb < modify->nfix; ineb++) + if (strcmp(modify->fix[ineb]->style,"neb_spin") == 0) break; + if (ineb == modify->nfix) error->all(FLERR,"NEB_spin requires use of fix neb_spin"); + //int ineb; + //for (ineb = 0; ineb < modify->nfix; ineb++) + // if (strcmp(modify->fix[ineb]->style,"neb") == 0) break; + //if (ineb == modify->nfix) error->all(FLERR,"NEB_spin requires use of fix neb"); + + //fneb = (FixNEB_spin *) modify->fix[ineb]; + fneb_spin = (FixNEB_spin *) modify->fix[ineb]; + if (verbose) numall =7; + else numall = 4; + memory->create(all,nreplica,numall,"neb:all"); + rdist = new double[nreplica]; + + // initialize LAMMPS + + update->whichflag = 2; + update->etol = etol; + update->ftol = ftol; + update->multireplica = 1; + + lmp->init(); + + if (update->minimize->searchflag) + error->all(FLERR,"NEB_spin requires damped dynamics minimizer"); + + // setup regular NEB_spin minimization + FILE *uscreen = universe->uscreen; + FILE *ulogfile = universe->ulogfile; + + if (me_universe == 0 && uscreen) + fprintf(uscreen,"Setting up regular NEB_spin ...\n"); + + update->beginstep = update->firststep = update->ntimestep; + update->endstep = update->laststep = update->firststep + n1steps; + update->nsteps = n1steps; + update->max_eval = n1steps; + if (update->laststep < 0) + error->all(FLERR,"Too many timesteps for NEB_spin"); + + update->minimize->setup(); + + if (me_universe == 0) { + if (uscreen) { + if (verbose) { + fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " + "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " + "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " + "... ReplicaForceN MaxAtomForceN\n"); + } else { + fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " + "RDN PEN\n"); + } + } + + if (ulogfile) { + if (verbose) { + fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " + "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " + "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " + "... ReplicaForceN MaxAtomForceN\n"); + } else { + fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " + "RDN PEN\n"); + } + } + } + print_status(); + + // perform regular NEB_spin for n1steps or until replicas converge + // retrieve PE values from fix NEB_spin and print every nevery iterations + // break out of while loop early if converged + // damped dynamic min styles insure all replicas converge together + + timer->init(); + timer->barrier_start(); + + while (update->minimize->niter < n1steps) { + update->minimize->run(nevery); + print_status(); + if (update->minimize->stop_condition) break; + } + + timer->barrier_stop(); + + update->minimize->cleanup(); + + Finish finish(lmp); + finish.end(1); + + // switch fix NEB_spin to climbing mode + // top = replica that becomes hill climber + + double vmax = all[0][0]; + int top = 0; + for (int m = 1; m < nreplica; m++) + if (vmax < all[m][0]) { + vmax = all[m][0]; + top = m; + } + + // setup climbing NEB_spin minimization + // must reinitialize minimizer so it re-creates its fix MINIMIZE + + if (me_universe == 0 && uscreen) + fprintf(uscreen,"Setting up climbing ...\n"); + + if (me_universe == 0) { + if (uscreen) + fprintf(uscreen,"Climbing replica = %d\n",top+1); + if (ulogfile) + fprintf(ulogfile,"Climbing replica = %d\n",top+1); + } + + update->beginstep = update->firststep = update->ntimestep; + update->endstep = update->laststep = update->firststep + n2steps; + update->nsteps = n2steps; + update->max_eval = n2steps; + if (update->laststep < 0) + error->all(FLERR,"Too many timesteps"); + + update->minimize->init(); + //fneb->rclimber = top; + fneb_spin->rclimber = top; + update->minimize->setup(); + + if (me_universe == 0) { + if (uscreen) { + if (verbose) { + fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc EBF EBR RDT " + "RD1 PE1 RD2 PE2 ... RDN PEN " + "pathangle1 angletangrad1 anglegrad1 gradV1 " + "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " + "... ReplicaForceN MaxAtomForceN\n"); + } else { + fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc " + "EBF EBR RDT " + "RD1 PE1 RD2 PE2 ... RDN PEN\n"); + } + } + if (ulogfile) { + if (verbose) { + fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc EBF EBR RDT " + "RD1 PE1 RD2 PE2 ... RDN PEN " + "pathangle1 angletangrad1 anglegrad1 gradV1 " + "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " + "... ReplicaForceN MaxAtomForceN\n"); + } else { + fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + "GradV0 GradV1 GradVc " + "EBF EBR RDT " + "RD1 PE1 RD2 PE2 ... RDN PEN\n"); + } + } + } + print_status(); + + // perform climbing NEB_spin for n2steps or until replicas converge + // retrieve PE values from fix NEB_spin and print every nevery iterations + // break induced if converged + // damped dynamic min styles insure all replicas converge together + + timer->init(); + timer->barrier_start(); + + while (update->minimize->niter < n2steps) { + update->minimize->run(nevery); + print_status(); + if (update->minimize->stop_condition) break; + } + + timer->barrier_stop(); + + update->minimize->cleanup(); + + finish.end(1); + + update->whichflag = 0; + update->multireplica = 0; + update->firststep = update->laststep = 0; + update->beginstep = update->endstep = 0; +} + +/* ---------------------------------------------------------------------- + read initial config atom coords from file + flag = 0 + only first replica opens file and reads it + first replica bcasts lines to all replicas + final replica stores coords + intermediate replicas interpolate from coords + new coord = replica fraction between current and final state + initial replica does nothing + flag = 1 + each replica (except first) opens file and reads it + each replica stores coords + initial replica does nothing +------------------------------------------------------------------------- */ + +void NEB_spin::readfile(char *file, int flag) +{ + int i,j,m,nchunk,eofflag,nlines; + tagint tag; + char *eof,*start,*next,*buf; + char line[MAXLINE]; + double xx,yy,zz,delx,dely,delz; + // creating new temp. sp + double spx,spy,spz,delspx,delspy,delspz; + + if (me_universe == 0 && screen) + fprintf(screen,"Reading NEB_spin coordinate file(s) ...\n"); + + // flag = 0, universe root reads header of file, bcast to universe + // flag = 1, each replica's root reads header of file, bcast to world + // but explicitly skip first replica + + if (flag == 0) { + if (me_universe == 0) { + open(file); + while (1) { + eof = fgets(line,MAXLINE,fp); + if (eof == NULL) error->one(FLERR,"Unexpected end of neb file"); + start = &line[strspn(line," \t\n\v\f\r")]; + if (*start != '\0' && *start != '#') break; + } + sscanf(line,"%d",&nlines); + } + MPI_Bcast(&nlines,1,MPI_INT,0,uworld); + + } else { + if (me == 0) { + if (ireplica) { + open(file); + while (1) { + eof = fgets(line,MAXLINE,fp); + if (eof == NULL) error->one(FLERR,"Unexpected end of neb file"); + start = &line[strspn(line," \t\n\v\f\r")]; + if (*start != '\0' && *start != '#') break; + } + sscanf(line,"%d",&nlines); + } else nlines = 0; + } + MPI_Bcast(&nlines,1,MPI_INT,0,world); + } + + char *buffer = new char[CHUNK*MAXLINE]; + char **values = new char*[ATTRIBUTE_PERLINE]; + + double fraction = ireplica/(nreplica-1.0); + + double **x = atom->x; + // spin table + double **sp = atom->sp; + int nlocal = atom->nlocal; + + // loop over chunks of lines read from file + // two versions of read_lines_from_file() for world vs universe bcast + // count # of atom coords changed so can check for invalid atom IDs in file + + int ncount = 0; + + int nread = 0; + while (nread < nlines) { + nchunk = MIN(nlines-nread,CHUNK); + if (flag == 0) + eofflag = comm->read_lines_from_file_universe(fp,nchunk,MAXLINE,buffer); + else + eofflag = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer); + if (eofflag) error->all(FLERR,"Unexpected end of neb file"); + + buf = buffer; + next = strchr(buf,'\n'); + *next = '\0'; + int nwords = atom->count_words(buf); + *next = '\n'; + + if (nwords != ATTRIBUTE_PERLINE) + error->all(FLERR,"Incorrect atom format in neb file"); + + // loop over lines of atom coords + // tokenize the line into values + + for (i = 0; i < nchunk; i++) { + next = strchr(buf,'\n'); + + values[0] = strtok(buf," \t\n\r\f"); + for (j = 1; j < nwords; j++) + values[j] = strtok(NULL," \t\n\r\f"); + + // adjust atom coord based on replica fraction + // for flag = 0, interpolate for intermediate and final replicas + // for flag = 1, replace existing coord with new coord + // ignore image flags of final x + // for interpolation: + // new x is displacement from old x via minimum image convention + // if final x is across periodic boundary: + // new x may be outside box + // will be remapped back into box when simulation starts + // its image flags will then be adjusted + + tag = ATOTAGINT(values[0]); + m = atom->map(tag); + if (m >= 0 && m < nlocal) { + ncount++; + xx = atof(values[1]); + yy = atof(values[2]); + zz = atof(values[3]); + + if (flag == 0) { + delx = xx - x[m][0]; + dely = yy - x[m][1]; + delz = zz - x[m][2]; + domain->minimum_image(delx,dely,delz); + x[m][0] += fraction*delx; + x[m][1] += fraction*dely; + x[m][2] += fraction*delz; + } else { + x[m][0] = xx; + x[m][1] = yy; + x[m][2] = zz; + } + } + + buf = next + 1; + } + + nread += nchunk; + } + + // check that all atom IDs in file were found by a proc + + if (flag == 0) { + int ntotal; + MPI_Allreduce(&ncount,&ntotal,1,MPI_INT,MPI_SUM,uworld); + if (ntotal != nreplica*nlines) + error->universe_all(FLERR,"Invalid atom IDs in neb file"); + } else { + int ntotal; + MPI_Allreduce(&ncount,&ntotal,1,MPI_INT,MPI_SUM,world); + if (ntotal != nlines) + error->all(FLERR,"Invalid atom IDs in neb file"); + } + + // clean up + + delete [] buffer; + delete [] values; + + if (flag == 0) { + if (me_universe == 0) { + if (compressed) pclose(fp); + else fclose(fp); + } + } else { + if (me == 0 && ireplica) { + if (compressed) pclose(fp); + else fclose(fp); + } + } +} + +/* ---------------------------------------------------------------------- + universe proc 0 opens NEB_spin data file + test if gzipped +------------------------------------------------------------------------- */ + +void NEB_spin::open(char *file) +{ + compressed = 0; + char *suffix = file + strlen(file) - 3; + if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1; + if (!compressed) fp = fopen(file,"r"); + else { +#ifdef LAMMPS_GZIP + char gunzip[128]; + snprintf(gunzip,128,"gzip -c -d %s",file); + +#ifdef _WIN32 + fp = _popen(gunzip,"rb"); +#else + fp = popen(gunzip,"r"); +#endif + +#else + error->one(FLERR,"Cannot open gzipped file"); +#endif + } + + if (fp == NULL) { + char str[128]; + snprintf(str,128,"Cannot open file %s",file); + error->one(FLERR,str); + } +} + +/* ---------------------------------------------------------------------- + query fix NEB_spin for info on each replica + universe proc 0 prints current NEB_spin status +------------------------------------------------------------------------- */ + +void NEB_spin::print_status() +{ + double fnorm2 = sqrt(update->minimize->fnorm_sqr()); + double fmaxreplica; + MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); + double fnorminf = update->minimize->fnorm_inf(); + double fmaxatom; + MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots); + + if (verbose) { + freplica = new double[nreplica]; + MPI_Allgather(&fnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots); + fmaxatomInRepl = new double[nreplica]; + MPI_Allgather(&fnorminf,1,MPI_DOUBLE,&fmaxatomInRepl[0],1,MPI_DOUBLE,roots); + } + + double one[7]; + //one[0] = fneb->veng; + //one[1] = fneb->plen; + //one[2] = fneb->nlen; + //one[3] = fneb->gradlen; + one[0] = fneb_neb->veng; + one[1] = fneb_neb->plen; + one[2] = fneb_neb->nlen; + one[3] = fneb_neb->gradlen; + + if (verbose) { + //one[4] = fneb->dotpath; + //one[5] = fneb->dottangrad; + //one[6] = fneb->dotgrad; + one[4] = fneb_spin->dotpath; + one[5] = fneb_spin->dottangrad; + one[6] = fneb_spin->dotgrad; + } + + if (output->thermo->normflag) one[0] /= atom->natoms; + if (me == 0) + MPI_Allgather(one,numall,MPI_DOUBLE,&all[0][0],numall,MPI_DOUBLE,roots); + MPI_Bcast(&all[0][0],numall*nreplica,MPI_DOUBLE,0,world); + + rdist[0] = 0.0; + for (int i = 1; i < nreplica; i++) + rdist[i] = rdist[i-1] + all[i][1]; + double endpt = rdist[nreplica-1] = rdist[nreplica-2] + all[nreplica-2][2]; + for (int i = 1; i < nreplica; i++) + rdist[i] /= endpt; + + // look up GradV for the initial, final, and climbing replicas + // these are identical to fnorm2, but to be safe we + // take them straight from fix_neb + + double gradvnorm0, gradvnorm1, gradvnormc; + + int irep; + irep = 0; + gradvnorm0 = all[irep][3]; + irep = nreplica-1; + gradvnorm1 = all[irep][3]; + irep = fneb->rclimber; + if (irep > -1) { + gradvnormc = all[irep][3]; + ebf = all[irep][0]-all[0][0]; + ebr = all[irep][0]-all[nreplica-1][0]; + } else { + double vmax = all[0][0]; + int top = 0; + for (int m = 1; m < nreplica; m++) + if (vmax < all[m][0]) { + vmax = all[m][0]; + top = m; + } + irep = top; + gradvnormc = all[irep][3]; + ebf = all[irep][0]-all[0][0]; + ebr = all[irep][0]-all[nreplica-1][0]; + } + + if (me_universe == 0) { + const double todeg=180.0/MY_PI; + FILE *uscreen = universe->uscreen; + FILE *ulogfile = universe->ulogfile; + if (uscreen) { + fprintf(uscreen,BIGINT_FORMAT " %12.8g %12.8g ", + update->ntimestep,fmaxreplica,fmaxatom); + fprintf(uscreen,"%12.8g %12.8g %12.8g ", + gradvnorm0,gradvnorm1,gradvnormc); + fprintf(uscreen,"%12.8g %12.8g %12.8g ",ebf,ebr,endpt); + for (int i = 0; i < nreplica; i++) + fprintf(uscreen,"%12.8g %12.8g ",rdist[i],all[i][0]); + if (verbose) { + fprintf(uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g", + NAN,180-acos(all[0][5])*todeg,180-acos(all[0][6])*todeg, + all[0][3],freplica[0],fmaxatomInRepl[0]); + for (int i = 1; i < nreplica-1; i++) + fprintf(uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g", + 180-acos(all[i][4])*todeg,180-acos(all[i][5])*todeg, + 180-acos(all[i][6])*todeg,all[i][3],freplica[i], + fmaxatomInRepl[i]); + fprintf(uscreen,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g", + NAN,180-acos(all[nreplica-1][5])*todeg,NAN,all[nreplica-1][3], + freplica[nreplica-1],fmaxatomInRepl[nreplica-1]); + } + fprintf(uscreen,"\n"); + } + + if (ulogfile) { + fprintf(ulogfile,BIGINT_FORMAT " %12.8g %12.8g ", + update->ntimestep,fmaxreplica,fmaxatom); + fprintf(ulogfile,"%12.8g %12.8g %12.8g ", + gradvnorm0,gradvnorm1,gradvnormc); + fprintf(ulogfile,"%12.8g %12.8g %12.8g ",ebf,ebr,endpt); + for (int i = 0; i < nreplica; i++) + fprintf(ulogfile,"%12.8g %12.8g ",rdist[i],all[i][0]); + if (verbose) { + fprintf(ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g", + NAN,180-acos(all[0][5])*todeg,180-acos(all[0][6])*todeg, + all[0][3],freplica[0],fmaxatomInRepl[0]); + for (int i = 1; i < nreplica-1; i++) + fprintf(ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g", + 180-acos(all[i][4])*todeg,180-acos(all[i][5])*todeg, + 180-acos(all[i][6])*todeg,all[i][3],freplica[i], + fmaxatomInRepl[i]); + fprintf(ulogfile,"%12.5g %12.5g %12.5g %12.5g %12.5g %12.5g", + NAN,180-acos(all[nreplica-1][5])*todeg,NAN,all[nreplica-1][3], + freplica[nreplica-1],fmaxatomInRepl[nreplica-1]); + } + fprintf(ulogfile,"\n"); + fflush(ulogfile); + } + } +} diff --git a/src/REPLICA/neb_spin.h b/src/REPLICA/neb_spin.h new file mode 100644 index 0000000000..3fa19460fc --- /dev/null +++ b/src/REPLICA/neb_spin.h @@ -0,0 +1,137 @@ +/* -*- 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 COMMAND_CLASS + +CommandStyle(neb_spin,NEB_SPIN) + +#else + +#ifndef LMP_NEB_SPIN_H +#define LMP_NEB_SPIN_H + +#include +#include "pointers.h" + +namespace LAMMPS_NS { + +class NEB_spin : protected Pointers { + public: + NEB_spin(class LAMMPS *); + NEB_spin(class LAMMPS *, double, double, int, int, int, double *, double *); + ~NEB_spin(); + void command(int, char **); // process neb command + void run(); // run NEB_spin + + double ebf,ebr; // forward and reverse energy barriers + + private: + int me,me_universe; // my proc ID in world and universe + int ireplica,nreplica; + bool verbose; + MPI_Comm uworld; + MPI_Comm roots; // MPI comm with 1 root proc from each world + FILE *fp; + int compressed; + double etol; // energy tolerance convergence criterion + double ftol; // force tolerance convergence criterion + int n1steps, n2steps; // number of steps in stage 1 and 2 + int nevery; // output interval + char *infile; // name of file containing final state + + class FixNEB_spin *fneb; + int numall; // per-replica dimension of array all + double **all; // PE,plen,nlen,gradvnorm from each replica + double *rdist; // normalize reaction distance, 0 to 1 + double *freplica; // force on an image + double *fmaxatomInRepl; // force on an image + + void readfile(char *, int); + void open(char *); + void print_status(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: NEB_spin command before simulation box is defined + +Self-explanatory. + +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. + +E: Cannot use NEB_spin with a single replica + +Self-explanatory. + +E: Cannot use NEB_spin unless atom map exists + +Use the atom_modify command to create an atom map. + +E: NEB_spin requires use of fix neb + +Self-explanatory. + +E: NEB_spin requires damped dynamics minimizer + +Use a different minimization style. + +E: Too many timesteps for NEB_spin + +You must use a number of timesteps that fit in a 32-bit integer +for NEB_spin. + +E: Too many timesteps + +The cumulative timesteps must fit in a 64-bit integer. + +E: Unexpected end of neb file + +A read operation from the file failed. + +E: Incorrect atom format in neb file + +The number of fields per line is not what expected. + +E: Invalid atom IDs in neb file + +An ID in the file was not found in the system. + +E: Cannot open gzipped file + +LAMMPS was compiled without support for reading and writing gzipped +files through a pipeline to the gzip program with -DLAMMPS_GZIP. + +E: Cannot open file %s + +The specified file cannot be opened. Check that the path and name are +correct. If the file is a compressed file, also check that the gzip +executable can be found and run. + +U: Can only use NEB_spin with 1-processor replicas + +This is current restriction for NEB_spin as implemented in LAMMPS. + +U: Cannot use NEB_spin with atom_modify sort enabled + +This is current restriction for NEB_spin implemented in LAMMPS. + +*/ -- GitLab From e195d6faee7346034d234b620bae670c52a11425 Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Wed, 30 Jan 2019 08:37:04 -0700 Subject: [PATCH 0094/1243] Fixed issue with not setting i-j, j-i coefficients correctly --- src/GRANULAR/pair_granular.cpp | 28 ++++++++++---------- src/GRANULAR/pair_granular_multi.cpp | 38 ++++++++++++++-------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index c2f202ac9c..82a470f83b 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -1571,22 +1571,22 @@ void PairGranular::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - normal_coeffs[i][j][0] = normal_coeffs_local[0]; - normal_coeffs[i][j][1] = damp; + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_local[0]; + normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][j][3] = normal_coeffs_local[3]; + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_local[3]; for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; + tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_local[k]; if (roll != ROLL_NONE) for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs_local[k]; + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_local[k]; if (twist != TWIST_NONE && twist != TWIST_MARSHALL) for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs_local[k]; + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_local[k]; setflag[i][j] = 1; count++; @@ -1746,31 +1746,31 @@ double PairGranular::init_one(int i, int j) if (setflag[i][j] == 0) { if (normal != HOOKE && normal != HERTZ){ - normal_coeffs[i][j][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - normal_coeffs[i][j][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][j][2] = normal_coeffs[j][i][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], normal_coeffs[i][i][2], normal_coeffs[j][j][2]); } else{ - normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); } - normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); + normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); + tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); if (roll != ROLL_NONE){ for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } if (twist != TWIST_NONE && twist != TWIST_MARSHALL){ for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } } diff --git a/src/GRANULAR/pair_granular_multi.cpp b/src/GRANULAR/pair_granular_multi.cpp index 09b8ea9709..07a6cab3dd 100644 --- a/src/GRANULAR/pair_granular_multi.cpp +++ b/src/GRANULAR/pair_granular_multi.cpp @@ -841,28 +841,28 @@ void PairGranularMulti::coeff(int narg, char **arg) for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - normal[i][j] = normal_local; - normal_coeffs[i][j][0] = normal_coeffs_local[0]; - normal_coeffs[i][j][1] = damp; + normal[i][j] = normal[j][i] = normal_local; + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_local[0]; + normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; if ((normal_local == JKR) || (normal_local == DMT)) - normal_coeffs[i][j][3] = normal_coeffs_local[3]; + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_local[3]; - damping[i][j] = damping_local; + damping[i][j] = damping[j][i] = damping_local; - tangential[i][j] = tangential_local; + tangential[i][j] = tangential[j][i] = tangential_local; for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs_local[k]; + tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_local[k]; - roll[i][j] = roll_local; + roll[i][j] = roll[j][i] = roll_local; if (roll_local != ROLL_NONE) for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs_local[k]; + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_local[k]; - twist[i][j] = twist_local; + twist[i][j] = twist[j][i] = twist_local; if (twist_local != TWIST_NONE && twist_local != TWIST_MARSHALL) for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs_local[k]; + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_local[k]; setflag[i][j] = 1; count++; @@ -1033,31 +1033,31 @@ double PairGranularMulti::init_one(int i, int j) } if (normal[i][j] != HOOKE && normal[i][j] != HERTZ){ - normal_coeffs[i][j][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - normal_coeffs[i][j][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][j][2] = normal_coeffs[j][i][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], normal_coeffs[i][i][2], normal_coeffs[j][j][2]); } else{ - normal_coeffs[i][j][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); } - normal_coeffs[i][j][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); + normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) - normal_coeffs[i][j][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); + tangential_coeffs[i][j][k] = normal_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); if (roll[i][i] != ROLL_NONE){ for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } if (twist[i][i] != TWIST_NONE && twist[i][i] != TWIST_MARSHALL){ for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } } -- GitLab From 682b456aae90f9e4a1867e460a7c71ea55de2491 Mon Sep 17 00:00:00 2001 From: casievers Date: Fri, 1 Feb 2019 16:18:17 -0800 Subject: [PATCH 0095/1243] Optimized (but not working) Dynamical Matrix command) --- src/USER-PHONON/Install.sh | 4 + src/USER-PHONON/dynamical_matrix.cpp | 489 +++++++++++++++++++++++++ src/USER-PHONON/dynamical_matrix.h | 72 ++++ src/USER-PHONON/third_order.cpp | 529 +++++++++++++++++++++++++++ src/USER-PHONON/third_order.h | 71 ++++ 5 files changed, 1165 insertions(+) create mode 100644 src/USER-PHONON/dynamical_matrix.cpp create mode 100644 src/USER-PHONON/dynamical_matrix.h create mode 100644 src/USER-PHONON/third_order.cpp create mode 100644 src/USER-PHONON/third_order.h diff --git a/src/USER-PHONON/Install.sh b/src/USER-PHONON/Install.sh index 3428415443..a73f529cfa 100755 --- a/src/USER-PHONON/Install.sh +++ b/src/USER-PHONON/Install.sh @@ -40,3 +40,7 @@ fi action fix_phonon.cpp fft3d_wrap.h action fix_phonon.h fft3d_wrap.h +action dynamical_matrix.cpp +action dynamical_matrix.h +action third_order.cpp +action third_order.h diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp new file mode 100644 index 0000000000..d1b53eee01 --- /dev/null +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -0,0 +1,489 @@ +// +// Created by charlie sievers on 6/21/18. +// + +#include +#include +#include "dynamical_matrix.h" +#include "atom.h" +#include "modify.h" +#include "domain.h" +#include "comm.h" +#include "group.h" +#include "force.h" +#include "math_extra.h" +#include "memory.h" +#include "bond.h" +#include "angle.h" +#include "dihedral.h" +#include "improper.h" +#include "kspace.h" +#include "update.h" +#include "neighbor.h" +#include "pair.h" +#include "timer.h" +#include "finish.h" + + +using namespace LAMMPS_NS; +enum{REGULAR,ESKM}; + +/* ---------------------------------------------------------------------- */ + +DynamicalMatrix::DynamicalMatrix(LAMMPS *lmp) : Pointers(lmp), fp(NULL) +{ + external_force_clear = 1; +} + +/* ---------------------------------------------------------------------- */ + +DynamicalMatrix::~DynamicalMatrix() +{ + if (fp && me == 0) fclose(fp); + memory->destroy(dynmat); + memory->destroy(final_dynmat); + fp = NULL; +} + +/* ---------------------------------------------------------------------- + setup without output or one-time post-init setup + flag = 0 = just force calculation + flag = 1 = reneighbor and force calculation +------------------------------------------------------------------------- */ + +void DynamicalMatrix::setup() +{ + // setup domain, communication and neighboring + // acquire ghosts + // build neighbor lists + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + comm->exchange(); + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + domain->image_check(); + domain->box_too_small_check(); + neighbor->build(1); + neighbor->ncalls = 0; + neighbor->every = 2; // build every this many steps + neighbor->delay = 1; + neighbor->ago = 0; + neighbor->ndanger = 0; + + // compute all forces + force_clear(); + external_force_clear = 0; + + eflag=0; + vflag=0; + if (pair_compute_flag) force->pair->compute(eflag,vflag); + else if (force->pair) force->pair->compute_dummy(eflag,vflag); + + if (atom->molecular) { + if (force->bond) force->bond->compute(eflag,vflag); + if (force->angle) force->angle->compute(eflag,vflag); + if (force->dihedral) force->dihedral->compute(eflag,vflag); + if (force->improper) force->improper->compute(eflag,vflag); + } + + if (force->kspace) { + force->kspace->setup(); + if (kspace_compute_flag) force->kspace->compute(eflag,vflag); + else force->kspace->compute_dummy(eflag,vflag); + } + + //modify->setup_pre_reverse(eflag,vflag); + if (force->newton) comm->reverse_comm(); +} + +/* ---------------------------------------------------------------------- */ + +void DynamicalMatrix::command(int narg, char **arg) +{ + MPI_Comm_rank(world,&me); + + if (domain->box_exist == 0) + error->all(FLERR,"Dynamical_matrix command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal dynamical_matrix command"); + + lmp->init(); + + // orthogonal vs triclinic simulation box + + triclinic = domain->triclinic; + + if (force->pair && force->pair->compute_flag) pair_compute_flag = 1; + else pair_compute_flag = 0; + if (force->kspace && force->kspace->compute_flag) kspace_compute_flag = 1; + else kspace_compute_flag = 0; + + // group and style + + igroup = group->find(arg[0]); + if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); + groupbit = group->bitmask[igroup]; + dynlen = (group->count(igroup))*3; + memory->create(dynmat,int(dynlen),int(dynlen),"dynamic_matrix:dynmat"); + update->setupflag = 1; + + int style = -1; + if (strcmp(arg[1],"regular") == 0) style = REGULAR; + else if (strcmp(arg[1],"eskm") == 0) style = ESKM; + else error->all(FLERR,"Illegal Dynamical Matrix command"); + del = force->numeric(FLERR, arg[2]); + + // set option defaults + + binaryflag = 0; + scaleflag = 0; + compressed = 0; + file_flag = 0; + file_opened = 0; + conversion = 1; + + // read options from end of input line + if (style == REGULAR) options(narg-3,&arg[3]); //COME BACK + else if (style == ESKM) options(narg-3,&arg[3]); //COME BACK + else if (comm->me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); + + // move atoms by 3-vector or specified variable(s) + + if (style == REGULAR) { + setup(); + calculateMatrix(); + if (me ==0) writeMatrix(); + } + + if (style == ESKM) { + setup(); + convert_units(update->unit_style); + conversion = conv_energy/conv_distance/conv_mass; + calculateMatrix(); + if (me ==0) writeMatrix(); + } + + Finish finish(lmp); + finish.end(1); +} + +/* ---------------------------------------------------------------------- + parse optional parameters +------------------------------------------------------------------------- */ + +void DynamicalMatrix::options(int narg, char **arg) +{ + if (narg < 0) error->all(FLERR,"Illegal dynamical_matrix command"); + int iarg = 0; + const char* filename = "dynmat.dyn"; + while (iarg < narg) { + if (strcmp(arg[iarg],"binary") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); + if (strcmp(arg[iarg+1],"gzip") == 0) { + compressed = 1; + } + else if (strcmp(arg[iarg+1],"yes") == 0) { + binaryflag = 1; + } + iarg += 2; + } + else if (strcmp(arg[iarg],"file") == 0) { + if (iarg+2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); + filename = arg[iarg + 1]; + file_flag = 1; + iarg += 2; + } else error->all(FLERR,"Illegal dynamical_matrix command"); + } + if (file_flag == 1) { + openfile(filename); + } +} + +/* ---------------------------------------------------------------------- + generic opening of a file + ASCII or binary or gzipped + some derived classes override this function +------------------------------------------------------------------------- */ + +void DynamicalMatrix::openfile(const char* filename) +{ + // if file already opened, return + if (me!=0) return; + if (file_opened) return; + + if (compressed) { +#ifdef LAMMPS_GZIP + char gzip[128]; + sprintf(gzip,"gzip -6 > %s",filename); +#ifdef _WIN32 + fp = _popen(gzip,"wb"); +#else + fp = popen(gzip,"w"); +#endif +#else + error->one(FLERR,"Cannot open gzipped file"); +#endif + } else if (binaryflag) { + fp = fopen(filename,"wb"); + } else { + fp = fopen(filename,"w"); + } + + if (fp == NULL) error->one(FLERR,"Cannot open dump file"); + + file_opened = 1; +} + +/* ---------------------------------------------------------------------- + create dynamical matrix +------------------------------------------------------------------------- */ + +void DynamicalMatrix::calculateMatrix() +{ + int local_idx; // local index + int local_jdx; // second local index + int natoms = atom->natoms; + int *mask = atom->mask; + int *type = atom->type; + double imass; // dynamical matrix element + double *m = atom->mass; + double **f = atom->f; + + //initialize dynmat to all zeros + for (int i=0; i < dynlen; i++) + for (int j=0; j < dynlen; j++) + dynmat[i][j] = 0.; + + energy_force(0); + + if (comm->me == 0 && screen) fprintf(screen,"Calculating Dynamical Matrix...\n"); + + for (int i=1; i<=natoms; i++){ + local_idx = atom->map(i); + if (local_idx >= 0){ + for (int alpha=0; alpha<3; alpha++){ + displace_atom(local_idx, alpha, 1); + energy_force(0); + for (int j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + if (local_jdx >= 0){ + for (int beta=0; beta<3; beta++){ + dynmat[(i-1)*3+alpha][(j-1)*3+beta] += -f[j-1][beta]; + } + } + } + displace_atom(local_idx,alpha,-2); + energy_force(0); + for (int j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + if (local_jdx >= 0){ + for (int beta=0; beta<3; beta++){ + if (atom->rmass_flag == 1) + imass = sqrt(m[i] * m[j]); + else + imass = sqrt(m[type[i]] * m[type[j]]); + //dynmat has length dynlen + //dynlen = (group->count(igroup))*3; + //currently dynmat is being called to natoms*3 + //Also with this implementation + //I am not recovering the correct dynamical matrix + //if I have more than 1 core + dynmat[(i-1)*3+alpha][(j-1)*3+beta] -= -f[j-1][beta]; + dynmat[(i-1)*3+alpha][(j-1)*3+beta] /= (2 * del * imass); + dynmat[(i-1)*3+alpha][(j-1)*3+beta] *= conversion; + } + } + } + displace_atom(local_idx,alpha,1); + } + } + } + + + memory->create(final_dynmat,int(dynlen),int(dynlen),"dynamic_matrix_buffer:buf"); + for (int i = 0; i < dynlen; i++) + MPI_Reduce(dynmat[i], final_dynmat[i], int(dynlen), MPI_DOUBLE, MPI_SUM, 0, world); + + if (screen && me ==0 ) fprintf(screen,"Finished Calculating Dynamical Matrix\n"); +} + +/* ---------------------------------------------------------------------- + write dynamical matrix +------------------------------------------------------------------------- */ + +void DynamicalMatrix::writeMatrix() +{ + // print file comment lines + if (!binaryflag && fp) { + clearerr(fp); + for (int i = 0; i < dynlen; i++) { + for (int j = 0; j < dynlen; j++) { + if ((j+1)%3==0) fprintf(fp, "%4.8f\n", final_dynmat[j][i]); + else fprintf(fp, "%4.8f ",final_dynmat[j][i]); + } + } + } + if (ferror(fp)) + error->one(FLERR,"Error writing to file"); + + if (binaryflag && fp) { + clearerr(fp); + fwrite(&final_dynmat[0], sizeof(double), dynlen * dynlen, fp); + if (ferror(fp)) + error->one(FLERR, "Error writing to binary file"); + } +} + +/* ---------------------------------------------------------------------- + Displace atoms + ---------------------------------------------------------------------- */ + +void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) +{ + double **x = atom->x; + int *sametag = atom->sametag; + int j = local_idx; + + x[local_idx][direction] += del*magnitude; + + while (sametag[j] >= 0){ + j = sametag[j]; + x[j][direction] += del*magnitude; + } +} + + +/* ---------------------------------------------------------------------- + evaluate potential energy and forces + may migrate atoms due to reneighboring + return new energy, which should include nextra_global dof + return negative gradient stored in atom->f + return negative gradient for nextra_global dof in fextra +------------------------------------------------------------------------- */ + +void DynamicalMatrix::energy_force(int resetflag) +{ + // check for reneighboring + // always communicate since atoms move + int nflag = neighbor->check_distance(); + + if (nflag == 0) { + //if (comm->me == 0 && screen) fprintf(screen,"b\n"); + timer->stamp(); + comm->forward_comm(); + timer->stamp(Timer::COMM); + //if (comm->me == 0 && screen) fprintf(screen,"c\n"); + } else { + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + if (domain->box_change) { + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + } + timer->stamp(); + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + timer->stamp(Timer::COMM); + neighbor->build(1); + timer->stamp(Timer::NEIGH); + } + force_clear(); + + if (pair_compute_flag) { + force->pair->compute(eflag,vflag); + timer->stamp(Timer::PAIR); + } + if (atom->molecular) { + if (force->bond) force->bond->compute(eflag,vflag); + if (force->angle) force->angle->compute(eflag,vflag); + if (force->dihedral) force->dihedral->compute(eflag,vflag); + if (force->improper) force->improper->compute(eflag,vflag); + timer->stamp(Timer::BOND); + } + if (kspace_compute_flag) { + force->kspace->compute(eflag,vflag); + timer->stamp(Timer::KSPACE); + } + if (force->newton) { + comm->reverse_comm(); + timer->stamp(Timer::COMM); + } +} + +/* ---------------------------------------------------------------------- + clear force on own & ghost atoms + clear other arrays as needed +------------------------------------------------------------------------- */ + +void DynamicalMatrix::force_clear() +{ + if (external_force_clear) return; + + // clear global force array + // if either newton flag is set, also include ghosts + + size_t nbytes = sizeof(double) * atom->nlocal; + if (force->newton) nbytes += sizeof(double) * atom->nghost; + + if (nbytes) { + memset(&atom->f[0][0],0,3*nbytes); + } +} + +/* ---------------------------------------------------------------------- */ + +void DynamicalMatrix::convert_units(const char *style) +{ + // physical constants from: + // http://physics.nist.gov/cuu/Constants/Table/allascii.txt + // using thermochemical calorie = 4.184 J + + if (strcmp(style,"lj") == 0) { + error->all(FLERR,"Conversion Not Set"); + //conversion = 1; // lj -> 10 J/mol + + } else if (strcmp(style,"real") == 0) { + conv_energy = 418.4; // kcal/mol -> 10 J/mol + conv_mass = 1; // g/mol -> g/mol + conv_distance = 1; // angstrom -> angstrom + + } else if (strcmp(style,"metal") == 0) { + conv_energy = 9648.5; // eV -> 10 J/mol + conv_mass = 1; // g/mol -> g/mol + conv_distance = 1; // angstrom -> angstrom + + } else if (strcmp(style,"si") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + conv_energy = 6.022E22; // J -> 10 J/mol + conv_mass = 6.022E26; // kg -> g/mol + conv_distance = 1E-10; // meter -> angstrom + + } else if (strcmp(style,"cgs") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + conv_energy = 6.022E12; // Erg -> 10 J/mol + conv_mass = 6.022E23; // g -> g/mol + conv_distance = 1E-7; // centimeter -> angstrom + + } else if (strcmp(style,"electron") == 0) { + conv_energy = 262550; // Hartree -> 10 J/mol + conv_mass = 1; // amu -> g/mol + conv_distance = 0.529177249; // bohr -> angstrom + + } else if (strcmp(style,"micro") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + conv_energy = 6.022E10; // picogram-micrometer^2/microsecond^2 -> 10 J/mol + conv_mass = 6.022E11; // pg -> g/mol + conv_distance = 1E-4; // micrometer -> angstrom + + } else if (strcmp(style,"nano") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + conv_energy = 6.022E4; // attogram-nanometer^2/nanosecond^2 -> 10 J/mol + conv_mass = 6.022E5; // ag -> g/mol + conv_distance = 0.1; // angstrom -> angstrom + + } else error->all(FLERR,"Units Type Conversion Not Found"); + +} diff --git a/src/USER-PHONON/dynamical_matrix.h b/src/USER-PHONON/dynamical_matrix.h new file mode 100644 index 0000000000..237c3f7d27 --- /dev/null +++ b/src/USER-PHONON/dynamical_matrix.h @@ -0,0 +1,72 @@ +// +// Created by charlie sievers on 6/21/18. +// + +#ifdef COMMAND_CLASS + +CommandStyle(dynamical_matrix,DynamicalMatrix) + +#else + +#ifndef LMP_DYNAMICAL_MATRIX_H +#define LMP_DYNAMICAL_MATRIX_H + +#include "pointers.h" + +namespace LAMMPS_NS { + + class DynamicalMatrix : protected Pointers { + public: + DynamicalMatrix(class LAMMPS *); + virtual ~DynamicalMatrix(); + void command(int, char **); + void setup(); + + protected: + int eflag,vflag; // flags for energy/virial computation + int external_force_clear; // clear forces locally or externally + + + int triclinic; // 0 if domain is orthog, 1 if triclinic + int pairflag; + + int pair_compute_flag; // 0 if pair->compute is skipped + int kspace_compute_flag; // 0 if kspace->compute is skipped + + int nvec; // local atomic dof = length of xvec + + void energy_force(int); + void force_clear(); + virtual void openfile(const char* filename); + + private: + void options(int, char **); + void calculateMatrix(); + void writeMatrix(); + void convert_units(const char *style); + void displace_atom(int local_idx, int direction, int magnitude); + + double conversion; + double conv_energy; + double conv_distance; + double conv_mass; + double del; + int igroup,groupbit; + int scaleflag; + int me; + bigint dynlen; + double **dynmat; + double **final_dynmat; + + int compressed; // 1 if dump file is written compressed, 0 no + int binaryflag; // 1 if dump file is written binary, 0 no + int file_opened; // 1 if openfile method has been called, 0 no + int file_flag; // 1 custom file name, 0 dynmat.dat + + FILE *fp; + }; +} + + +#endif //LMP_DYNAMICAL_MATRIX_H +#endif \ No newline at end of file diff --git a/src/USER-PHONON/third_order.cpp b/src/USER-PHONON/third_order.cpp new file mode 100644 index 0000000000..6fb8589c3b --- /dev/null +++ b/src/USER-PHONON/third_order.cpp @@ -0,0 +1,529 @@ +// +// Created by charlie sievers on 7/5/18. +// + + +#include +#include +#include "third_order.h" +#include "atom.h" +#include "complex" +#include "domain.h" +#include "comm.h" +#include "group.h" +#include "force.h" +#include "math_extra.h" +#include "bond.h" +#include "angle.h" +#include "dihedral.h" +#include "improper.h" +#include "kspace.h" +#include "update.h" +#include "neighbor.h" +#include "pair.h" +#include "timer.h" +#include "finish.h" + + +using namespace LAMMPS_NS; +enum{REGULAR,BALLISTICO}; + +/* ---------------------------------------------------------------------- */ + +ThirdOrder::ThirdOrder(LAMMPS *lmp) : Pointers(lmp), fp(NULL) +{ + external_force_clear = 1; +} + +/* ---------------------------------------------------------------------- */ + +ThirdOrder::~ThirdOrder() +{ + if (fp) fclose(fp); + fp = NULL; +} + +/* ---------------------------------------------------------------------- + setup without output or one-time post-init setup + flag = 0 = just force calculation + flag = 1 = reneighbor and force calculation +------------------------------------------------------------------------- */ + +void ThirdOrder::setup() +{ + // setup domain, communication and neighboring + // acquire ghosts + // build neighbor lists + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + comm->exchange(); + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + domain->image_check(); + domain->box_too_small_check(); + neighbor->build(1); + neighbor->ncalls = 0; + neighbor->every = 3; // build every this many steps + neighbor->delay = 1; + neighbor->ago = 0; + neighbor->ndanger = 0; + + // compute all forces + force_clear(); + external_force_clear = 0; + + eflag=0; + vflag=0; + if (pair_compute_flag) force->pair->compute(eflag,vflag); + else if (force->pair) force->pair->compute_dummy(eflag,vflag); + + if (atom->molecular) { + if (force->bond) force->bond->compute(eflag,vflag); + if (force->angle) force->angle->compute(eflag,vflag); + if (force->dihedral) force->dihedral->compute(eflag,vflag); + if (force->improper) force->improper->compute(eflag,vflag); + } + + if (force->kspace) { + force->kspace->setup(); + if (kspace_compute_flag) force->kspace->compute(eflag,vflag); + else force->kspace->compute_dummy(eflag,vflag); + } + + if (force->newton) comm->reverse_comm(); +} + +/* ---------------------------------------------------------------------- */ + +void ThirdOrder::command(int narg, char **arg) +{ + MPI_Comm_rank(world,&me); + + if (domain->box_exist == 0) + error->all(FLERR,"Dynamical_matrix command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal dynamical_matrix command"); + + lmp->init(); + + // orthogonal vs triclinic simulation box + + triclinic = domain->triclinic; + + if (force->pair && force->pair->compute_flag) pair_compute_flag = 1; + else pair_compute_flag = 0; + if (force->kspace && force->kspace->compute_flag) kspace_compute_flag = 1; + else kspace_compute_flag = 0; + + // group and style + + igroup = group->find(arg[0]); + if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); + groupbit = group->bitmask[igroup]; + update->setupflag = 1; + + int style = -1; + if (strcmp(arg[1],"regular") == 0) style = REGULAR; + else if (strcmp(arg[1],"ballistico") == 0) style = BALLISTICO; + else error->all(FLERR,"Illegal Dynamical Matrix command"); + + // set option defaults + + binaryflag = 0; + scaleflag = 0; + compressed = 0; + file_flag = 0; + file_opened = 0; + conversion = 1; + + // read options from end of input line + if (style == REGULAR) options(narg-3,&arg[3]); //COME BACK + else if (style == BALLISTICO) options(narg-3,&arg[3]); //COME BACK + else if (comm->me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); + del = force->numeric(FLERR, arg[2]); + + // move atoms by 3-vector or specified variable(s) + + if (style == REGULAR) { + setup(); + calculateMatrix(); + } + + if (style == BALLISTICO) { + setup(); + convert_units(update->unit_style); + conversion = conv_energy/conv_distance/conv_distance; + calculateMatrix(); + } + + Finish finish(lmp); + finish.end(1); +} + +/* ---------------------------------------------------------------------- + parse optional parameters +------------------------------------------------------------------------- */ + +void ThirdOrder::options(int narg, char **arg) +{ + if (narg < 0) error->all(FLERR,"Illegal dynamical_matrix command"); + int iarg = 0; + const char *filename = "third_order.txt"; + std::stringstream fss; + + while (iarg < narg) { + if (strcmp(arg[iarg],"file") == 0) { + if (iarg+2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); + fss << arg[iarg + 1] << me; + filename = fss.str().c_str(); + file_flag = 1; + iarg += 2; + } + else if (strcmp(arg[iarg],"binary") == 0) { + if (iarg + 2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); + if (strcmp(arg[iarg+1],"gzip") == 0) { + compressed = 1; + } + else if (strcmp(arg[iarg+1],"yes") == 0) { + binaryflag = 1; + } + iarg += 2; + } else error->all(FLERR,"Illegal dynamical_matrix command"); + } + if (file_flag == 1) { + openfile(filename); + } +} + +/* ---------------------------------------------------------------------- + generic opening of a file + ASCII or binary or gzipped + some derived classes override this function +------------------------------------------------------------------------- */ + +void ThirdOrder::openfile(const char* filename) +{ + // if file already opened, return + if (file_opened) return; + + if (compressed) { +#ifdef LAMMPS_GZIP + char gzip[128]; + sprintf(gzip,"gzip -6 > %s",filename); +#ifdef _WIN32 + fp = _popen(gzip,"wb"); +#else + fp = popen(gzip,"w"); +#endif +#else + error->one(FLERR,"Cannot open gzipped file"); +#endif + } else if (binaryflag) { + fp = fopen(filename,"wb"); + } else { + fp = fopen(filename,"w"); + } + + if (fp == NULL) error->one(FLERR,"Cannot open dump file"); + + file_opened = 1; +} + +/* ---------------------------------------------------------------------- + create dynamical matrix +------------------------------------------------------------------------- */ + +void ThirdOrder::calculateMatrix() +{ + int local_idx; // local index + int local_jdx; // second local index + int local_kdx; // third local index + int natoms = atom->natoms; + int *mask = atom->mask; + double **f = atom->f; + + energy_force(0); + + if (comm->me == 0 && screen) fprintf(screen,"Calculating Anharmonic Dynamical Matrix...\n"); + + for (int i=1; i<=natoms; i++){ + local_idx = atom->map(i); + if (local_idx >= 0 && mask[local_idx] && groupbit){ + for (int alpha=0; alpha<3; alpha++){ + displace_atom(local_idx, alpha, 1); + for (int j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + if (local_jdx >= 0&& mask[local_jdx] && groupbit){ + for (int beta=0; beta<3; beta++){ + } + } + } + displace_atom(local_idx,alpha,-2); + for (int j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + if (local_jdx >= 0 && mask[local_jdx] && groupbit){ + for (int beta=0; beta<3; beta++){ + + } + } + } + displace_atom(local_idx,alpha,1); + } + } + } + + //for (int proc1=0; proc1 < comm->nprocs; proc1++) { + // plocal1 = atom->nlocal; // 1 proc nlocal = 8 + // MPI_Bcast(&plocal1, 1, MPI_INT, proc1, MPI_COMM_WORLD); // plocal1 = 8 + // for (int i = 0; i < plocal1; i++) { + // if (me==proc1 & mask[i] & groupbit) + // group_flag_1 = 1; + // MPI_Bcast(&group_flag_1, 1, MPI_INT, proc1, MPI_COMM_WORLD); + // if (group_flag_1) { + // if (me == proc1) id1 = aid[i]; + // MPI_Bcast(&id1, 1, MPI_INT, proc1, MPI_COMM_WORLD); + // for (int alpha = 0; alpha < 3; alpha++) { + // for (int proc2 = 0; proc2 < comm->nprocs; proc2++) { + // plocal2 = atom->nlocal; + // MPI_Bcast(&plocal2, 1, MPI_INT, proc2, MPI_COMM_WORLD); + // for (int j = 0; j < plocal2; j++) { + // if (me==proc2 & mask[j] & groupbit) + // group_flag_2 = 1; + // MPI_Bcast(&group_flag_2, 1, MPI_INT, proc2, MPI_COMM_WORLD); + // if (mask[j] & groupbit) { + // if (me == proc2) id2 = aid[j]; + // MPI_Bcast(&id2, 1, MPI_INT, proc2, MPI_COMM_WORLD); + // for (int beta = 0; beta < 3; beta++) { +// + // if (me == proc1) x[i][alpha] += del; +// + // if (me == proc2) x[j][beta] += del; + // energy_force(0); +//// + // for (int gamma = 0; gamma < 3; gamma++) { + // for (int k = 0; k < nlocal; k++) + // if (mask[k] & groupbit) { + // first_derv[k*3+gamma] = f[k][gamma]; + // } + // } +// + // if (me == proc2) x[j][beta] -= 2 * del; + // energy_force(0); +//// + // for (int gamma = 0; gamma < 3; gamma++) { + // for (int k = 0; k < nlocal; k++) + // if (mask[k] & groupbit) { + // first_derv[k*3+gamma] -= f[k][gamma]; + // } + // } +// + // if (me == proc2) x[j][beta] += 2 * del; +// + // if (me == proc1) x[i][alpha] -= 2 * del; +// + // energy_force(0); +//// + // for (int gamma = 0; gamma < 3; gamma++) { + // for (int k = 0; k < nlocal; k++) + // if (mask[k] & groupbit) { + // first_derv[k*3+gamma] -= f[k][gamma]; + // } + // } +//// + // if (me == proc2) x[j][beta] -= 2 * del; + // energy_force(0); +//// + // for (int k = 0; k < nlocal; k++) + // if (mask[k] & groupbit) { + // for (int gamma = 0; gamma < 3; gamma++) { + // first_derv[k*3+gamma] += f[k][gamma]; + // first_derv[k*3+gamma] /= -4*del*del; + // } + // double norm = pow(first_derv[k*3], 2) + // + pow(first_derv[k*3+1], 2) + // + pow(first_derv[k+3+2], 2); + // if (fp && norm > 1.0e-16) + // fprintf(fp, + // "%d %d %d %d %d %7.8f %7.8f %7.8f\n", + // id1, alpha + 1, id2, beta + 1, aid[k], + // first_derv[k*3] * conversion, + // first_derv[k*3+1] * conversion, + // first_derv[k*3+2] * conversion); + // } +//// + // if (me == proc2) x[j][beta] += del; +// + // if (me == proc1) x[i][alpha] += del; + // } + // } + // } + // } +//// + // } + // } + // } + //} +// + + if (screen && me ==0 ) fprintf(screen,"Finished Calculating Third Order Tensor\n"); + +} + +/* ---------------------------------------------------------------------- + Displace atoms + ---------------------------------------------------------------------- */ + +void ThirdOrder::displace_atom(int local_idx, int direction, int magnitude) +{ + double **x = atom->x; + int *sametag = atom->sametag; + int j = local_idx; + + x[local_idx][direction] += del*magnitude; + + while (sametag[j] >= 0){ + j = sametag[j]; + x[j][direction] += del*magnitude; + } +} + +/* ---------------------------------------------------------------------- + evaluate potential energy and forces + may migrate atoms due to reneighboring + return new energy, which should include nextra_global dof + return negative gradient stored in atom->f + return negative gradient for nextra_global dof in fextra +------------------------------------------------------------------------- */ + +void ThirdOrder::energy_force(int resetflag) +{ + // check for reneighboring + // always communicate since atoms move + int nflag = neighbor->decide(); + + if (nflag == 0) { + timer->stamp(); + comm->forward_comm(); + timer->stamp(Timer::COMM); + } else { + if (triclinic) domain->x2lamda(atom->nlocal); + domain->pbc(); + if (domain->box_change) { + domain->reset_box(); + comm->setup(); + if (neighbor->style) neighbor->setup_bins(); + } + timer->stamp(); + + comm->borders(); + if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + timer->stamp(Timer::COMM); + + neighbor->build(1); + timer->stamp(Timer::NEIGH); + } + + force_clear(); + + timer->stamp(); + + if (pair_compute_flag) { + force->pair->compute(eflag,vflag); + timer->stamp(Timer::PAIR); + } + + if (atom->molecular) { + if (force->bond) force->bond->compute(eflag,vflag); + if (force->angle) force->angle->compute(eflag,vflag); + if (force->dihedral) force->dihedral->compute(eflag,vflag); + if (force->improper) force->improper->compute(eflag,vflag); + timer->stamp(Timer::BOND); + } + + if (kspace_compute_flag) { + force->kspace->compute(eflag,vflag); + timer->stamp(Timer::KSPACE); + } + + if (force->newton) { + comm->reverse_comm(); + timer->stamp(Timer::COMM); + } +} + +/* ---------------------------------------------------------------------- + clear force on own & ghost atoms + clear other arrays as needed +------------------------------------------------------------------------- */ + +void ThirdOrder::force_clear() +{ + if (external_force_clear) return; + + // clear global force array + // if either newton flag is set, also include ghosts + + size_t nbytes = sizeof(double) * atom->nlocal; + if (force->newton) nbytes += sizeof(double) * atom->nghost; + + if (nbytes) { + memset(&atom->f[0][0],0,3*nbytes); + } +} + +/* ---------------------------------------------------------------------- */ + +void ThirdOrder::convert_units(const char *style) +{ + // physical constants from: + // http://physics.nist.gov/cuu/Constants/Table/allascii.txt + // using thermochemical calorie = 4.184 J + + if (strcmp(style,"lj") == 0) { + error->all(FLERR,"Conversion Not Set"); + //conversion = 1; // lj -> 10 J/mol + + } else if (strcmp(style,"real") == 0) { + conv_energy = 418.4; // kcal/mol -> 10 J/mol + conv_mass = 1; // g/mol -> g/mol + conv_distance = 1; // angstrom -> angstrom + + } else if (strcmp(style,"metal") == 0) { + conv_energy = 9648.5; // eV -> 10 J/mol + conv_mass = 1; // g/mol -> g/mol + conv_distance = 1; // angstrom -> angstrom + + } else if (strcmp(style,"si") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + conv_energy = 6.022E22; // J -> 10 J/mol + conv_mass = 6.022E26; // kg -> g/mol + conv_distance = 1E-10; // meter -> angstrom + + } else if (strcmp(style,"cgs") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); + conv_energy = 6.022E12; // Erg -> 10 J/mol + conv_mass = 6.022E23; // g -> g/mol + conv_distance = 1E-7; // centimeter -> angstrom + + } else if (strcmp(style,"electron") == 0) { + conv_energy = 262550; // Hartree -> 10 J/mol + conv_mass = 1; // amu -> g/mol + conv_distance = 0.529177249; // bohr -> angstrom + + } else if (strcmp(style,"micro") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + conv_energy = 6.022E10; // picogram-micrometer^2/microsecond^2 -> 10 J/mol + conv_mass = 6.022E11; // pg -> g/mol + conv_distance = 1E-4; // micrometer -> angstrom + + } else if (strcmp(style,"nano") == 0) { + if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); + conv_energy = 6.022E4; // attogram-nanometer^2/nanosecond^2 -> 10 J/mol + conv_mass = 6.022E5; // ag -> g/mol + conv_distance = 0.1; // angstrom -> angstrom + + } else error->all(FLERR,"Units Type Conversion Not Found"); + +} diff --git a/src/USER-PHONON/third_order.h b/src/USER-PHONON/third_order.h new file mode 100644 index 0000000000..0bbdc21939 --- /dev/null +++ b/src/USER-PHONON/third_order.h @@ -0,0 +1,71 @@ +// +// Created by charlie sievers on 7/5/18. +// + + +#ifdef COMMAND_CLASS + +CommandStyle(third_order,ThirdOrder) + +#else + +#ifndef LMP_THIRD_ORDER_H +#define LMP_THIRD_ORDER_H + +#include "pointers.h" + +namespace LAMMPS_NS { + + class ThirdOrder : protected Pointers { + public: + ThirdOrder(class LAMMPS *); + virtual ~ThirdOrder(); + void command(int, char **); + void setup(); + + protected: + int eflag,vflag; // flags for energy/virial computation + int external_force_clear; // clear forces locally or externally + + + int triclinic; // 0 if domain is orthog, 1 if triclinic + int pairflag; + + int pair_compute_flag; // 0 if pair->compute is skipped + int kspace_compute_flag; // 0 if kspace->compute is skipped + + int nvec; // local atomic dof = length of xvec + + void energy_force(int); + void force_clear(); + virtual void openfile(const char* filename); + + + private: + void options(int, char **); + void calculateMatrix(); + void convert_units(const char *style); + void displace_atom(int local_idx, int direction, int magnitude); + + double conversion; + double conv_energy; + double conv_distance; + double conv_mass; + double del; + int igroup,groupbit; + int scaleflag; + int me; + + int compressed; // 1 if dump file is written compressed, 0 no + int binaryflag; // 1 if dump file is written binary, 0 no + int file_opened; // 1 if openfile method has been called, 0 no + int file_flag; // 1 custom file name, 0 dynmat.dat + + FILE *fp; + }; +} + + +#endif //LMP_THIRD_ORDER_H +#endif + -- GitLab From adebe90315bfdf6190848b0cba3d55365e3f90a4 Mon Sep 17 00:00:00 2001 From: charlie sievers Date: Fri, 1 Feb 2019 21:55:29 -0800 Subject: [PATCH 0096/1243] Optimized Dynamical Matrix --- .../phonon/dynamical_matrix_command/Manual.md | 48 + .../phonon/dynamical_matrix_command/README.md | 21 + .../dynamical_matrix_command/Si.opt.tersoff | 66 + .../dynamical_matrix_command/ff-silicon.lmp | 19 + .../dynamical_matrix_command/in.silicon | 89 + .../lmp_bank/amorphous_silicon.lmp | 534 ++ .../lmp_bank/silicon_216.lmp | 238 + .../lmp_bank/silicon_512.lmp | 534 ++ .../lmp_bank/silicon_8.lmp | 29 + .../results/dynmat.dat | 192 + .../results/out.silicon | 58 + .../silicon_input_file.lmp | 29 + .../USER/phonon/third_order_command/Manual.md | 48 + .../USER/phonon/third_order_command/README.md | 25 + .../phonon/third_order_command/Si.opt.tersoff | 66 + .../phonon/third_order_command/combine.sh | 17 + .../phonon/third_order_command/ff-silicon.lmp | 19 + .../phonon/third_order_command/in.silicon | 84 + .../lmp_bank/silicon_216.lmp | 238 + .../lmp_bank/silicon_512.lmp | 534 ++ .../lmp_bank/silicon_8.lmp | 29 + .../third_order_command/results/out.silicon | 58 + .../third_order_command/results/third_order | 4608 +++++++++++++++++ .../silicon_input_file.lmp | 29 + src/USER-PHONON/dynamical_matrix.cpp | 58 +- 25 files changed, 7642 insertions(+), 28 deletions(-) create mode 100755 examples/USER/phonon/dynamical_matrix_command/Manual.md create mode 100755 examples/USER/phonon/dynamical_matrix_command/README.md create mode 100755 examples/USER/phonon/dynamical_matrix_command/Si.opt.tersoff create mode 100755 examples/USER/phonon/dynamical_matrix_command/ff-silicon.lmp create mode 100755 examples/USER/phonon/dynamical_matrix_command/in.silicon create mode 100755 examples/USER/phonon/dynamical_matrix_command/lmp_bank/amorphous_silicon.lmp create mode 100755 examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_216.lmp create mode 100755 examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_512.lmp create mode 100755 examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_8.lmp create mode 100755 examples/USER/phonon/dynamical_matrix_command/results/dynmat.dat create mode 100755 examples/USER/phonon/dynamical_matrix_command/results/out.silicon create mode 100755 examples/USER/phonon/dynamical_matrix_command/silicon_input_file.lmp create mode 100755 examples/USER/phonon/third_order_command/Manual.md create mode 100755 examples/USER/phonon/third_order_command/README.md create mode 100755 examples/USER/phonon/third_order_command/Si.opt.tersoff create mode 100755 examples/USER/phonon/third_order_command/combine.sh create mode 100755 examples/USER/phonon/third_order_command/ff-silicon.lmp create mode 100755 examples/USER/phonon/third_order_command/in.silicon create mode 100755 examples/USER/phonon/third_order_command/lmp_bank/silicon_216.lmp create mode 100755 examples/USER/phonon/third_order_command/lmp_bank/silicon_512.lmp create mode 100755 examples/USER/phonon/third_order_command/lmp_bank/silicon_8.lmp create mode 100755 examples/USER/phonon/third_order_command/results/out.silicon create mode 100755 examples/USER/phonon/third_order_command/results/third_order create mode 100755 examples/USER/phonon/third_order_command/silicon_input_file.lmp diff --git a/examples/USER/phonon/dynamical_matrix_command/Manual.md b/examples/USER/phonon/dynamical_matrix_command/Manual.md new file mode 100755 index 0000000000..c361f80325 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/Manual.md @@ -0,0 +1,48 @@ +# dynamical_matrix command + +## Syntax + +``` +dynamical_matrix group-ID style args keyword value ... +``` + +* group-ID = ID of group of atoms to displace +* style = *regular* or *eskm* +``` +*regular* args = gamma + gamma = finite difference displacement length +*eskm* args = gamma + gamma = finite difference displacement length +``` +* zero or more keyword/value pairs may be appended +* keyword = *file* or *binary* +``` +*file* value = output_file + output_file = name of file to dump the dynamical matrix into +*binary* values = *yes* or *no* or *gzip* +``` + +## Examples + +``` +dynamical_matrix 1 regular 0.000001 +dynamical_matrix 1 eskm 0.000001 +dynamical_matrix 3 regular 0.00004 file dynmat.dat +dynamical_matrix 5 eskm 0.00000001 file dynamical.dat binary yes +``` + +## Description + +Calculate the dynamical matrix of the selected group. + +## Restrictions + +None + +## Related commands + +None + +## Default + +The option defaults are file = "dynmat.dyn", binary = no diff --git a/examples/USER/phonon/dynamical_matrix_command/README.md b/examples/USER/phonon/dynamical_matrix_command/README.md new file mode 100755 index 0000000000..8981c1e63a --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/README.md @@ -0,0 +1,21 @@ +# LAMMPS LATTICE DYNAMICS COMMANDS + +## DYNAMICAL MATRIX CALCULATOR + +This directory contains the ingredients to calculate a dynamical matrix. + +Example: +``` +NP=4 #number of processors +mpirun -np $NP lmp_mpi < in.silicon > out.silicon +``` + +To test out a different silicon example: +``` +LMP_FILE=amorphous_silicon.lmp +cp lmp_bank/$LMP_FILE ./silicon_input_file.lmp +NP=4 #number of processors +mpirun -np $NP lmp_mpi < in.silicon > out.silicon +``` + +## Requires: MANYBODY and MOLECULE packages diff --git a/examples/USER/phonon/dynamical_matrix_command/Si.opt.tersoff b/examples/USER/phonon/dynamical_matrix_command/Si.opt.tersoff new file mode 100755 index 0000000000..3bc19f0581 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/Si.opt.tersoff @@ -0,0 +1,66 @@ +# Tersoff 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: +# A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms +# other quantities are unitless + +# Aidan Thompson (athomps at sandia.gov) takes full blame for this +# file. It specifies various potentials published by J. Tersoff for +# silicon, carbon and germanium. Since Tersoff published several +# different silicon potentials, I refer to them using atom types +# Si(B), Si(C) and Si(D). The last two are almost almost identical but +# refer to two different publications. These names should be used in +# the LAMMPS command when the file is invoked. For example: +# pair_coeff * * SiCGe.tersoff Si(B). The Si(D), C and Ge potentials +# can be used pure silicon, pure carbon, pure germanium, binary SiC, +# and binary SiGe, but not binary GeC or ternary SiGeC. LAMMPS will +# generate an error if this file is used with any combination +# involving C and Ge, since there are no entries for the GeC +# interactions (Tersoff did not publish parameters for this +# cross-interaction.) + +# format of a single entry (one or more lines): +# element 1, element 2, element 3, +# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A + +# The original Tersoff potential for Silicon, Si(B) +# J. Tersoff, PRB, 37, 6991 (1988) + +Si(B) Si(B) Si(B) 3.0 1.0 1.3258 4.8381 2.0417 0.0000 22.956 + 0.33675 1.3258 95.373 3.0 0.2 3.2394 3264.7 + +# The later Tersoff potential for Silicon, Si(C) +# J. Tersoff, PRB, 38, 9902 (1988) + +Si(C) Si(C) Si(C) 3.0 1.0 1.7322 1.0039e5 16.218 -0.59826 0.78734 + 1.0999e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 + +# The later Tersoff potential for Carbon, Silicon, and Germanium +# J. Tersoff, PRB, 39, 5566 (1989) + errata (PRB 41, 3248) +# The Si and C parameters are very close to those in SiC.tersoff + +C C C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 2.2119 346.74 1.95 0.15 3.4879 1393.6 +Si(D) Si(D) Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 +Ge Ge Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.7047 419.23 2.95 0.15 2.4451 1769.0 + +C Si(D) Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 +C Si(D) C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 1.95 0.15 0.0 0.0 +C C Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 + +Si(D) C C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 +Si(D) Si(D) C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 +Si(D) C Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 + +Si(D) Ge Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 +Si(D) Si(D) Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 +Si(D) Ge Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 + +Ge Si(D) Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 +Ge Si(D) Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.95 0.15 0.0 0.0 +Ge Ge Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 + +# Optimized Tersoff for Carbon: Lindsay and Broido PRB 81, 205441 (2010) +# element 1, element 2, element 3, +# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A +C(O) C(O) C(O) 3.0 1.0 0.0 3.8049e4 4.3484 -0.930 0.72751 1.5724e-7 2.2119 430.0 1.95 0.15 3.4879 1393.6 + diff --git a/examples/USER/phonon/dynamical_matrix_command/ff-silicon.lmp b/examples/USER/phonon/dynamical_matrix_command/ff-silicon.lmp new file mode 100755 index 0000000000..f3b895f168 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/ff-silicon.lmp @@ -0,0 +1,19 @@ +############################# +#Atoms types - mass - charge# +############################# +#@ 1 atom types #!THIS LINE IS NECESSARY DON'T SPEND HOURS FINDING THAT OUT!# + +variable Si equal 1 + +############# +#Atom Masses# +############# + +mass ${Si} 28.08550 + +########################### +#Pair Potentials - Tersoff# +########################### + +pair_style tersoff +pair_coeff * * Si.opt.tersoff Si(D) diff --git a/examples/USER/phonon/dynamical_matrix_command/in.silicon b/examples/USER/phonon/dynamical_matrix_command/in.silicon new file mode 100755 index 0000000000..cda0ee8c58 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/in.silicon @@ -0,0 +1,89 @@ +###############################mm +# Atom style - charge/vdw/bonded# +################################# +atom_style full + +############################################## +#Units Metal : eV - ps - angstrom - bar# +# Real : kcal/mol - fs - angstrom - atm# +############################################## +units metal + +############ +#Run number# +############ +variable run_no equal 0 # is it a restart? +variable res_no equal ${run_no}-1 # restart file number + +####################################### +#Random Seeds and Domain Decomposition# +####################################### +variable iseed0 equal 2357 +variable iseed1 equal 26488 +variable iseed2 equal 10669 +processors * * * + +########### +#Data File# +########### +variable inpfile string silicon_input_file.lmp +variable resfile string final_restart.${res_no} +variable ff_file string ff-silicon.lmp + +########## +#Run Type# +########## +variable minimise equal 0 #Energy Minimization + +############################### +#Molecular Dynamics Parameters# +############################### +neighbor 1 bin + +################################ +#Energy Minimization Parameters# +################################ +variable mtraj equal 1 # trajectory output frequency - all system +variable etol equal 1e-5 # % change in energy +variable ftol equal 1e-5 # max force threshold (force units) +variable maxiter equal 10000 # max # of iterations + +######################## +#3D Periodic Simulation# +######################## +boundary p p p + +############################# +#Reading the input structure# +############################# +if "${run_no} == 0" then "read_data ${inpfile}" else "read_restart ${resfile}" + +############# +#Force Field# +############# +include ${ff_file} + +###################### +#Thermodynamic Output# +###################### +variable str_basic string 'step time pe temp press' + +##################### +#Energy Minimization# +##################### +if "${minimise} <= 0 || ${run_no} > 0" then "jump SELF end_minimise" + print "Doing CG minimisation" + dump mdcd all dcd ${mtraj} min.dcd + dump_modify mdcd unwrap yes + min_style cg + min_modify line quadratic + minimize ${etol} ${ftol} ${maxiter} ${maxiter} + reset_timestep 0 + undump mdcd +label end_minimise + +################## +#Dynamical Matrix# +################## +dynamical_matrix all eskm 0.000001 file dynmat.dat binary no + diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/amorphous_silicon.lmp b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/amorphous_silicon.lmp new file mode 100755 index 0000000000..036ece0279 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/amorphous_silicon.lmp @@ -0,0 +1,534 @@ +LAMMPS description + + 512 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 21.848000 xlo xhi + 0.0000000 21.848000 ylo yhi + 0.0000000 21.848000 zlo zhi + + Atoms + + 1 1 1 0.0000000 6.2030000 5.5980000 12.9980000 + 2 2 1 0.0000000 21.3100000 5.6310000 21.1380000 + 3 3 1 0.0000000 19.5320000 6.1170000 3.6940000 + 4 4 1 0.0000000 4.3700000 14.0260000 0.0900000 + 5 5 1 0.0000000 10.1930000 7.4590000 2.3530000 + 6 6 1 0.0000000 17.5070000 14.1860000 3.6790000 + 7 7 1 0.0000000 11.2050000 15.9160000 15.0480000 + 8 8 1 0.0000000 8.6050000 19.8970000 21.0040000 + 9 9 1 0.0000000 15.0360000 17.5650000 1.3640000 + 10 10 1 0.0000000 12.0450000 3.3600000 7.2720000 + 11 11 1 0.0000000 7.1330000 17.4130000 18.0480000 + 12 12 1 0.0000000 8.7340000 6.3830000 3.8480000 + 13 13 1 0.0000000 13.0940000 3.2490000 3.5840000 + 14 14 1 0.0000000 11.3200000 7.2770000 20.4120000 + 15 15 1 0.0000000 19.7770000 8.9110000 0.3000000 + 16 16 1 0.0000000 11.9710000 20.8500000 1.5140000 + 17 17 1 0.0000000 10.4480000 10.3650000 15.4040000 + 18 18 1 0.0000000 9.2060000 9.4670000 10.2240000 + 19 19 1 0.0000000 8.4360000 13.6240000 17.6570000 + 20 20 1 0.0000000 18.2020000 21.1230000 0.1380000 + 21 21 1 0.0000000 3.2970000 19.5740000 14.7410000 + 22 22 1 0.0000000 12.5330000 17.3580000 7.5960000 + 23 23 1 0.0000000 1.4040000 18.1060000 3.1510000 + 24 24 1 0.0000000 17.7440000 13.1530000 16.7940000 + 25 25 1 0.0000000 12.1070000 12.6630000 18.0340000 + 26 26 1 0.0000000 8.7270000 17.1140000 10.4200000 + 27 27 1 0.0000000 13.2330000 16.0380000 13.9210000 + 28 28 1 0.0000000 15.2360000 14.8650000 7.0150000 + 29 29 1 0.0000000 5.5190000 20.8660000 19.9260000 + 30 30 1 0.0000000 16.5810000 9.7460000 15.1710000 + 31 31 1 0.0000000 2.0500000 13.8550000 21.8010000 + 32 32 1 0.0000000 21.2670000 20.8970000 13.6740000 + 33 33 1 0.0000000 9.6900000 6.7650000 0.1950000 + 34 34 1 0.0000000 11.2570000 13.2440000 2.8190000 + 35 35 1 0.0000000 10.7810000 12.7310000 12.1920000 + 36 36 1 0.0000000 16.2630000 7.4100000 1.5360000 + 37 37 1 0.0000000 19.6100000 18.1440000 19.6830000 + 38 38 1 0.0000000 8.1790000 0.1200000 10.1620000 + 39 39 1 0.0000000 17.0520000 20.4210000 15.0450000 + 40 40 1 0.0000000 12.3690000 12.6710000 4.8320000 + 41 41 1 0.0000000 7.8300000 16.6790000 14.2470000 + 42 42 1 0.0000000 1.6790000 9.9500000 1.2660000 + 43 43 1 0.0000000 16.6160000 14.6580000 13.2790000 + 44 44 1 0.0000000 13.7430000 11.9730000 21.5360000 + 45 45 1 0.0000000 5.2590000 15.1850000 9.5720000 + 46 46 1 0.0000000 20.5980000 14.7930000 20.4140000 + 47 47 1 0.0000000 1.5640000 16.8080000 13.0450000 + 48 48 1 0.0000000 21.3670000 11.4610000 20.6420000 + 49 49 1 0.0000000 14.5890000 5.9510000 7.1950000 + 50 50 1 0.0000000 1.0870000 13.5410000 11.3300000 + 51 51 1 0.0000000 6.2040000 4.8970000 16.9420000 + 52 52 1 0.0000000 0.4800000 4.1450000 0.8710000 + 53 53 1 0.0000000 2.0120000 5.7530000 1.8950000 + 54 54 1 0.0000000 9.8460000 19.1320000 7.3060000 + 55 55 1 0.0000000 18.3760000 21.3430000 4.0940000 + 56 56 1 0.0000000 5.2900000 6.5400000 5.3620000 + 57 57 1 0.0000000 1.4110000 6.5750000 4.0580000 + 58 58 1 0.0000000 16.1600000 15.1390000 11.0380000 + 59 59 1 0.0000000 21.0670000 18.3830000 8.6900000 + 60 60 1 0.0000000 18.0250000 17.7750000 1.4340000 + 61 61 1 0.0000000 19.0570000 16.2190000 6.6410000 + 62 62 1 0.0000000 5.1170000 16.5510000 11.5540000 + 63 63 1 0.0000000 14.4810000 7.8720000 12.6320000 + 64 64 1 0.0000000 11.7990000 10.9690000 13.5430000 + 65 65 1 0.0000000 11.2980000 18.5410000 1.5740000 + 66 66 1 0.0000000 16.1280000 19.0390000 19.6440000 + 67 67 1 0.0000000 6.0950000 7.0580000 9.6530000 + 68 68 1 0.0000000 5.3890000 20.2540000 10.7060000 + 69 69 1 0.0000000 17.9160000 18.9070000 21.1540000 + 70 70 1 0.0000000 13.0780000 2.1790000 17.4030000 + 71 71 1 0.0000000 8.0450000 14.3440000 14.0640000 + 72 72 1 0.0000000 14.4380000 6.8780000 14.6950000 + 73 73 1 0.0000000 0.4570000 21.6180000 8.3670000 + 74 74 1 0.0000000 6.4350000 16.9720000 21.7330000 + 75 75 1 0.0000000 8.0530000 4.0310000 20.1860000 + 76 76 1 0.0000000 6.8130000 19.7870000 12.5790000 + 77 77 1 0.0000000 19.0490000 10.8480000 6.0760000 + 78 78 1 0.0000000 2.2540000 7.7370000 0.5320000 + 79 79 1 0.0000000 16.3920000 9.0880000 3.1430000 + 80 80 1 0.0000000 2.3620000 2.5500000 7.5690000 + 81 81 1 0.0000000 16.4560000 18.5670000 3.1120000 + 82 82 1 0.0000000 8.9560000 21.0830000 12.3020000 + 83 83 1 0.0000000 20.5540000 8.9280000 5.9480000 + 84 84 1 0.0000000 13.5930000 8.4890000 16.2370000 + 85 85 1 0.0000000 9.5270000 18.0720000 3.0190000 + 86 86 1 0.0000000 11.3690000 15.3870000 7.1310000 + 87 87 1 0.0000000 8.3670000 13.3960000 11.8610000 + 88 88 1 0.0000000 14.6370000 11.4110000 11.4870000 + 89 89 1 0.0000000 8.4720000 16.0650000 2.4300000 + 90 90 1 0.0000000 8.2360000 5.2200000 18.1710000 + 91 91 1 0.0000000 11.0620000 2.8760000 0.4170000 + 92 92 1 0.0000000 14.0830000 1.3550000 14.0190000 + 93 93 1 0.0000000 20.5600000 4.1900000 19.4660000 + 94 94 1 0.0000000 4.6340000 13.0980000 10.3670000 + 95 95 1 0.0000000 19.9860000 15.5670000 11.7860000 + 96 96 1 0.0000000 21.5070000 4.1860000 14.8350000 + 97 97 1 0.0000000 3.3000000 11.2060000 2.5350000 + 98 98 1 0.0000000 19.2680000 21.0240000 10.9110000 + 99 99 1 0.0000000 12.2370000 19.4650000 19.9000000 + 100 100 1 0.0000000 8.3790000 9.6670000 14.5440000 + 101 101 1 0.0000000 5.4520000 19.1660000 5.6940000 + 102 102 1 0.0000000 15.8720000 15.4140000 0.3070000 + 103 103 1 0.0000000 6.9830000 19.1480000 0.5830000 + 104 104 1 0.0000000 7.9760000 18.3420000 8.5250000 + 105 105 1 0.0000000 13.9710000 6.7570000 1.1860000 + 106 106 1 0.0000000 18.7050000 7.2110000 9.2350000 + 107 107 1 0.0000000 3.2430000 13.6330000 12.1990000 + 108 108 1 0.0000000 1.9830000 10.8340000 5.4640000 + 109 109 1 0.0000000 16.5770000 5.0400000 11.4490000 + 110 110 1 0.0000000 9.5130000 6.2390000 14.3030000 + 111 111 1 0.0000000 14.1990000 4.0910000 16.7750000 + 112 112 1 0.0000000 8.0160000 3.5600000 2.0280000 + 113 113 1 0.0000000 7.9650000 12.1700000 7.8050000 + 114 114 1 0.0000000 0.3770000 0.0320000 15.5780000 + 115 115 1 0.0000000 19.0860000 17.5690000 12.6230000 + 116 116 1 0.0000000 17.2970000 16.8030000 13.9660000 + 117 117 1 0.0000000 6.7180000 10.5880000 19.5790000 + 118 118 1 0.0000000 21.3930000 21.2940000 6.2410000 + 119 119 1 0.0000000 16.0260000 18.7640000 13.6100000 + 120 120 1 0.0000000 3.1880000 2.1990000 18.5690000 + 121 121 1 0.0000000 20.7860000 13.7840000 4.4870000 + 122 122 1 0.0000000 18.3540000 11.7960000 11.0710000 + 123 123 1 0.0000000 19.3210000 0.4960000 5.9630000 + 124 124 1 0.0000000 3.7260000 13.4120000 18.4840000 + 125 125 1 0.0000000 4.4280000 4.9270000 18.4730000 + 126 126 1 0.0000000 2.7040000 21.7660000 15.2940000 + 127 127 1 0.0000000 9.3640000 14.3230000 3.7130000 + 128 128 1 0.0000000 20.5800000 3.3360000 7.9310000 + 129 129 1 0.0000000 2.4060000 4.1320000 17.3120000 + 130 130 1 0.0000000 0.9210000 2.6080000 11.0930000 + 131 131 1 0.0000000 13.7900000 9.5610000 8.2490000 + 132 132 1 0.0000000 5.5210000 8.6760000 2.5590000 + 133 133 1 0.0000000 11.1320000 11.1160000 6.1310000 + 134 134 1 0.0000000 1.6180000 6.5650000 10.7690000 + 135 135 1 0.0000000 21.0480000 17.3880000 3.1250000 + 136 136 1 0.0000000 2.5950000 13.3430000 3.3870000 + 137 137 1 0.0000000 1.8600000 4.7830000 14.1190000 + 138 138 1 0.0000000 1.2420000 12.9340000 9.0760000 + 139 139 1 0.0000000 2.2650000 8.2300000 7.4350000 + 140 140 1 0.0000000 10.9360000 17.8140000 10.9520000 + 141 141 1 0.0000000 10.3160000 13.8030000 14.5060000 + 142 142 1 0.0000000 11.0500000 2.5760000 12.8090000 + 143 143 1 0.0000000 18.3430000 15.3950000 10.0190000 + 144 144 1 0.0000000 8.2990000 0.3320000 5.4980000 + 145 145 1 0.0000000 17.9730000 3.4330000 17.4260000 + 146 146 1 0.0000000 0.8080000 7.5530000 20.4740000 + 147 147 1 0.0000000 20.6320000 14.4730000 6.7080000 + 148 148 1 0.0000000 19.3400000 2.8450000 5.9340000 + 149 149 1 0.0000000 5.2100000 0.9290000 6.2580000 + 150 150 1 0.0000000 8.6370000 4.0920000 9.2870000 + 151 151 1 0.0000000 16.5730000 2.0050000 1.7720000 + 152 152 1 0.0000000 14.6570000 14.1440000 14.4910000 + 153 153 1 0.0000000 11.1610000 6.0610000 15.8870000 + 154 154 1 0.0000000 3.8100000 4.2040000 2.1350000 + 155 155 1 0.0000000 18.6920000 11.8180000 18.5170000 + 156 156 1 0.0000000 20.4240000 10.6340000 10.7960000 + 157 157 1 0.0000000 8.9050000 9.9220000 20.2310000 + 158 158 1 0.0000000 7.7940000 19.5410000 2.7410000 + 159 159 1 0.0000000 2.7600000 18.2100000 9.0140000 + 160 160 1 0.0000000 11.7480000 5.0280000 4.3170000 + 161 161 1 0.0000000 20.6470000 3.0010000 2.1470000 + 162 162 1 0.0000000 6.5680000 11.9510000 11.1410000 + 163 163 1 0.0000000 18.0300000 5.6700000 13.1650000 + 164 164 1 0.0000000 15.8950000 17.4810000 17.7940000 + 165 165 1 0.0000000 0.6840000 12.2180000 4.0930000 + 166 166 1 0.0000000 0.9170000 0.0080000 0.9710000 + 167 167 1 0.0000000 1.5850000 18.4470000 16.1470000 + 168 168 1 0.0000000 13.1970000 2.0830000 5.6040000 + 169 169 1 0.0000000 13.4220000 1.6690000 19.6280000 + 170 170 1 0.0000000 7.2980000 15.5410000 6.4330000 + 171 171 1 0.0000000 11.8930000 0.1240000 5.2450000 + 172 172 1 0.0000000 21.5410000 5.4260000 7.3690000 + 173 173 1 0.0000000 6.2310000 17.4900000 7.1340000 + 174 174 1 0.0000000 20.3880000 18.7320000 14.2000000 + 175 175 1 0.0000000 15.0410000 20.5060000 3.2370000 + 176 176 1 0.0000000 19.8180000 7.0070000 7.1800000 + 177 177 1 0.0000000 8.4660000 2.7180000 5.7470000 + 178 178 1 0.0000000 5.4480000 10.4180000 6.1220000 + 179 179 1 0.0000000 10.8570000 0.2910000 3.1650000 + 180 180 1 0.0000000 7.1820000 12.9370000 19.5560000 + 181 181 1 0.0000000 21.6620000 11.8360000 12.5450000 + 182 182 1 0.0000000 10.9080000 11.2050000 1.6360000 + 183 183 1 0.0000000 11.2840000 8.4420000 16.6070000 + 184 184 1 0.0000000 8.0040000 7.5690000 15.4890000 + 185 185 1 0.0000000 8.0790000 6.2840000 8.6400000 + 186 186 1 0.0000000 18.9520000 12.1530000 4.0530000 + 187 187 1 0.0000000 10.3010000 12.0820000 8.1320000 + 188 188 1 0.0000000 14.4560000 11.6780000 4.7170000 + 189 189 1 0.0000000 7.1020000 21.2750000 15.8180000 + 190 190 1 0.0000000 13.1170000 20.7170000 9.0870000 + 191 191 1 0.0000000 5.3560000 2.2610000 12.5060000 + 192 192 1 0.0000000 17.3690000 11.1000000 2.4870000 + 193 193 1 0.0000000 15.9510000 5.0030000 20.2280000 + 194 194 1 0.0000000 3.3320000 11.8950000 8.8170000 + 195 195 1 0.0000000 8.2450000 1.7100000 19.8310000 + 196 196 1 0.0000000 9.0600000 15.9380000 18.2990000 + 197 197 1 0.0000000 10.3120000 12.4780000 16.5400000 + 198 198 1 0.0000000 21.2690000 2.1440000 16.1630000 + 199 199 1 0.0000000 20.7920000 11.3890000 2.6870000 + 200 200 1 0.0000000 5.5190000 10.8650000 12.9180000 + 201 201 1 0.0000000 13.1600000 14.6530000 5.7980000 + 202 202 1 0.0000000 9.4110000 4.0280000 3.9640000 + 203 203 1 0.0000000 10.1160000 21.3800000 6.7070000 + 204 204 1 0.0000000 18.8050000 17.5440000 8.7540000 + 205 205 1 0.0000000 0.2690000 20.1700000 17.2400000 + 206 206 1 0.0000000 14.6190000 13.4340000 10.3480000 + 207 207 1 0.0000000 14.9800000 3.6520000 2.2770000 + 208 208 1 0.0000000 10.4210000 1.4390000 14.8540000 + 209 209 1 0.0000000 2.8950000 8.5990000 11.0640000 + 210 210 1 0.0000000 8.3350000 0.6070000 14.2020000 + 211 211 1 0.0000000 5.6790000 2.9730000 15.7800000 + 212 212 1 0.0000000 7.9000000 8.2920000 21.6460000 + 213 213 1 0.0000000 1.7820000 17.8720000 5.4810000 + 214 214 1 0.0000000 7.1130000 2.5790000 13.9770000 + 215 215 1 0.0000000 14.4580000 4.6660000 0.2210000 + 216 216 1 0.0000000 2.6400000 9.9660000 17.7570000 + 217 217 1 0.0000000 12.9280000 10.2110000 10.3600000 + 218 218 1 0.0000000 0.5090000 2.0800000 8.8230000 + 219 219 1 0.0000000 0.9650000 20.6540000 11.9240000 + 220 220 1 0.0000000 19.5740000 21.0310000 2.1230000 + 221 221 1 0.0000000 18.6770000 7.8820000 12.9890000 + 222 222 1 0.0000000 17.1700000 3.9160000 5.7110000 + 223 223 1 0.0000000 7.0920000 12.0700000 1.6960000 + 224 224 1 0.0000000 2.6840000 17.0880000 1.3490000 + 225 225 1 0.0000000 5.4860000 16.7240000 19.5970000 + 226 226 1 0.0000000 16.3220000 3.8420000 15.8790000 + 227 227 1 0.0000000 3.8940000 2.4920000 0.4900000 + 228 228 1 0.0000000 13.2430000 3.5150000 13.0570000 + 229 229 1 0.0000000 13.3010000 21.5940000 12.5150000 + 230 230 1 0.0000000 4.9010000 11.9630000 0.9870000 + 231 231 1 0.0000000 12.6700000 14.8980000 18.4670000 + 232 232 1 0.0000000 6.4220000 6.6170000 3.2980000 + 233 233 1 0.0000000 16.6360000 5.9910000 15.0630000 + 234 234 1 0.0000000 17.9000000 15.3980000 1.6090000 + 235 235 1 0.0000000 18.1580000 0.8480000 9.7210000 + 236 236 1 0.0000000 20.2850000 4.8230000 12.9090000 + 237 237 1 0.0000000 1.6610000 2.7360000 5.3350000 + 238 238 1 0.0000000 5.8340000 0.9980000 16.9740000 + 239 239 1 0.0000000 9.0090000 7.7870000 5.7310000 + 240 240 1 0.0000000 16.1890000 4.3150000 7.8490000 + 241 241 1 0.0000000 16.5840000 8.9600000 12.9530000 + 242 242 1 0.0000000 4.8520000 10.4780000 21.0310000 + 243 243 1 0.0000000 2.7810000 16.7740000 17.2520000 + 244 244 1 0.0000000 19.7990000 10.0200000 15.9170000 + 245 245 1 0.0000000 3.1690000 7.6710000 5.2800000 + 246 246 1 0.0000000 15.1980000 2.3520000 8.6870000 + 247 247 1 0.0000000 16.3130000 2.2040000 14.2110000 + 248 248 1 0.0000000 6.3140000 2.9350000 6.7010000 + 249 249 1 0.0000000 8.2590000 4.5060000 13.2730000 + 250 250 1 0.0000000 13.9300000 18.2210000 14.4470000 + 251 251 1 0.0000000 20.2210000 7.9620000 14.8160000 + 252 252 1 0.0000000 1.6700000 11.5910000 21.3490000 + 253 253 1 0.0000000 11.2380000 16.3450000 17.3670000 + 254 254 1 0.0000000 2.0800000 20.2850000 2.3410000 + 255 255 1 0.0000000 13.5570000 16.5190000 4.3840000 + 256 256 1 0.0000000 7.4220000 19.6120000 18.9900000 + 257 257 1 0.0000000 12.9300000 16.8740000 2.1540000 + 258 258 1 0.0000000 14.8300000 17.0150000 10.5830000 + 259 259 1 0.0000000 9.9680000 16.3050000 20.5360000 + 260 260 1 0.0000000 20.9510000 14.9180000 15.5360000 + 261 261 1 0.0000000 21.2710000 0.7830000 2.5700000 + 262 262 1 0.0000000 7.5010000 11.4110000 5.6070000 + 263 263 1 0.0000000 15.1820000 11.1410000 6.9920000 + 264 264 1 0.0000000 12.3430000 6.8350000 2.9520000 + 265 265 1 0.0000000 15.6910000 17.3040000 4.9430000 + 266 266 1 0.0000000 6.2450000 1.4930000 10.4630000 + 267 267 1 0.0000000 15.3140000 20.7570000 16.6390000 + 268 268 1 0.0000000 18.2310000 18.8700000 10.8220000 + 269 269 1 0.0000000 19.9080000 8.2790000 11.0020000 + 270 270 1 0.0000000 16.2580000 5.0600000 3.6820000 + 271 271 1 0.0000000 3.6660000 15.6980000 13.3000000 + 272 272 1 0.0000000 21.3440000 9.2620000 2.0490000 + 273 273 1 0.0000000 21.6340000 20.9700000 20.9670000 + 274 274 1 0.0000000 20.4570000 2.7200000 11.7840000 + 275 275 1 0.0000000 4.3450000 15.9260000 15.6130000 + 276 276 1 0.0000000 18.5090000 3.3140000 1.1410000 + 277 277 1 0.0000000 0.4070000 15.7920000 11.2970000 + 278 278 1 0.0000000 13.3440000 8.1980000 4.5520000 + 279 279 1 0.0000000 8.5380000 21.6840000 3.2560000 + 280 280 1 0.0000000 2.2890000 0.7680000 11.6890000 + 281 281 1 0.0000000 21.5990000 18.8900000 6.4050000 + 282 282 1 0.0000000 14.9140000 7.5570000 8.8670000 + 283 283 1 0.0000000 21.3690000 18.6450000 21.2590000 + 284 284 1 0.0000000 10.9470000 5.8950000 10.8840000 + 285 285 1 0.0000000 2.6280000 15.7990000 6.4350000 + 286 286 1 0.0000000 11.9940000 15.1200000 20.8540000 + 287 287 1 0.0000000 16.6450000 10.2270000 10.9850000 + 288 288 1 0.0000000 13.0310000 2.8900000 9.3200000 + 289 289 1 0.0000000 12.4260000 19.8280000 13.6940000 + 290 290 1 0.0000000 19.8890000 19.6500000 17.8410000 + 291 291 1 0.0000000 4.0230000 9.6810000 4.2830000 + 292 292 1 0.0000000 2.6590000 21.3600000 4.2810000 + 293 293 1 0.0000000 6.4930000 3.2770000 9.0110000 + 294 294 1 0.0000000 21.3560000 20.3330000 10.0560000 + 295 295 1 0.0000000 14.3030000 20.6610000 0.9740000 + 296 296 1 0.0000000 4.4890000 8.4620000 0.4180000 + 297 297 1 0.0000000 6.5630000 7.5730000 11.8490000 + 298 298 1 0.0000000 3.4090000 1.4420000 13.6640000 + 299 299 1 0.0000000 15.6340000 1.9640000 5.3770000 + 300 300 1 0.0000000 11.9210000 0.8170000 9.6710000 + 301 301 1 0.0000000 20.9660000 9.2330000 20.1270000 + 302 302 1 0.0000000 1.6280000 6.2090000 8.4340000 + 303 303 1 0.0000000 0.5530000 9.8060000 7.0560000 + 304 304 1 0.0000000 11.5710000 18.9280000 8.9830000 + 305 305 1 0.0000000 4.2490000 7.9910000 14.8160000 + 306 306 1 0.0000000 19.7300000 12.4900000 7.6500000 + 307 307 1 0.0000000 10.8450000 14.1880000 9.0020000 + 308 308 1 0.0000000 10.8070000 11.1620000 10.2560000 + 309 309 1 0.0000000 4.7040000 8.6980000 12.6030000 + 310 310 1 0.0000000 3.7570000 12.0590000 6.5220000 + 311 311 1 0.0000000 9.7910000 2.9010000 7.6620000 + 312 312 1 0.0000000 3.7810000 14.0810000 5.2770000 + 313 313 1 0.0000000 4.0640000 19.1000000 1.8260000 + 314 314 1 0.0000000 21.7520000 10.6160000 14.7710000 + 315 315 1 0.0000000 1.3090000 11.5200000 16.3780000 + 316 316 1 0.0000000 5.1840000 20.6560000 0.4260000 + 317 317 1 0.0000000 10.7630000 2.3920000 17.0100000 + 318 318 1 0.0000000 4.7970000 15.9920000 1.2450000 + 319 319 1 0.0000000 11.1370000 0.4590000 11.8330000 + 320 320 1 0.0000000 14.5870000 13.6170000 1.1610000 + 321 321 1 0.0000000 9.8660000 0.7940000 8.6450000 + 322 322 1 0.0000000 17.7650000 19.2430000 7.2990000 + 323 323 1 0.0000000 6.0610000 1.2430000 19.3000000 + 324 324 1 0.0000000 18.2200000 12.8760000 13.2170000 + 325 325 1 0.0000000 18.0460000 13.1700000 9.1450000 + 326 326 1 0.0000000 3.3530000 3.3130000 15.2040000 + 327 327 1 0.0000000 10.4090000 19.4890000 16.3660000 + 328 328 1 0.0000000 15.6710000 1.1260000 19.9260000 + 329 329 1 0.0000000 10.8900000 7.3650000 7.1060000 + 330 330 1 0.0000000 13.4480000 20.2870000 5.0130000 + 331 331 1 0.0000000 16.0530000 0.3050000 0.2340000 + 332 332 1 0.0000000 9.8430000 17.8410000 14.6670000 + 333 333 1 0.0000000 13.0150000 10.2370000 1.1400000 + 334 334 1 0.0000000 4.2090000 16.6330000 8.0040000 + 335 335 1 0.0000000 4.5530000 4.3630000 11.8090000 + 336 336 1 0.0000000 12.4370000 18.2310000 5.4180000 + 337 337 1 0.0000000 4.6660000 4.4220000 5.9770000 + 338 338 1 0.0000000 9.5670000 9.6790000 2.7600000 + 339 339 1 0.0000000 17.6640000 17.0250000 16.2770000 + 340 340 1 0.0000000 20.3640000 13.8280000 13.4210000 + 341 341 1 0.0000000 10.0140000 7.4130000 9.2700000 + 342 342 1 0.0000000 2.1350000 7.0370000 14.8450000 + 343 343 1 0.0000000 10.1280000 17.9060000 5.2690000 + 344 344 1 0.0000000 9.9640000 11.7180000 21.3790000 + 345 345 1 0.0000000 3.9300000 18.4910000 10.9740000 + 346 346 1 0.0000000 4.4370000 0.9780000 3.9700000 + 347 347 1 0.0000000 3.3540000 11.6180000 13.2880000 + 348 348 1 0.0000000 10.1490000 8.5100000 18.7440000 + 349 349 1 0.0000000 20.0030000 12.0850000 0.6000000 + 350 350 1 0.0000000 8.1370000 7.5880000 17.8300000 + 351 351 1 0.0000000 4.9940000 4.9580000 9.5900000 + 352 352 1 0.0000000 5.3170000 14.3610000 19.8350000 + 353 353 1 0.0000000 9.3030000 10.0320000 5.0540000 + 354 354 1 0.0000000 15.9060000 19.0210000 11.2850000 + 355 355 1 0.0000000 4.7750000 3.1100000 20.1740000 + 356 356 1 0.0000000 12.3120000 9.1080000 6.4970000 + 357 357 1 0.0000000 10.4810000 4.6620000 17.6350000 + 358 358 1 0.0000000 4.7080000 13.6970000 16.3300000 + 359 359 1 0.0000000 12.2970000 5.5490000 6.5760000 + 360 360 1 0.0000000 17.9900000 5.6590000 1.9370000 + 361 361 1 0.0000000 15.7760000 13.0220000 8.3090000 + 362 362 1 0.0000000 17.0960000 9.8020000 6.8980000 + 363 363 1 0.0000000 14.4040000 20.5780000 7.1330000 + 364 364 1 0.0000000 10.5700000 7.4740000 12.5610000 + 365 365 1 0.0000000 7.1880000 17.4800000 12.1560000 + 366 366 1 0.0000000 19.2640000 6.6050000 0.0900000 + 367 367 1 0.0000000 2.4860000 20.3860000 7.9620000 + 368 368 1 0.0000000 1.6540000 17.4650000 21.0330000 + 369 369 1 0.0000000 0.8570000 14.9180000 7.7750000 + 370 370 1 0.0000000 15.6360000 3.0200000 12.0780000 + 371 371 1 0.0000000 20.9520000 6.0750000 16.1620000 + 372 372 1 0.0000000 6.5150000 10.9720000 15.0530000 + 373 373 1 0.0000000 1.6150000 2.1220000 0.1040000 + 374 374 1 0.0000000 12.4880000 14.7040000 1.3780000 + 375 375 1 0.0000000 1.8720000 14.8200000 18.2130000 + 376 376 1 0.0000000 1.3840000 6.3060000 16.9560000 + 377 377 1 0.0000000 13.1420000 8.3550000 21.5020000 + 378 378 1 0.0000000 10.3950000 19.1540000 12.7720000 + 379 379 1 0.0000000 18.9350000 15.8660000 19.2180000 + 380 380 1 0.0000000 19.6110000 0.3890000 20.4600000 + 381 381 1 0.0000000 1.6460000 14.9430000 1.9780000 + 382 382 1 0.0000000 16.9420000 8.7780000 9.0500000 + 383 383 1 0.0000000 15.0770000 11.3050000 19.7190000 + 384 384 1 0.0000000 6.2370000 17.3890000 15.8170000 + 385 385 1 0.0000000 14.6890000 16.8390000 8.2540000 + 386 386 1 0.0000000 5.9660000 6.4540000 15.1720000 + 387 387 1 0.0000000 6.1100000 4.8320000 21.2820000 + 388 388 1 0.0000000 5.9710000 14.6570000 4.7110000 + 389 389 1 0.0000000 3.1780000 19.7080000 5.8410000 + 390 390 1 0.0000000 5.7600000 19.5340000 14.8080000 + 391 391 1 0.0000000 18.1190000 11.5110000 15.1550000 + 392 392 1 0.0000000 17.0450000 3.0230000 19.5700000 + 393 393 1 0.0000000 11.7520000 21.8180000 19.7610000 + 394 394 1 0.0000000 15.5870000 18.5610000 6.9700000 + 395 395 1 0.0000000 6.0680000 8.8370000 18.0920000 + 396 396 1 0.0000000 14.2730000 18.8060000 21.1250000 + 397 397 1 0.0000000 14.8640000 7.7480000 18.0510000 + 398 398 1 0.0000000 7.1970000 14.3360000 8.4160000 + 399 399 1 0.0000000 12.4080000 8.9750000 12.3640000 + 400 400 1 0.0000000 15.7690000 0.5910000 7.2330000 + 401 401 1 0.0000000 14.1880000 18.6730000 16.7170000 + 402 402 1 0.0000000 0.1070000 17.0650000 14.8780000 + 403 403 1 0.0000000 1.2690000 21.0730000 19.1580000 + 404 404 1 0.0000000 8.3320000 15.5390000 0.1550000 + 405 405 1 0.0000000 3.4890000 20.2250000 18.9410000 + 406 406 1 0.0000000 16.7760000 7.8120000 16.6050000 + 407 407 1 0.0000000 0.5070000 4.7570000 5.2510000 + 408 408 1 0.0000000 19.1810000 3.0200000 9.7780000 + 409 409 1 0.0000000 4.7160000 9.7900000 16.3110000 + 410 410 1 0.0000000 2.4040000 18.9600000 12.6390000 + 411 411 1 0.0000000 3.3380000 4.6500000 7.9680000 + 412 412 1 0.0000000 17.7990000 4.9620000 9.4940000 + 413 413 1 0.0000000 12.7390000 16.3390000 11.5840000 + 414 414 1 0.0000000 17.5550000 6.7730000 20.3200000 + 415 415 1 0.0000000 14.1770000 9.8840000 3.2060000 + 416 416 1 0.0000000 14.4790000 10.5810000 15.6890000 + 417 417 1 0.0000000 14.7570000 21.0200000 10.8010000 + 418 418 1 0.0000000 19.6820000 0.5930000 12.8140000 + 419 419 1 0.0000000 8.6600000 0.3420000 21.6710000 + 420 420 1 0.0000000 9.6300000 4.0130000 11.4620000 + 421 421 1 0.0000000 21.1990000 7.8220000 3.8780000 + 422 422 1 0.0000000 1.0220000 15.3220000 20.3160000 + 423 423 1 0.0000000 19.5230000 9.5210000 18.2400000 + 424 424 1 0.0000000 6.0420000 4.8470000 1.8140000 + 425 425 1 0.0000000 19.0970000 2.7310000 20.7130000 + 426 426 1 0.0000000 20.7220000 12.9310000 18.9570000 + 427 427 1 0.0000000 12.0420000 5.2830000 19.3670000 + 428 428 1 0.0000000 12.3510000 14.1340000 10.8070000 + 429 429 1 0.0000000 0.6760000 0.6980000 4.6080000 + 430 430 1 0.0000000 17.9010000 21.6070000 7.6530000 + 431 431 1 0.0000000 12.9910000 4.6940000 10.9090000 + 432 432 1 0.0000000 4.1650000 0.3790000 10.2450000 + 433 433 1 0.0000000 11.0350000 2.5880000 2.7230000 + 434 434 1 0.0000000 0.8260000 16.8030000 9.2410000 + 435 435 1 0.0000000 1.2930000 1.5320000 19.6910000 + 436 436 1 0.0000000 3.6360000 0.6300000 7.9720000 + 437 437 1 0.0000000 18.7690000 21.6650000 18.3160000 + 438 438 1 0.0000000 15.9900000 1.2130000 10.5660000 + 439 439 1 0.0000000 3.6880000 0.2170000 17.3680000 + 440 440 1 0.0000000 15.4550000 13.7970000 16.7760000 + 441 441 1 0.0000000 13.6260000 0.3920000 16.0690000 + 442 442 1 0.0000000 2.2090000 7.7760000 18.5900000 + 443 443 1 0.0000000 7.5390000 1.2670000 1.6990000 + 444 444 1 0.0000000 5.8870000 7.1350000 20.9610000 + 445 445 1 0.0000000 3.5460000 9.4970000 8.9750000 + 446 446 1 0.0000000 1.7030000 10.1450000 12.4300000 + 447 447 1 0.0000000 4.5220000 7.2320000 19.0140000 + 448 448 1 0.0000000 12.0790000 18.5320000 17.7390000 + 449 449 1 0.0000000 11.8150000 12.7440000 20.4040000 + 450 450 1 0.0000000 14.1450000 16.3300000 20.6400000 + 451 451 1 0.0000000 13.9790000 11.9100000 13.7820000 + 452 452 1 0.0000000 5.7860000 9.0870000 8.2180000 + 453 453 1 0.0000000 5.7610000 18.5920000 3.4730000 + 454 454 1 0.0000000 17.1860000 12.2100000 20.2580000 + 455 455 1 0.0000000 19.9590000 17.8190000 5.1360000 + 456 456 1 0.0000000 17.0590000 15.4900000 5.5810000 + 457 457 1 0.0000000 3.6710000 3.1920000 4.2290000 + 458 458 1 0.0000000 9.3110000 4.4320000 0.2320000 + 459 459 1 0.0000000 7.2900000 10.5480000 9.3640000 + 460 460 1 0.0000000 3.1990000 11.3340000 19.5640000 + 461 461 1 0.0000000 18.7960000 19.0310000 15.8960000 + 462 462 1 0.0000000 16.4530000 21.1730000 18.6370000 + 463 463 1 0.0000000 19.0360000 1.4790000 16.6070000 + 464 464 1 0.0000000 15.1190000 6.7220000 5.0610000 + 465 465 1 0.0000000 14.6980000 6.3460000 10.8900000 + 466 466 1 0.0000000 9.5270000 15.6660000 5.6890000 + 467 467 1 0.0000000 9.8670000 0.7250000 18.4290000 + 468 468 1 0.0000000 3.5070000 11.8220000 15.5670000 + 469 469 1 0.0000000 5.2170000 0.8530000 1.6550000 + 470 470 1 0.0000000 14.2830000 11.9310000 17.5860000 + 471 471 1 0.0000000 21.4650000 11.2840000 8.7140000 + 472 472 1 0.0000000 0.2700000 13.5140000 17.1240000 + 473 473 1 0.0000000 8.7330000 20.7300000 17.4130000 + 474 474 1 0.0000000 7.4140000 12.9760000 3.8660000 + 475 475 1 0.0000000 8.5520000 8.7210000 12.3480000 + 476 476 1 0.0000000 7.4770000 9.7280000 1.7090000 + 477 477 1 0.0000000 16.9200000 14.6800000 20.0740000 + 478 478 1 0.0000000 6.5920000 20.9910000 6.6400000 + 479 479 1 0.0000000 18.3870000 7.4290000 18.2380000 + 480 480 1 0.0000000 21.2320000 15.1360000 2.5810000 + 481 481 1 0.0000000 16.7390000 8.6780000 21.4380000 + 482 482 1 0.0000000 18.2260000 6.2380000 5.6140000 + 483 483 1 0.0000000 12.7550000 3.5820000 20.8720000 + 484 484 1 0.0000000 14.8870000 9.0010000 20.0300000 + 485 485 1 0.0000000 6.1970000 16.3000000 3.0880000 + 486 486 1 0.0000000 6.9450000 13.1810000 15.8140000 + 487 487 1 0.0000000 20.1770000 18.7700000 1.5020000 + 488 488 1 0.0000000 19.8750000 14.4220000 0.7710000 + 489 489 1 0.0000000 13.0770000 5.0280000 14.9330000 + 490 490 1 0.0000000 10.9540000 0.5380000 0.0170000 + 491 491 1 0.0000000 0.3310000 3.0520000 18.1720000 + 492 492 1 0.0000000 8.8200000 14.8310000 10.0110000 + 493 493 1 0.0000000 6.9570000 20.3870000 8.9230000 + 494 494 1 0.0000000 21.4900000 6.8560000 12.0490000 + 495 495 1 0.0000000 8.1550000 13.1990000 21.7210000 + 496 496 1 0.0000000 2.1970000 4.5290000 11.8290000 + 497 497 1 0.0000000 14.2880000 5.5560000 18.5960000 + 498 498 1 0.0000000 15.0910000 15.4110000 18.5470000 + 499 499 1 0.0000000 18.9760000 15.1930000 16.8970000 + 500 500 1 0.0000000 19.4100000 5.3490000 17.7540000 + 501 501 1 0.0000000 0.5430000 8.3990000 13.7700000 + 502 502 1 0.0000000 18.0770000 19.1690000 4.8770000 + 503 503 1 0.0000000 3.3760000 17.8650000 19.2940000 + 504 504 1 0.0000000 16.3760000 0.5870000 3.6340000 + 505 505 1 0.0000000 10.4990000 18.5190000 21.1770000 + 506 506 1 0.0000000 15.7320000 12.7570000 3.0200000 + 507 507 1 0.0000000 16.9190000 8.1780000 5.2430000 + 508 508 1 0.0000000 6.9450000 7.4210000 6.8040000 + 509 509 1 0.0000000 11.6120000 21.2610000 15.3620000 + 510 510 1 0.0000000 18.0500000 0.6840000 14.5470000 + 511 511 1 0.0000000 20.4340000 4.0240000 4.2040000 + 512 512 1 0.0000000 18.0190000 10.7210000 0.2160000 + diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_216.lmp b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_216.lmp new file mode 100755 index 0000000000..893d75e69b --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_216.lmp @@ -0,0 +1,238 @@ +LAMMPS description + + 216 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 16.293000 xlo xhi + 0.0000000 16.293000 ylo yhi + 0.0000000 16.293000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 0.0000000 2.7160000 2.7160000 + 3 3 1 0.0000000 2.7160000 2.7160000 0.0000000 + 4 4 1 0.0000000 2.7160000 0.0000000 2.7160000 + 5 5 1 0.0000000 4.0730000 1.3580000 4.0730000 + 6 6 1 0.0000000 1.3580000 1.3580000 1.3580000 + 7 7 1 0.0000000 1.3580000 4.0730000 4.0730000 + 8 8 1 0.0000000 4.0730000 4.0730000 1.3580000 + 9 9 1 0.0000000 0.0000000 0.0000000 5.4310000 + 10 10 1 0.0000000 0.0000000 2.7160000 8.1460000 + 11 11 1 0.0000000 2.7160000 2.7160000 5.4310000 + 12 12 1 0.0000000 2.7160000 0.0000000 8.1460000 + 13 13 1 0.0000000 4.0730000 1.3580000 9.5040000 + 14 14 1 0.0000000 1.3580000 1.3580000 6.7890000 + 15 15 1 0.0000000 1.3580000 4.0730000 9.5040000 + 16 16 1 0.0000000 4.0730000 4.0730000 6.7890000 + 17 17 1 0.0000000 0.0000000 0.0000000 10.8620000 + 18 18 1 0.0000000 0.0000000 2.7160000 13.5780000 + 19 19 1 0.0000000 2.7160000 2.7160000 10.8620000 + 20 20 1 0.0000000 2.7160000 0.0000000 13.5780000 + 21 21 1 0.0000000 4.0730000 1.3580000 14.9350000 + 22 22 1 0.0000000 1.3580000 1.3580000 12.2200000 + 23 23 1 0.0000000 1.3580000 4.0730000 14.9350000 + 24 24 1 0.0000000 4.0730000 4.0730000 12.2200000 + 25 25 1 0.0000000 0.0000000 5.4310000 0.0000000 + 26 26 1 0.0000000 0.0000000 8.1460000 2.7160000 + 27 27 1 0.0000000 2.7160000 8.1460000 0.0000000 + 28 28 1 0.0000000 2.7160000 5.4310000 2.7160000 + 29 29 1 0.0000000 4.0730000 6.7890000 4.0730000 + 30 30 1 0.0000000 1.3580000 6.7890000 1.3580000 + 31 31 1 0.0000000 1.3580000 9.5040000 4.0730000 + 32 32 1 0.0000000 4.0730000 9.5040000 1.3580000 + 33 33 1 0.0000000 0.0000000 5.4310000 5.4310000 + 34 34 1 0.0000000 0.0000000 8.1460000 8.1460000 + 35 35 1 0.0000000 2.7160000 8.1460000 5.4310000 + 36 36 1 0.0000000 2.7160000 5.4310000 8.1460000 + 37 37 1 0.0000000 4.0730000 6.7890000 9.5040000 + 38 38 1 0.0000000 1.3580000 6.7890000 6.7890000 + 39 39 1 0.0000000 1.3580000 9.5040000 9.5040000 + 40 40 1 0.0000000 4.0730000 9.5040000 6.7890000 + 41 41 1 0.0000000 0.0000000 5.4310000 10.8620000 + 42 42 1 0.0000000 0.0000000 8.1460000 13.5780000 + 43 43 1 0.0000000 2.7160000 8.1460000 10.8620000 + 44 44 1 0.0000000 2.7160000 5.4310000 13.5780000 + 45 45 1 0.0000000 4.0730000 6.7890000 14.9350000 + 46 46 1 0.0000000 1.3580000 6.7890000 12.2200000 + 47 47 1 0.0000000 1.3580000 9.5040000 14.9350000 + 48 48 1 0.0000000 4.0730000 9.5040000 12.2200000 + 49 49 1 0.0000000 0.0000000 10.8620000 0.0000000 + 50 50 1 0.0000000 0.0000000 13.5780000 2.7160000 + 51 51 1 0.0000000 2.7160000 13.5780000 0.0000000 + 52 52 1 0.0000000 2.7160000 10.8620000 2.7160000 + 53 53 1 0.0000000 4.0730000 12.2200000 4.0730000 + 54 54 1 0.0000000 1.3580000 12.2200000 1.3580000 + 55 55 1 0.0000000 1.3580000 14.9350000 4.0730000 + 56 56 1 0.0000000 4.0730000 14.9350000 1.3580000 + 57 57 1 0.0000000 0.0000000 10.8620000 5.4310000 + 58 58 1 0.0000000 0.0000000 13.5780000 8.1460000 + 59 59 1 0.0000000 2.7160000 13.5780000 5.4310000 + 60 60 1 0.0000000 2.7160000 10.8620000 8.1460000 + 61 61 1 0.0000000 4.0730000 12.2200000 9.5040000 + 62 62 1 0.0000000 1.3580000 12.2200000 6.7890000 + 63 63 1 0.0000000 1.3580000 14.9350000 9.5040000 + 64 64 1 0.0000000 4.0730000 14.9350000 6.7890000 + 65 65 1 0.0000000 0.0000000 10.8620000 10.8620000 + 66 66 1 0.0000000 0.0000000 13.5780000 13.5780000 + 67 67 1 0.0000000 2.7160000 13.5780000 10.8620000 + 68 68 1 0.0000000 2.7160000 10.8620000 13.5780000 + 69 69 1 0.0000000 4.0730000 12.2200000 14.9350000 + 70 70 1 0.0000000 1.3580000 12.2200000 12.2200000 + 71 71 1 0.0000000 1.3580000 14.9350000 14.9350000 + 72 72 1 0.0000000 4.0730000 14.9350000 12.2200000 + 73 73 1 0.0000000 5.4310000 0.0000000 0.0000000 + 74 74 1 0.0000000 5.4310000 2.7160000 2.7160000 + 75 75 1 0.0000000 8.1460000 2.7160000 0.0000000 + 76 76 1 0.0000000 8.1460000 0.0000000 2.7160000 + 77 77 1 0.0000000 9.5040000 1.3580000 4.0730000 + 78 78 1 0.0000000 6.7890000 1.3580000 1.3580000 + 79 79 1 0.0000000 6.7890000 4.0730000 4.0730000 + 80 80 1 0.0000000 9.5040000 4.0730000 1.3580000 + 81 81 1 0.0000000 5.4310000 0.0000000 5.4310000 + 82 82 1 0.0000000 5.4310000 2.7160000 8.1460000 + 83 83 1 0.0000000 8.1460000 2.7160000 5.4310000 + 84 84 1 0.0000000 8.1460000 0.0000000 8.1460000 + 85 85 1 0.0000000 9.5040000 1.3580000 9.5040000 + 86 86 1 0.0000000 6.7890000 1.3580000 6.7890000 + 87 87 1 0.0000000 6.7890000 4.0730000 9.5040000 + 88 88 1 0.0000000 9.5040000 4.0730000 6.7890000 + 89 89 1 0.0000000 5.4310000 0.0000000 10.8620000 + 90 90 1 0.0000000 5.4310000 2.7160000 13.5780000 + 91 91 1 0.0000000 8.1460000 2.7160000 10.8620000 + 92 92 1 0.0000000 8.1460000 0.0000000 13.5780000 + 93 93 1 0.0000000 9.5040000 1.3580000 14.9350000 + 94 94 1 0.0000000 6.7890000 1.3580000 12.2200000 + 95 95 1 0.0000000 6.7890000 4.0730000 14.9350000 + 96 96 1 0.0000000 9.5040000 4.0730000 12.2200000 + 97 97 1 0.0000000 5.4310000 5.4310000 0.0000000 + 98 98 1 0.0000000 5.4310000 8.1460000 2.7160000 + 99 99 1 0.0000000 8.1460000 8.1460000 0.0000000 + 100 100 1 0.0000000 8.1460000 5.4310000 2.7160000 + 101 101 1 0.0000000 9.5040000 6.7890000 4.0730000 + 102 102 1 0.0000000 6.7890000 6.7890000 1.3580000 + 103 103 1 0.0000000 6.7890000 9.5040000 4.0730000 + 104 104 1 0.0000000 9.5040000 9.5040000 1.3580000 + 105 105 1 0.0000000 5.4310000 5.4310000 5.4310000 + 106 106 1 0.0000000 5.4310000 8.1460000 8.1460000 + 107 107 1 0.0000000 8.1460000 8.1460000 5.4310000 + 108 108 1 0.0000000 8.1460000 5.4310000 8.1460000 + 109 109 1 0.0000000 9.5040000 6.7890000 9.5040000 + 110 110 1 0.0000000 6.7890000 6.7890000 6.7890000 + 111 111 1 0.0000000 6.7890000 9.5040000 9.5040000 + 112 112 1 0.0000000 9.5040000 9.5040000 6.7890000 + 113 113 1 0.0000000 5.4310000 5.4310000 10.8620000 + 114 114 1 0.0000000 5.4310000 8.1460000 13.5780000 + 115 115 1 0.0000000 8.1460000 8.1460000 10.8620000 + 116 116 1 0.0000000 8.1460000 5.4310000 13.5780000 + 117 117 1 0.0000000 9.5040000 6.7890000 14.9350000 + 118 118 1 0.0000000 6.7890000 6.7890000 12.2200000 + 119 119 1 0.0000000 6.7890000 9.5040000 14.9350000 + 120 120 1 0.0000000 9.5040000 9.5040000 12.2200000 + 121 121 1 0.0000000 5.4310000 10.8620000 0.0000000 + 122 122 1 0.0000000 5.4310000 13.5780000 2.7160000 + 123 123 1 0.0000000 8.1460000 13.5780000 0.0000000 + 124 124 1 0.0000000 8.1460000 10.8620000 2.7160000 + 125 125 1 0.0000000 9.5040000 12.2200000 4.0730000 + 126 126 1 0.0000000 6.7890000 12.2200000 1.3580000 + 127 127 1 0.0000000 6.7890000 14.9350000 4.0730000 + 128 128 1 0.0000000 9.5040000 14.9350000 1.3580000 + 129 129 1 0.0000000 5.4310000 10.8620000 5.4310000 + 130 130 1 0.0000000 5.4310000 13.5780000 8.1460000 + 131 131 1 0.0000000 8.1460000 13.5780000 5.4310000 + 132 132 1 0.0000000 8.1460000 10.8620000 8.1460000 + 133 133 1 0.0000000 9.5040000 12.2200000 9.5040000 + 134 134 1 0.0000000 6.7890000 12.2200000 6.7890000 + 135 135 1 0.0000000 6.7890000 14.9350000 9.5040000 + 136 136 1 0.0000000 9.5040000 14.9350000 6.7890000 + 137 137 1 0.0000000 5.4310000 10.8620000 10.8620000 + 138 138 1 0.0000000 5.4310000 13.5780000 13.5780000 + 139 139 1 0.0000000 8.1460000 13.5780000 10.8620000 + 140 140 1 0.0000000 8.1460000 10.8620000 13.5780000 + 141 141 1 0.0000000 9.5040000 12.2200000 14.9350000 + 142 142 1 0.0000000 6.7890000 12.2200000 12.2200000 + 143 143 1 0.0000000 6.7890000 14.9350000 14.9350000 + 144 144 1 0.0000000 9.5040000 14.9350000 12.2200000 + 145 145 1 0.0000000 10.8620000 0.0000000 0.0000000 + 146 146 1 0.0000000 10.8620000 2.7160000 2.7160000 + 147 147 1 0.0000000 13.5780000 2.7160000 0.0000000 + 148 148 1 0.0000000 13.5780000 0.0000000 2.7160000 + 149 149 1 0.0000000 14.9350000 1.3580000 4.0730000 + 150 150 1 0.0000000 12.2200000 1.3580000 1.3580000 + 151 151 1 0.0000000 12.2200000 4.0730000 4.0730000 + 152 152 1 0.0000000 14.9350000 4.0730000 1.3580000 + 153 153 1 0.0000000 10.8620000 0.0000000 5.4310000 + 154 154 1 0.0000000 10.8620000 2.7160000 8.1460000 + 155 155 1 0.0000000 13.5780000 2.7160000 5.4310000 + 156 156 1 0.0000000 13.5780000 0.0000000 8.1460000 + 157 157 1 0.0000000 14.9350000 1.3580000 9.5040000 + 158 158 1 0.0000000 12.2200000 1.3580000 6.7890000 + 159 159 1 0.0000000 12.2200000 4.0730000 9.5040000 + 160 160 1 0.0000000 14.9350000 4.0730000 6.7890000 + 161 161 1 0.0000000 10.8620000 0.0000000 10.8620000 + 162 162 1 0.0000000 10.8620000 2.7160000 13.5780000 + 163 163 1 0.0000000 13.5780000 2.7160000 10.8620000 + 164 164 1 0.0000000 13.5780000 0.0000000 13.5780000 + 165 165 1 0.0000000 14.9350000 1.3580000 14.9350000 + 166 166 1 0.0000000 12.2200000 1.3580000 12.2200000 + 167 167 1 0.0000000 12.2200000 4.0730000 14.9350000 + 168 168 1 0.0000000 14.9350000 4.0730000 12.2200000 + 169 169 1 0.0000000 10.8620000 5.4310000 0.0000000 + 170 170 1 0.0000000 10.8620000 8.1460000 2.7160000 + 171 171 1 0.0000000 13.5780000 8.1460000 0.0000000 + 172 172 1 0.0000000 13.5780000 5.4310000 2.7160000 + 173 173 1 0.0000000 14.9350000 6.7890000 4.0730000 + 174 174 1 0.0000000 12.2200000 6.7890000 1.3580000 + 175 175 1 0.0000000 12.2200000 9.5040000 4.0730000 + 176 176 1 0.0000000 14.9350000 9.5040000 1.3580000 + 177 177 1 0.0000000 10.8620000 5.4310000 5.4310000 + 178 178 1 0.0000000 10.8620000 8.1460000 8.1460000 + 179 179 1 0.0000000 13.5780000 8.1460000 5.4310000 + 180 180 1 0.0000000 13.5780000 5.4310000 8.1460000 + 181 181 1 0.0000000 14.9350000 6.7890000 9.5040000 + 182 182 1 0.0000000 12.2200000 6.7890000 6.7890000 + 183 183 1 0.0000000 12.2200000 9.5040000 9.5040000 + 184 184 1 0.0000000 14.9350000 9.5040000 6.7890000 + 185 185 1 0.0000000 10.8620000 5.4310000 10.8620000 + 186 186 1 0.0000000 10.8620000 8.1460000 13.5780000 + 187 187 1 0.0000000 13.5780000 8.1460000 10.8620000 + 188 188 1 0.0000000 13.5780000 5.4310000 13.5780000 + 189 189 1 0.0000000 14.9350000 6.7890000 14.9350000 + 190 190 1 0.0000000 12.2200000 6.7890000 12.2200000 + 191 191 1 0.0000000 12.2200000 9.5040000 14.9350000 + 192 192 1 0.0000000 14.9350000 9.5040000 12.2200000 + 193 193 1 0.0000000 10.8620000 10.8620000 0.0000000 + 194 194 1 0.0000000 10.8620000 13.5780000 2.7160000 + 195 195 1 0.0000000 13.5780000 13.5780000 0.0000000 + 196 196 1 0.0000000 13.5780000 10.8620000 2.7160000 + 197 197 1 0.0000000 14.9350000 12.2200000 4.0730000 + 198 198 1 0.0000000 12.2200000 12.2200000 1.3580000 + 199 199 1 0.0000000 12.2200000 14.9350000 4.0730000 + 200 200 1 0.0000000 14.9350000 14.9350000 1.3580000 + 201 201 1 0.0000000 10.8620000 10.8620000 5.4310000 + 202 202 1 0.0000000 10.8620000 13.5780000 8.1460000 + 203 203 1 0.0000000 13.5780000 13.5780000 5.4310000 + 204 204 1 0.0000000 13.5780000 10.8620000 8.1460000 + 205 205 1 0.0000000 14.9350000 12.2200000 9.5040000 + 206 206 1 0.0000000 12.2200000 12.2200000 6.7890000 + 207 207 1 0.0000000 12.2200000 14.9350000 9.5040000 + 208 208 1 0.0000000 14.9350000 14.9350000 6.7890000 + 209 209 1 0.0000000 10.8620000 10.8620000 10.8620000 + 210 210 1 0.0000000 10.8620000 13.5780000 13.5780000 + 211 211 1 0.0000000 13.5780000 13.5780000 10.8620000 + 212 212 1 0.0000000 13.5780000 10.8620000 13.5780000 + 213 213 1 0.0000000 14.9350000 12.2200000 14.9350000 + 214 214 1 0.0000000 12.2200000 12.2200000 12.2200000 + 215 215 1 0.0000000 12.2200000 14.9350000 14.9350000 + 216 216 1 0.0000000 14.9350000 14.9350000 12.2200000 + diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_512.lmp b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_512.lmp new file mode 100755 index 0000000000..8c1ecd30bd --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_512.lmp @@ -0,0 +1,534 @@ +LAMMPS description + + 512 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 21.724000 xlo xhi + 0.0000000 21.724000 ylo yhi + 0.0000000 21.724000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 0.0000000 2.7150000 2.7150000 + 3 3 1 0.0000000 2.7150000 2.7150000 0.0000000 + 4 4 1 0.0000000 2.7150000 0.0000000 2.7150000 + 5 5 1 0.0000000 4.0730000 1.3580000 4.0730000 + 6 6 1 0.0000000 1.3580000 1.3580000 1.3580000 + 7 7 1 0.0000000 1.3580000 4.0730000 4.0730000 + 8 8 1 0.0000000 4.0730000 4.0730000 1.3580000 + 9 9 1 0.0000000 0.0000000 0.0000000 5.4310000 + 10 10 1 0.0000000 0.0000000 2.7150000 8.1460000 + 11 11 1 0.0000000 2.7150000 2.7150000 5.4310000 + 12 12 1 0.0000000 2.7150000 0.0000000 8.1460000 + 13 13 1 0.0000000 4.0730000 1.3580000 9.5040000 + 14 14 1 0.0000000 1.3580000 1.3580000 6.7890000 + 15 15 1 0.0000000 1.3580000 4.0730000 9.5040000 + 16 16 1 0.0000000 4.0730000 4.0730000 6.7890000 + 17 17 1 0.0000000 0.0000000 0.0000000 10.8620000 + 18 18 1 0.0000000 0.0000000 2.7150000 13.5770000 + 19 19 1 0.0000000 2.7150000 2.7150000 10.8620000 + 20 20 1 0.0000000 2.7150000 0.0000000 13.5770000 + 21 21 1 0.0000000 4.0730000 1.3580000 14.9350000 + 22 22 1 0.0000000 1.3580000 1.3580000 12.2200000 + 23 23 1 0.0000000 1.3580000 4.0730000 14.9350000 + 24 24 1 0.0000000 4.0730000 4.0730000 12.2200000 + 25 25 1 0.0000000 0.0000000 0.0000000 16.2930000 + 26 26 1 0.0000000 0.0000000 2.7150000 19.0080000 + 27 27 1 0.0000000 2.7150000 2.7150000 16.2930000 + 28 28 1 0.0000000 2.7150000 0.0000000 19.0080000 + 29 29 1 0.0000000 4.0730000 1.3580000 20.3660000 + 30 30 1 0.0000000 1.3580000 1.3580000 17.6510000 + 31 31 1 0.0000000 1.3580000 4.0730000 20.3660000 + 32 32 1 0.0000000 4.0730000 4.0730000 17.6510000 + 33 33 1 0.0000000 0.0000000 5.4310000 0.0000000 + 34 34 1 0.0000000 0.0000000 8.1460000 2.7150000 + 35 35 1 0.0000000 2.7150000 8.1460000 0.0000000 + 36 36 1 0.0000000 2.7150000 5.4310000 2.7150000 + 37 37 1 0.0000000 4.0730000 6.7890000 4.0730000 + 38 38 1 0.0000000 1.3580000 6.7890000 1.3580000 + 39 39 1 0.0000000 1.3580000 9.5040000 4.0730000 + 40 40 1 0.0000000 4.0730000 9.5040000 1.3580000 + 41 41 1 0.0000000 0.0000000 5.4310000 5.4310000 + 42 42 1 0.0000000 0.0000000 8.1460000 8.1460000 + 43 43 1 0.0000000 2.7150000 8.1460000 5.4310000 + 44 44 1 0.0000000 2.7150000 5.4310000 8.1460000 + 45 45 1 0.0000000 4.0730000 6.7890000 9.5040000 + 46 46 1 0.0000000 1.3580000 6.7890000 6.7890000 + 47 47 1 0.0000000 1.3580000 9.5040000 9.5040000 + 48 48 1 0.0000000 4.0730000 9.5040000 6.7890000 + 49 49 1 0.0000000 0.0000000 5.4310000 10.8620000 + 50 50 1 0.0000000 0.0000000 8.1460000 13.5770000 + 51 51 1 0.0000000 2.7150000 8.1460000 10.8620000 + 52 52 1 0.0000000 2.7150000 5.4310000 13.5770000 + 53 53 1 0.0000000 4.0730000 6.7890000 14.9350000 + 54 54 1 0.0000000 1.3580000 6.7890000 12.2200000 + 55 55 1 0.0000000 1.3580000 9.5040000 14.9350000 + 56 56 1 0.0000000 4.0730000 9.5040000 12.2200000 + 57 57 1 0.0000000 0.0000000 5.4310000 16.2930000 + 58 58 1 0.0000000 0.0000000 8.1460000 19.0080000 + 59 59 1 0.0000000 2.7150000 8.1460000 16.2930000 + 60 60 1 0.0000000 2.7150000 5.4310000 19.0080000 + 61 61 1 0.0000000 4.0730000 6.7890000 20.3660000 + 62 62 1 0.0000000 1.3580000 6.7890000 17.6510000 + 63 63 1 0.0000000 1.3580000 9.5040000 20.3660000 + 64 64 1 0.0000000 4.0730000 9.5040000 17.6510000 + 65 65 1 0.0000000 0.0000000 10.8620000 0.0000000 + 66 66 1 0.0000000 0.0000000 13.5770000 2.7150000 + 67 67 1 0.0000000 2.7150000 13.5770000 0.0000000 + 68 68 1 0.0000000 2.7150000 10.8620000 2.7150000 + 69 69 1 0.0000000 4.0730000 12.2200000 4.0730000 + 70 70 1 0.0000000 1.3580000 12.2200000 1.3580000 + 71 71 1 0.0000000 1.3580000 14.9350000 4.0730000 + 72 72 1 0.0000000 4.0730000 14.9350000 1.3580000 + 73 73 1 0.0000000 0.0000000 10.8620000 5.4310000 + 74 74 1 0.0000000 0.0000000 13.5770000 8.1460000 + 75 75 1 0.0000000 2.7150000 13.5770000 5.4310000 + 76 76 1 0.0000000 2.7150000 10.8620000 8.1460000 + 77 77 1 0.0000000 4.0730000 12.2200000 9.5040000 + 78 78 1 0.0000000 1.3580000 12.2200000 6.7890000 + 79 79 1 0.0000000 1.3580000 14.9350000 9.5040000 + 80 80 1 0.0000000 4.0730000 14.9350000 6.7890000 + 81 81 1 0.0000000 0.0000000 10.8620000 10.8620000 + 82 82 1 0.0000000 0.0000000 13.5770000 13.5770000 + 83 83 1 0.0000000 2.7150000 13.5770000 10.8620000 + 84 84 1 0.0000000 2.7150000 10.8620000 13.5770000 + 85 85 1 0.0000000 4.0730000 12.2200000 14.9350000 + 86 86 1 0.0000000 1.3580000 12.2200000 12.2200000 + 87 87 1 0.0000000 1.3580000 14.9350000 14.9350000 + 88 88 1 0.0000000 4.0730000 14.9350000 12.2200000 + 89 89 1 0.0000000 0.0000000 10.8620000 16.2930000 + 90 90 1 0.0000000 0.0000000 13.5770000 19.0080000 + 91 91 1 0.0000000 2.7150000 13.5770000 16.2930000 + 92 92 1 0.0000000 2.7150000 10.8620000 19.0080000 + 93 93 1 0.0000000 4.0730000 12.2200000 20.3660000 + 94 94 1 0.0000000 1.3580000 12.2200000 17.6510000 + 95 95 1 0.0000000 1.3580000 14.9350000 20.3660000 + 96 96 1 0.0000000 4.0730000 14.9350000 17.6510000 + 97 97 1 0.0000000 0.0000000 16.2930000 0.0000000 + 98 98 1 0.0000000 0.0000000 19.0080000 2.7150000 + 99 99 1 0.0000000 2.7150000 19.0080000 0.0000000 + 100 100 1 0.0000000 2.7150000 16.2930000 2.7150000 + 101 101 1 0.0000000 4.0730000 17.6510000 4.0730000 + 102 102 1 0.0000000 1.3580000 17.6510000 1.3580000 + 103 103 1 0.0000000 1.3580000 20.3660000 4.0730000 + 104 104 1 0.0000000 4.0730000 20.3660000 1.3580000 + 105 105 1 0.0000000 0.0000000 16.2930000 5.4310000 + 106 106 1 0.0000000 0.0000000 19.0080000 8.1460000 + 107 107 1 0.0000000 2.7150000 19.0080000 5.4310000 + 108 108 1 0.0000000 2.7150000 16.2930000 8.1460000 + 109 109 1 0.0000000 4.0730000 17.6510000 9.5040000 + 110 110 1 0.0000000 1.3580000 17.6510000 6.7890000 + 111 111 1 0.0000000 1.3580000 20.3660000 9.5040000 + 112 112 1 0.0000000 4.0730000 20.3660000 6.7890000 + 113 113 1 0.0000000 0.0000000 16.2930000 10.8620000 + 114 114 1 0.0000000 0.0000000 19.0080000 13.5770000 + 115 115 1 0.0000000 2.7150000 19.0080000 10.8620000 + 116 116 1 0.0000000 2.7150000 16.2930000 13.5770000 + 117 117 1 0.0000000 4.0730000 17.6510000 14.9350000 + 118 118 1 0.0000000 1.3580000 17.6510000 12.2200000 + 119 119 1 0.0000000 1.3580000 20.3660000 14.9350000 + 120 120 1 0.0000000 4.0730000 20.3660000 12.2200000 + 121 121 1 0.0000000 0.0000000 16.2930000 16.2930000 + 122 122 1 0.0000000 0.0000000 19.0080000 19.0080000 + 123 123 1 0.0000000 2.7150000 19.0080000 16.2930000 + 124 124 1 0.0000000 2.7150000 16.2930000 19.0080000 + 125 125 1 0.0000000 4.0730000 17.6510000 20.3660000 + 126 126 1 0.0000000 1.3580000 17.6510000 17.6510000 + 127 127 1 0.0000000 1.3580000 20.3660000 20.3660000 + 128 128 1 0.0000000 4.0730000 20.3660000 17.6510000 + 129 129 1 0.0000000 5.4310000 0.0000000 0.0000000 + 130 130 1 0.0000000 5.4310000 2.7150000 2.7150000 + 131 131 1 0.0000000 8.1460000 2.7150000 0.0000000 + 132 132 1 0.0000000 8.1460000 0.0000000 2.7150000 + 133 133 1 0.0000000 9.5040000 1.3580000 4.0730000 + 134 134 1 0.0000000 6.7890000 1.3580000 1.3580000 + 135 135 1 0.0000000 6.7890000 4.0730000 4.0730000 + 136 136 1 0.0000000 9.5040000 4.0730000 1.3580000 + 137 137 1 0.0000000 5.4310000 0.0000000 5.4310000 + 138 138 1 0.0000000 5.4310000 2.7150000 8.1460000 + 139 139 1 0.0000000 8.1460000 2.7150000 5.4310000 + 140 140 1 0.0000000 8.1460000 0.0000000 8.1460000 + 141 141 1 0.0000000 9.5040000 1.3580000 9.5040000 + 142 142 1 0.0000000 6.7890000 1.3580000 6.7890000 + 143 143 1 0.0000000 6.7890000 4.0730000 9.5040000 + 144 144 1 0.0000000 9.5040000 4.0730000 6.7890000 + 145 145 1 0.0000000 5.4310000 0.0000000 10.8620000 + 146 146 1 0.0000000 5.4310000 2.7150000 13.5770000 + 147 147 1 0.0000000 8.1460000 2.7150000 10.8620000 + 148 148 1 0.0000000 8.1460000 0.0000000 13.5770000 + 149 149 1 0.0000000 9.5040000 1.3580000 14.9350000 + 150 150 1 0.0000000 6.7890000 1.3580000 12.2200000 + 151 151 1 0.0000000 6.7890000 4.0730000 14.9350000 + 152 152 1 0.0000000 9.5040000 4.0730000 12.2200000 + 153 153 1 0.0000000 5.4310000 0.0000000 16.2930000 + 154 154 1 0.0000000 5.4310000 2.7150000 19.0080000 + 155 155 1 0.0000000 8.1460000 2.7150000 16.2930000 + 156 156 1 0.0000000 8.1460000 0.0000000 19.0080000 + 157 157 1 0.0000000 9.5040000 1.3580000 20.3660000 + 158 158 1 0.0000000 6.7890000 1.3580000 17.6510000 + 159 159 1 0.0000000 6.7890000 4.0730000 20.3660000 + 160 160 1 0.0000000 9.5040000 4.0730000 17.6510000 + 161 161 1 0.0000000 5.4310000 5.4310000 0.0000000 + 162 162 1 0.0000000 5.4310000 8.1460000 2.7150000 + 163 163 1 0.0000000 8.1460000 8.1460000 0.0000000 + 164 164 1 0.0000000 8.1460000 5.4310000 2.7150000 + 165 165 1 0.0000000 9.5040000 6.7890000 4.0730000 + 166 166 1 0.0000000 6.7890000 6.7890000 1.3580000 + 167 167 1 0.0000000 6.7890000 9.5040000 4.0730000 + 168 168 1 0.0000000 9.5040000 9.5040000 1.3580000 + 169 169 1 0.0000000 5.4310000 5.4310000 5.4310000 + 170 170 1 0.0000000 5.4310000 8.1460000 8.1460000 + 171 171 1 0.0000000 8.1460000 8.1460000 5.4310000 + 172 172 1 0.0000000 8.1460000 5.4310000 8.1460000 + 173 173 1 0.0000000 9.5040000 6.7890000 9.5040000 + 174 174 1 0.0000000 6.7890000 6.7890000 6.7890000 + 175 175 1 0.0000000 6.7890000 9.5040000 9.5040000 + 176 176 1 0.0000000 9.5040000 9.5040000 6.7890000 + 177 177 1 0.0000000 5.4310000 5.4310000 10.8620000 + 178 178 1 0.0000000 5.4310000 8.1460000 13.5770000 + 179 179 1 0.0000000 8.1460000 8.1460000 10.8620000 + 180 180 1 0.0000000 8.1460000 5.4310000 13.5770000 + 181 181 1 0.0000000 9.5040000 6.7890000 14.9350000 + 182 182 1 0.0000000 6.7890000 6.7890000 12.2200000 + 183 183 1 0.0000000 6.7890000 9.5040000 14.9350000 + 184 184 1 0.0000000 9.5040000 9.5040000 12.2200000 + 185 185 1 0.0000000 5.4310000 5.4310000 16.2930000 + 186 186 1 0.0000000 5.4310000 8.1460000 19.0080000 + 187 187 1 0.0000000 8.1460000 8.1460000 16.2930000 + 188 188 1 0.0000000 8.1460000 5.4310000 19.0080000 + 189 189 1 0.0000000 9.5040000 6.7890000 20.3660000 + 190 190 1 0.0000000 6.7890000 6.7890000 17.6510000 + 191 191 1 0.0000000 6.7890000 9.5040000 20.3660000 + 192 192 1 0.0000000 9.5040000 9.5040000 17.6510000 + 193 193 1 0.0000000 5.4310000 10.8620000 0.0000000 + 194 194 1 0.0000000 5.4310000 13.5770000 2.7150000 + 195 195 1 0.0000000 8.1460000 13.5770000 0.0000000 + 196 196 1 0.0000000 8.1460000 10.8620000 2.7150000 + 197 197 1 0.0000000 9.5040000 12.2200000 4.0730000 + 198 198 1 0.0000000 6.7890000 12.2200000 1.3580000 + 199 199 1 0.0000000 6.7890000 14.9350000 4.0730000 + 200 200 1 0.0000000 9.5040000 14.9350000 1.3580000 + 201 201 1 0.0000000 5.4310000 10.8620000 5.4310000 + 202 202 1 0.0000000 5.4310000 13.5770000 8.1460000 + 203 203 1 0.0000000 8.1460000 13.5770000 5.4310000 + 204 204 1 0.0000000 8.1460000 10.8620000 8.1460000 + 205 205 1 0.0000000 9.5040000 12.2200000 9.5040000 + 206 206 1 0.0000000 6.7890000 12.2200000 6.7890000 + 207 207 1 0.0000000 6.7890000 14.9350000 9.5040000 + 208 208 1 0.0000000 9.5040000 14.9350000 6.7890000 + 209 209 1 0.0000000 5.4310000 10.8620000 10.8620000 + 210 210 1 0.0000000 5.4310000 13.5770000 13.5770000 + 211 211 1 0.0000000 8.1460000 13.5770000 10.8620000 + 212 212 1 0.0000000 8.1460000 10.8620000 13.5770000 + 213 213 1 0.0000000 9.5040000 12.2200000 14.9350000 + 214 214 1 0.0000000 6.7890000 12.2200000 12.2200000 + 215 215 1 0.0000000 6.7890000 14.9350000 14.9350000 + 216 216 1 0.0000000 9.5040000 14.9350000 12.2200000 + 217 217 1 0.0000000 5.4310000 10.8620000 16.2930000 + 218 218 1 0.0000000 5.4310000 13.5770000 19.0080000 + 219 219 1 0.0000000 8.1460000 13.5770000 16.2930000 + 220 220 1 0.0000000 8.1460000 10.8620000 19.0080000 + 221 221 1 0.0000000 9.5040000 12.2200000 20.3660000 + 222 222 1 0.0000000 6.7890000 12.2200000 17.6510000 + 223 223 1 0.0000000 6.7890000 14.9350000 20.3660000 + 224 224 1 0.0000000 9.5040000 14.9350000 17.6510000 + 225 225 1 0.0000000 5.4310000 16.2930000 0.0000000 + 226 226 1 0.0000000 5.4310000 19.0080000 2.7150000 + 227 227 1 0.0000000 8.1460000 19.0080000 0.0000000 + 228 228 1 0.0000000 8.1460000 16.2930000 2.7150000 + 229 229 1 0.0000000 9.5040000 17.6510000 4.0730000 + 230 230 1 0.0000000 6.7890000 17.6510000 1.3580000 + 231 231 1 0.0000000 6.7890000 20.3660000 4.0730000 + 232 232 1 0.0000000 9.5040000 20.3660000 1.3580000 + 233 233 1 0.0000000 5.4310000 16.2930000 5.4310000 + 234 234 1 0.0000000 5.4310000 19.0080000 8.1460000 + 235 235 1 0.0000000 8.1460000 19.0080000 5.4310000 + 236 236 1 0.0000000 8.1460000 16.2930000 8.1460000 + 237 237 1 0.0000000 9.5040000 17.6510000 9.5040000 + 238 238 1 0.0000000 6.7890000 17.6510000 6.7890000 + 239 239 1 0.0000000 6.7890000 20.3660000 9.5040000 + 240 240 1 0.0000000 9.5040000 20.3660000 6.7890000 + 241 241 1 0.0000000 5.4310000 16.2930000 10.8620000 + 242 242 1 0.0000000 5.4310000 19.0080000 13.5770000 + 243 243 1 0.0000000 8.1460000 19.0080000 10.8620000 + 244 244 1 0.0000000 8.1460000 16.2930000 13.5770000 + 245 245 1 0.0000000 9.5040000 17.6510000 14.9350000 + 246 246 1 0.0000000 6.7890000 17.6510000 12.2200000 + 247 247 1 0.0000000 6.7890000 20.3660000 14.9350000 + 248 248 1 0.0000000 9.5040000 20.3660000 12.2200000 + 249 249 1 0.0000000 5.4310000 16.2930000 16.2930000 + 250 250 1 0.0000000 5.4310000 19.0080000 19.0080000 + 251 251 1 0.0000000 8.1460000 19.0080000 16.2930000 + 252 252 1 0.0000000 8.1460000 16.2930000 19.0080000 + 253 253 1 0.0000000 9.5040000 17.6510000 20.3660000 + 254 254 1 0.0000000 6.7890000 17.6510000 17.6510000 + 255 255 1 0.0000000 6.7890000 20.3660000 20.3660000 + 256 256 1 0.0000000 9.5040000 20.3660000 17.6510000 + 257 257 1 0.0000000 10.8620000 0.0000000 0.0000000 + 258 258 1 0.0000000 10.8620000 2.7150000 2.7150000 + 259 259 1 0.0000000 13.5770000 2.7150000 0.0000000 + 260 260 1 0.0000000 13.5770000 0.0000000 2.7150000 + 261 261 1 0.0000000 14.9350000 1.3580000 4.0730000 + 262 262 1 0.0000000 12.2200000 1.3580000 1.3580000 + 263 263 1 0.0000000 12.2200000 4.0730000 4.0730000 + 264 264 1 0.0000000 14.9350000 4.0730000 1.3580000 + 265 265 1 0.0000000 10.8620000 0.0000000 5.4310000 + 266 266 1 0.0000000 10.8620000 2.7150000 8.1460000 + 267 267 1 0.0000000 13.5770000 2.7150000 5.4310000 + 268 268 1 0.0000000 13.5770000 0.0000000 8.1460000 + 269 269 1 0.0000000 14.9350000 1.3580000 9.5040000 + 270 270 1 0.0000000 12.2200000 1.3580000 6.7890000 + 271 271 1 0.0000000 12.2200000 4.0730000 9.5040000 + 272 272 1 0.0000000 14.9350000 4.0730000 6.7890000 + 273 273 1 0.0000000 10.8620000 0.0000000 10.8620000 + 274 274 1 0.0000000 10.8620000 2.7150000 13.5770000 + 275 275 1 0.0000000 13.5770000 2.7150000 10.8620000 + 276 276 1 0.0000000 13.5770000 0.0000000 13.5770000 + 277 277 1 0.0000000 14.9350000 1.3580000 14.9350000 + 278 278 1 0.0000000 12.2200000 1.3580000 12.2200000 + 279 279 1 0.0000000 12.2200000 4.0730000 14.9350000 + 280 280 1 0.0000000 14.9350000 4.0730000 12.2200000 + 281 281 1 0.0000000 10.8620000 0.0000000 16.2930000 + 282 282 1 0.0000000 10.8620000 2.7150000 19.0080000 + 283 283 1 0.0000000 13.5770000 2.7150000 16.2930000 + 284 284 1 0.0000000 13.5770000 0.0000000 19.0080000 + 285 285 1 0.0000000 14.9350000 1.3580000 20.3660000 + 286 286 1 0.0000000 12.2200000 1.3580000 17.6510000 + 287 287 1 0.0000000 12.2200000 4.0730000 20.3660000 + 288 288 1 0.0000000 14.9350000 4.0730000 17.6510000 + 289 289 1 0.0000000 10.8620000 5.4310000 0.0000000 + 290 290 1 0.0000000 10.8620000 8.1460000 2.7150000 + 291 291 1 0.0000000 13.5770000 8.1460000 0.0000000 + 292 292 1 0.0000000 13.5770000 5.4310000 2.7150000 + 293 293 1 0.0000000 14.9350000 6.7890000 4.0730000 + 294 294 1 0.0000000 12.2200000 6.7890000 1.3580000 + 295 295 1 0.0000000 12.2200000 9.5040000 4.0730000 + 296 296 1 0.0000000 14.9350000 9.5040000 1.3580000 + 297 297 1 0.0000000 10.8620000 5.4310000 5.4310000 + 298 298 1 0.0000000 10.8620000 8.1460000 8.1460000 + 299 299 1 0.0000000 13.5770000 8.1460000 5.4310000 + 300 300 1 0.0000000 13.5770000 5.4310000 8.1460000 + 301 301 1 0.0000000 14.9350000 6.7890000 9.5040000 + 302 302 1 0.0000000 12.2200000 6.7890000 6.7890000 + 303 303 1 0.0000000 12.2200000 9.5040000 9.5040000 + 304 304 1 0.0000000 14.9350000 9.5040000 6.7890000 + 305 305 1 0.0000000 10.8620000 5.4310000 10.8620000 + 306 306 1 0.0000000 10.8620000 8.1460000 13.5770000 + 307 307 1 0.0000000 13.5770000 8.1460000 10.8620000 + 308 308 1 0.0000000 13.5770000 5.4310000 13.5770000 + 309 309 1 0.0000000 14.9350000 6.7890000 14.9350000 + 310 310 1 0.0000000 12.2200000 6.7890000 12.2200000 + 311 311 1 0.0000000 12.2200000 9.5040000 14.9350000 + 312 312 1 0.0000000 14.9350000 9.5040000 12.2200000 + 313 313 1 0.0000000 10.8620000 5.4310000 16.2930000 + 314 314 1 0.0000000 10.8620000 8.1460000 19.0080000 + 315 315 1 0.0000000 13.5770000 8.1460000 16.2930000 + 316 316 1 0.0000000 13.5770000 5.4310000 19.0080000 + 317 317 1 0.0000000 14.9350000 6.7890000 20.3660000 + 318 318 1 0.0000000 12.2200000 6.7890000 17.6510000 + 319 319 1 0.0000000 12.2200000 9.5040000 20.3660000 + 320 320 1 0.0000000 14.9350000 9.5040000 17.6510000 + 321 321 1 0.0000000 10.8620000 10.8620000 0.0000000 + 322 322 1 0.0000000 10.8620000 13.5770000 2.7150000 + 323 323 1 0.0000000 13.5770000 13.5770000 0.0000000 + 324 324 1 0.0000000 13.5770000 10.8620000 2.7150000 + 325 325 1 0.0000000 14.9350000 12.2200000 4.0730000 + 326 326 1 0.0000000 12.2200000 12.2200000 1.3580000 + 327 327 1 0.0000000 12.2200000 14.9350000 4.0730000 + 328 328 1 0.0000000 14.9350000 14.9350000 1.3580000 + 329 329 1 0.0000000 10.8620000 10.8620000 5.4310000 + 330 330 1 0.0000000 10.8620000 13.5770000 8.1460000 + 331 331 1 0.0000000 13.5770000 13.5770000 5.4310000 + 332 332 1 0.0000000 13.5770000 10.8620000 8.1460000 + 333 333 1 0.0000000 14.9350000 12.2200000 9.5040000 + 334 334 1 0.0000000 12.2200000 12.2200000 6.7890000 + 335 335 1 0.0000000 12.2200000 14.9350000 9.5040000 + 336 336 1 0.0000000 14.9350000 14.9350000 6.7890000 + 337 337 1 0.0000000 10.8620000 10.8620000 10.8620000 + 338 338 1 0.0000000 10.8620000 13.5770000 13.5770000 + 339 339 1 0.0000000 13.5770000 13.5770000 10.8620000 + 340 340 1 0.0000000 13.5770000 10.8620000 13.5770000 + 341 341 1 0.0000000 14.9350000 12.2200000 14.9350000 + 342 342 1 0.0000000 12.2200000 12.2200000 12.2200000 + 343 343 1 0.0000000 12.2200000 14.9350000 14.9350000 + 344 344 1 0.0000000 14.9350000 14.9350000 12.2200000 + 345 345 1 0.0000000 10.8620000 10.8620000 16.2930000 + 346 346 1 0.0000000 10.8620000 13.5770000 19.0080000 + 347 347 1 0.0000000 13.5770000 13.5770000 16.2930000 + 348 348 1 0.0000000 13.5770000 10.8620000 19.0080000 + 349 349 1 0.0000000 14.9350000 12.2200000 20.3660000 + 350 350 1 0.0000000 12.2200000 12.2200000 17.6510000 + 351 351 1 0.0000000 12.2200000 14.9350000 20.3660000 + 352 352 1 0.0000000 14.9350000 14.9350000 17.6510000 + 353 353 1 0.0000000 10.8620000 16.2930000 0.0000000 + 354 354 1 0.0000000 10.8620000 19.0080000 2.7150000 + 355 355 1 0.0000000 13.5770000 19.0080000 0.0000000 + 356 356 1 0.0000000 13.5770000 16.2930000 2.7150000 + 357 357 1 0.0000000 14.9350000 17.6510000 4.0730000 + 358 358 1 0.0000000 12.2200000 17.6510000 1.3580000 + 359 359 1 0.0000000 12.2200000 20.3660000 4.0730000 + 360 360 1 0.0000000 14.9350000 20.3660000 1.3580000 + 361 361 1 0.0000000 10.8620000 16.2930000 5.4310000 + 362 362 1 0.0000000 10.8620000 19.0080000 8.1460000 + 363 363 1 0.0000000 13.5770000 19.0080000 5.4310000 + 364 364 1 0.0000000 13.5770000 16.2930000 8.1460000 + 365 365 1 0.0000000 14.9350000 17.6510000 9.5040000 + 366 366 1 0.0000000 12.2200000 17.6510000 6.7890000 + 367 367 1 0.0000000 12.2200000 20.3660000 9.5040000 + 368 368 1 0.0000000 14.9350000 20.3660000 6.7890000 + 369 369 1 0.0000000 10.8620000 16.2930000 10.8620000 + 370 370 1 0.0000000 10.8620000 19.0080000 13.5770000 + 371 371 1 0.0000000 13.5770000 19.0080000 10.8620000 + 372 372 1 0.0000000 13.5770000 16.2930000 13.5770000 + 373 373 1 0.0000000 14.9350000 17.6510000 14.9350000 + 374 374 1 0.0000000 12.2200000 17.6510000 12.2200000 + 375 375 1 0.0000000 12.2200000 20.3660000 14.9350000 + 376 376 1 0.0000000 14.9350000 20.3660000 12.2200000 + 377 377 1 0.0000000 10.8620000 16.2930000 16.2930000 + 378 378 1 0.0000000 10.8620000 19.0080000 19.0080000 + 379 379 1 0.0000000 13.5770000 19.0080000 16.2930000 + 380 380 1 0.0000000 13.5770000 16.2930000 19.0080000 + 381 381 1 0.0000000 14.9350000 17.6510000 20.3660000 + 382 382 1 0.0000000 12.2200000 17.6510000 17.6510000 + 383 383 1 0.0000000 12.2200000 20.3660000 20.3660000 + 384 384 1 0.0000000 14.9350000 20.3660000 17.6510000 + 385 385 1 0.0000000 16.2930000 0.0000000 0.0000000 + 386 386 1 0.0000000 16.2930000 2.7150000 2.7150000 + 387 387 1 0.0000000 19.0080000 2.7150000 0.0000000 + 388 388 1 0.0000000 19.0080000 0.0000000 2.7150000 + 389 389 1 0.0000000 20.3660000 1.3580000 4.0730000 + 390 390 1 0.0000000 17.6510000 1.3580000 1.3580000 + 391 391 1 0.0000000 17.6510000 4.0730000 4.0730000 + 392 392 1 0.0000000 20.3660000 4.0730000 1.3580000 + 393 393 1 0.0000000 16.2930000 0.0000000 5.4310000 + 394 394 1 0.0000000 16.2930000 2.7150000 8.1460000 + 395 395 1 0.0000000 19.0080000 2.7150000 5.4310000 + 396 396 1 0.0000000 19.0080000 0.0000000 8.1460000 + 397 397 1 0.0000000 20.3660000 1.3580000 9.5040000 + 398 398 1 0.0000000 17.6510000 1.3580000 6.7890000 + 399 399 1 0.0000000 17.6510000 4.0730000 9.5040000 + 400 400 1 0.0000000 20.3660000 4.0730000 6.7890000 + 401 401 1 0.0000000 16.2930000 0.0000000 10.8620000 + 402 402 1 0.0000000 16.2930000 2.7150000 13.5770000 + 403 403 1 0.0000000 19.0080000 2.7150000 10.8620000 + 404 404 1 0.0000000 19.0080000 0.0000000 13.5770000 + 405 405 1 0.0000000 20.3660000 1.3580000 14.9350000 + 406 406 1 0.0000000 17.6510000 1.3580000 12.2200000 + 407 407 1 0.0000000 17.6510000 4.0730000 14.9350000 + 408 408 1 0.0000000 20.3660000 4.0730000 12.2200000 + 409 409 1 0.0000000 16.2930000 0.0000000 16.2930000 + 410 410 1 0.0000000 16.2930000 2.7150000 19.0080000 + 411 411 1 0.0000000 19.0080000 2.7150000 16.2930000 + 412 412 1 0.0000000 19.0080000 0.0000000 19.0080000 + 413 413 1 0.0000000 20.3660000 1.3580000 20.3660000 + 414 414 1 0.0000000 17.6510000 1.3580000 17.6510000 + 415 415 1 0.0000000 17.6510000 4.0730000 20.3660000 + 416 416 1 0.0000000 20.3660000 4.0730000 17.6510000 + 417 417 1 0.0000000 16.2930000 5.4310000 0.0000000 + 418 418 1 0.0000000 16.2930000 8.1460000 2.7150000 + 419 419 1 0.0000000 19.0080000 8.1460000 0.0000000 + 420 420 1 0.0000000 19.0080000 5.4310000 2.7150000 + 421 421 1 0.0000000 20.3660000 6.7890000 4.0730000 + 422 422 1 0.0000000 17.6510000 6.7890000 1.3580000 + 423 423 1 0.0000000 17.6510000 9.5040000 4.0730000 + 424 424 1 0.0000000 20.3660000 9.5040000 1.3580000 + 425 425 1 0.0000000 16.2930000 5.4310000 5.4310000 + 426 426 1 0.0000000 16.2930000 8.1460000 8.1460000 + 427 427 1 0.0000000 19.0080000 8.1460000 5.4310000 + 428 428 1 0.0000000 19.0080000 5.4310000 8.1460000 + 429 429 1 0.0000000 20.3660000 6.7890000 9.5040000 + 430 430 1 0.0000000 17.6510000 6.7890000 6.7890000 + 431 431 1 0.0000000 17.6510000 9.5040000 9.5040000 + 432 432 1 0.0000000 20.3660000 9.5040000 6.7890000 + 433 433 1 0.0000000 16.2930000 5.4310000 10.8620000 + 434 434 1 0.0000000 16.2930000 8.1460000 13.5770000 + 435 435 1 0.0000000 19.0080000 8.1460000 10.8620000 + 436 436 1 0.0000000 19.0080000 5.4310000 13.5770000 + 437 437 1 0.0000000 20.3660000 6.7890000 14.9350000 + 438 438 1 0.0000000 17.6510000 6.7890000 12.2200000 + 439 439 1 0.0000000 17.6510000 9.5040000 14.9350000 + 440 440 1 0.0000000 20.3660000 9.5040000 12.2200000 + 441 441 1 0.0000000 16.2930000 5.4310000 16.2930000 + 442 442 1 0.0000000 16.2930000 8.1460000 19.0080000 + 443 443 1 0.0000000 19.0080000 8.1460000 16.2930000 + 444 444 1 0.0000000 19.0080000 5.4310000 19.0080000 + 445 445 1 0.0000000 20.3660000 6.7890000 20.3660000 + 446 446 1 0.0000000 17.6510000 6.7890000 17.6510000 + 447 447 1 0.0000000 17.6510000 9.5040000 20.3660000 + 448 448 1 0.0000000 20.3660000 9.5040000 17.6510000 + 449 449 1 0.0000000 16.2930000 10.8620000 0.0000000 + 450 450 1 0.0000000 16.2930000 13.5770000 2.7150000 + 451 451 1 0.0000000 19.0080000 13.5770000 0.0000000 + 452 452 1 0.0000000 19.0080000 10.8620000 2.7150000 + 453 453 1 0.0000000 20.3660000 12.2200000 4.0730000 + 454 454 1 0.0000000 17.6510000 12.2200000 1.3580000 + 455 455 1 0.0000000 17.6510000 14.9350000 4.0730000 + 456 456 1 0.0000000 20.3660000 14.9350000 1.3580000 + 457 457 1 0.0000000 16.2930000 10.8620000 5.4310000 + 458 458 1 0.0000000 16.2930000 13.5770000 8.1460000 + 459 459 1 0.0000000 19.0080000 13.5770000 5.4310000 + 460 460 1 0.0000000 19.0080000 10.8620000 8.1460000 + 461 461 1 0.0000000 20.3660000 12.2200000 9.5040000 + 462 462 1 0.0000000 17.6510000 12.2200000 6.7890000 + 463 463 1 0.0000000 17.6510000 14.9350000 9.5040000 + 464 464 1 0.0000000 20.3660000 14.9350000 6.7890000 + 465 465 1 0.0000000 16.2930000 10.8620000 10.8620000 + 466 466 1 0.0000000 16.2930000 13.5770000 13.5770000 + 467 467 1 0.0000000 19.0080000 13.5770000 10.8620000 + 468 468 1 0.0000000 19.0080000 10.8620000 13.5770000 + 469 469 1 0.0000000 20.3660000 12.2200000 14.9350000 + 470 470 1 0.0000000 17.6510000 12.2200000 12.2200000 + 471 471 1 0.0000000 17.6510000 14.9350000 14.9350000 + 472 472 1 0.0000000 20.3660000 14.9350000 12.2200000 + 473 473 1 0.0000000 16.2930000 10.8620000 16.2930000 + 474 474 1 0.0000000 16.2930000 13.5770000 19.0080000 + 475 475 1 0.0000000 19.0080000 13.5770000 16.2930000 + 476 476 1 0.0000000 19.0080000 10.8620000 19.0080000 + 477 477 1 0.0000000 20.3660000 12.2200000 20.3660000 + 478 478 1 0.0000000 17.6510000 12.2200000 17.6510000 + 479 479 1 0.0000000 17.6510000 14.9350000 20.3660000 + 480 480 1 0.0000000 20.3660000 14.9350000 17.6510000 + 481 481 1 0.0000000 16.2930000 16.2930000 0.0000000 + 482 482 1 0.0000000 16.2930000 19.0080000 2.7150000 + 483 483 1 0.0000000 19.0080000 19.0080000 0.0000000 + 484 484 1 0.0000000 19.0080000 16.2930000 2.7150000 + 485 485 1 0.0000000 20.3660000 17.6510000 4.0730000 + 486 486 1 0.0000000 17.6510000 17.6510000 1.3580000 + 487 487 1 0.0000000 17.6510000 20.3660000 4.0730000 + 488 488 1 0.0000000 20.3660000 20.3660000 1.3580000 + 489 489 1 0.0000000 16.2930000 16.2930000 5.4310000 + 490 490 1 0.0000000 16.2930000 19.0080000 8.1460000 + 491 491 1 0.0000000 19.0080000 19.0080000 5.4310000 + 492 492 1 0.0000000 19.0080000 16.2930000 8.1460000 + 493 493 1 0.0000000 20.3660000 17.6510000 9.5040000 + 494 494 1 0.0000000 17.6510000 17.6510000 6.7890000 + 495 495 1 0.0000000 17.6510000 20.3660000 9.5040000 + 496 496 1 0.0000000 20.3660000 20.3660000 6.7890000 + 497 497 1 0.0000000 16.2930000 16.2930000 10.8620000 + 498 498 1 0.0000000 16.2930000 19.0080000 13.5770000 + 499 499 1 0.0000000 19.0080000 19.0080000 10.8620000 + 500 500 1 0.0000000 19.0080000 16.2930000 13.5770000 + 501 501 1 0.0000000 20.3660000 17.6510000 14.9350000 + 502 502 1 0.0000000 17.6510000 17.6510000 12.2200000 + 503 503 1 0.0000000 17.6510000 20.3660000 14.9350000 + 504 504 1 0.0000000 20.3660000 20.3660000 12.2200000 + 505 505 1 0.0000000 16.2930000 16.2930000 16.2930000 + 506 506 1 0.0000000 16.2930000 19.0080000 19.0080000 + 507 507 1 0.0000000 19.0080000 19.0080000 16.2930000 + 508 508 1 0.0000000 19.0080000 16.2930000 19.0080000 + 509 509 1 0.0000000 20.3660000 17.6510000 20.3660000 + 510 510 1 0.0000000 17.6510000 17.6510000 17.6510000 + 511 511 1 0.0000000 17.6510000 20.3660000 20.3660000 + 512 512 1 0.0000000 20.3660000 20.3660000 17.6510000 + diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_8.lmp b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_8.lmp new file mode 100755 index 0000000000..5066049895 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_8.lmp @@ -0,0 +1,29 @@ +LAMMPS description + + 8 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 5.4310000 xlo xhi + 0.0000000 5.4310000 ylo yhi + 0.0000000 5.4310000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 1.3577500 1.3577500 1.3572000 + 3 3 1 0.0000000 2.7155000 2.7155000 0.0000000 + 4 4 1 0.0000000 4.0732500 4.0732500 1.3572000 + 5 5 1 0.0000000 2.7155000 0.0000000 2.7144000 + 6 6 1 0.0000000 4.0732500 1.3577500 4.0732500 + 7 7 1 0.0000000 0.0000000 2.7155000 2.7155000 + 8 8 1 0.0000000 1.3577500 4.0732500 4.0732500 diff --git a/examples/USER/phonon/dynamical_matrix_command/results/dynmat.dat b/examples/USER/phonon/dynamical_matrix_command/results/dynmat.dat new file mode 100755 index 0000000000..676f897416 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/results/dynmat.dat @@ -0,0 +1,192 @@ +5409.83472486 3.05075234 0.00000214 +-1277.48270695 -863.24917964 -862.95613831 +-193.14095266 0.11071645 0.00000015 +-1277.48270619 -863.24917934 862.95613793 +-193.17613831 0.34066975 -0.00000031 +-1276.01088244 861.54715125 -861.62537402 +83.46959051 -0.09801326 0.00000000 +-1276.01088167 861.54715064 861.62537387 +3.05073556 5409.83419867 0.00000137 +-863.13224993 -1277.34160622 -862.92133430 +0.12865796 -193.14095472 -0.00000023 +-863.13224825 -1277.34160485 862.92133392 +-0.23661028 83.46934214 -0.00000046 +861.66402909 -1276.15172701 861.66024333 +-0.00634065 -193.17585981 -0.00000015 +861.66402909 -1276.15172686 -861.66024394 +0.00000031 0.00000031 5410.11037330 +-862.89766079 -862.97973912 -1277.71823542 +0.00000000 -0.00000008 83.84059083 +862.89766018 862.97973851 -1277.71823557 +0.00000015 0.00000015 -193.17558390 +-861.60900269 861.52691291 -1276.08157137 +-0.00000015 -0.00000031 -193.17573821 +861.60900330 -861.52691284 -1276.08157236 +-1277.48271824 -863.13225435 -862.89768596 +5409.83567916 3.04882502 2.82007861 +-1277.34161080 -863.24919475 862.97975804 +-193.14089260 0.11950100 0.11994134 +-1277.52243157 863.24943259 -863.11331046 +-193.17597070 0.16713301 -0.02106496 +-1274.64156872 859.96385388 860.17328202 +83.46945758 -0.16730525 -0.06100253 +-863.24919444 -1277.34161103 -862.97975804 +3.04882666 5409.83567944 -2.82007731 +-863.13225496 -1277.48271916 862.89768688 +0.11950094 -193.14089255 -0.11994043 +863.24943320 -1277.52243118 863.11331076 +-0.16730522 83.46945778 0.06100314 +859.96385365 -1274.64156819 -860.17328225 +0.16713979 -193.17596607 0.02106008 +-862.95611199 -862.92132598 -1277.71824411 +2.82004085 -2.82004013 5410.11000835 +862.92132743 862.95611344 -1277.71824587 +-0.11994722 0.11994786 83.84083834 +-862.88110757 862.88110699 -1277.34764097 +0.02099713 0.06108924 -193.17561785 +860.25587487 -860.25587502 -1274.81548840 +-0.06108897 -0.02099687 -193.17561808 +-193.14095465 0.12865765 0.00000015 +-1277.34160508 -863.13224794 862.92133361 +5409.83419867 3.05073968 0.00000092 +-1277.34160584 -863.13224924 -862.92133483 +83.46934214 -0.23660998 -0.00000076 +-1276.15172724 861.66402917 861.66024325 +-193.17585988 -0.00634042 -0.00000031 +-1276.15172694 861.66402940 -861.66024325 +0.11071645 -193.14095243 0.00000046 +-863.24917949 -1277.48270718 862.95613831 +3.05075524 5409.83472478 -0.00000046 +-863.24918117 -1277.48270825 -862.95613923 +0.34066922 -193.17613823 0.00000046 +861.54715094 -1276.01088228 -861.62537295 +-0.09801303 83.46959035 0.00000015 +861.54713538 -1276.01088145 861.62537387 +-0.00000046 -0.00000023 83.84059068 +862.97973867 862.89766010 -1277.71823633 +-0.00000214 -0.00000053 5410.11037574 +-862.97973943 -862.89766079 -1277.71823633 +0.00000015 0.00000008 -193.17558374 +861.52691291 -861.60900269 -1276.08157198 +-0.00000015 -0.00000015 -193.17573814 +-861.52691368 861.60900261 -1276.08157243 +-1277.48271786 -863.13225450 862.89768520 +-193.14089232 0.11950085 -0.11994115 +-1277.34161255 -863.24919673 -862.97975957 +5409.83568051 3.04882517 -2.82007644 +-1277.52243110 863.24943259 863.11330990 +83.46945732 -0.16730494 0.06100319 +-1274.64156796 859.96385342 -860.17328103 +-193.17597041 0.16713331 0.02106477 +-863.24919482 -1277.34161057 862.97975774 +0.11950077 -193.14089270 0.11994160 +-863.13225473 -1277.48271839 -862.89768673 +3.04882502 5409.83568081 2.82007903 +863.24943084 -1277.52242966 -863.11330868 +0.16713324 -193.17597064 -0.02106522 +859.96385510 -1274.64156926 860.17328255 +-0.16730411 83.46945641 -0.06100350 +862.95611161 862.92132537 -1277.71824365 +0.11994725 -0.11994740 83.84083859 +-862.92132606 -862.95611207 -1277.71824548 +-2.82003936 2.82004013 5410.11000806 +862.88110509 -862.88110547 -1277.34764015 +0.06108893 0.02099703 -193.17561792 +-860.25587388 860.25587441 -1274.81548916 +-0.02099726 -0.06108878 -193.17561777 +-193.17613465 -0.23660693 0.00000015 +-1277.52241409 863.24943328 -862.88111478 +83.46934549 0.34066334 -0.00000015 +-1277.52241425 863.24943335 862.88111508 +5404.58897235 -9.71806749 0.00000015 +-1273.31333522 -858.38273960 -858.96245956 +-193.21062369 -0.11938368 0.00000000 +-1273.31333598 -858.38273967 858.96245926 +0.34066342 83.46934572 0.00000015 +863.24943335 -1277.52241402 862.88111478 +-0.23660723 -193.17613480 -0.00000046 +863.24943320 -1277.52241425 -862.88111432 +-9.71806582 5404.58897135 -0.00000183 +-858.38273891 -1273.31333552 -858.96245926 +-0.11938338 -193.21062369 0.00000000 +-858.38273937 -1273.31333598 858.96245987 +-0.00000031 -0.00000008 -193.17559595 +-863.11328229 863.11328297 -1277.34763999 +0.00000000 -0.00000015 -193.17559595 +863.11328305 -863.11328282 -1277.34763984 +0.00000122 -0.00000259 5404.30470550 +-858.80486827 -858.80486866 -1273.17865241 +-0.00000031 0.00000000 83.09905870 +858.80486827 858.80486812 -1273.17865272 +-1276.01089136 861.66402482 -861.60900483 +-193.17596134 -0.16730494 0.02099535 +-1276.15175745 861.54714988 861.52691337 +83.46947097 0.16714109 0.06108436 +-1273.31334651 -858.38273311 -858.80488185 +5404.58493608 -3.04507687 -2.81778617 +-1276.19187193 -861.66399965 861.74280750 +-193.21058304 -0.11920641 -0.12012575 +861.54714972 -1276.15175730 861.52691337 +0.16714140 83.46947120 0.06108451 +861.66402345 -1276.01089022 -861.60900330 +-0.16730487 -193.17596164 0.02099489 +-858.38273281 -1273.31334681 -858.80488063 +-3.04507603 5404.58493554 -2.81778617 +-861.66400079 -1276.19187270 861.74280887 +-0.11920511 -193.21058281 -0.12012498 +-861.62536929 861.66025668 -1276.08157121 +-0.02106026 0.06099877 -193.17561197 +861.66025752 -861.62537051 -1276.08157274 +0.06099923 -0.02106049 -193.17561227 +-858.96244980 -858.96244965 -1273.17866523 +-2.81780608 -2.81780615 5404.30474272 +861.58531232 861.58531248 -1275.71087663 +0.12013467 0.12013460 83.09915619 +83.46958166 -0.00634218 -0.00000023 +-1274.64157002 859.96383191 860.25587098 +-193.17585332 -0.09802844 0.00000023 +-1274.64157155 859.96383290 -860.25587243 +-193.21062064 -0.11939070 -0.00000008 +-1276.19189573 -861.66398638 861.58531118 +5404.58377546 3.62403097 0.00000015 +-1276.19189558 -861.66398615 -861.58531103 +-0.09802859 -193.17585355 -0.00000015 +859.96383206 -1274.64156979 -860.25587113 +-0.00634187 83.46958204 -0.00000008 +859.96383282 -1274.64157132 860.25587212 +-0.11939055 -193.21062041 0.00000000 +-861.66398576 -1276.19189528 861.58531087 +3.62402982 5404.58377698 -0.00000076 +-861.66398927 -1276.19189772 -861.58531331 +0.00000000 0.00000000 -193.17573654 +860.17327676 -860.17327637 -1274.81551212 +0.00000031 0.00000023 -193.17573676 +-860.17327615 860.17327645 -1274.81551258 +0.00000000 0.00000015 83.09907327 +861.74281299 861.74281299 -1275.71086763 +-0.00000046 -0.00000015 5404.30514861 +-861.74281406 -861.74281421 -1275.71086938 +-1276.01088968 861.66402284 861.60900330 +83.46947136 0.16714109 -0.06108436 +-1276.15175722 861.54714957 -861.52691391 +-193.17596141 -0.16730510 -0.02099527 +-1273.31334666 -858.38273281 858.80488124 +-193.21058304 -0.11920641 0.12012636 +-1276.19187285 -861.66400087 -861.74280773 +5404.58493638 -3.04507565 2.81778602 +861.54715133 -1276.15175913 -861.52691490 +-0.16730502 -193.17596118 -0.02099497 +861.66402314 -1276.01088976 861.60900383 +0.16714125 83.46947151 -0.06108497 +-858.38273296 -1273.31334681 858.80488139 +-0.11920686 -193.21058311 0.12012605 +-861.66400079 -1276.19187255 -861.74280811 +-3.04506703 5404.58493432 2.81779319 +861.62536952 -861.66025637 -1276.08157175 +-0.06099938 0.02106080 -193.17561235 +-861.66025645 861.62536929 -1276.08157213 +0.02106049 -0.06099862 -193.17561189 +858.96245049 858.96245041 -1273.17866553 +-0.12013444 -0.12013475 83.09915550 +-861.58531232 -861.58531217 -1275.71087655 +2.81780737 2.81780753 5404.30474547 diff --git a/examples/USER/phonon/dynamical_matrix_command/results/out.silicon b/examples/USER/phonon/dynamical_matrix_command/results/out.silicon new file mode 100755 index 0000000000..9920ddac51 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/results/out.silicon @@ -0,0 +1,58 @@ +LAMMPS (16 Jul 2018) +Reading data file ... + orthogonal box = (0 0 0) to (5.431 5.431 5.431) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 8 atoms +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 0 = max # of 1-2 neighbors + 0 = max # of 1-3 neighbors + 0 = max # of 1-4 neighbors + 1 = max # of special neighbors +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 4 + ghost atom cutoff = 4 + binsize = 2, bins = 3 3 3 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair tersoff, perpetual + attributes: full, newton on + pair build: full/bin + stencil: full/bin/3d + bin: standard +Calculating Dynamical Matrix... +Dynamical Matrix calculation took 0.001183 seconds +Finished Calculating Dynamical Matrix +Loop time of 1.22396e+06 on 4 procs for 0 steps with 8 atoms + +0.0% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.00016781 | 0.00041345 | 0.00051464 | 0.0 | 0.00 +Bond | 1.9255e-06 | 2.1775e-06 | 2.4787e-06 | 0.0 | 0.00 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.00056143 | 0.00066602 | 0.00090865 | 0.0 | 0.00 +Output | 0 | 0 | 0 | 0.0 | 0.00 +Modify | 0 | 0 | 0 | 0.0 | 0.00 +Other | | 1.224e+06 | | |100.00 + +Nlocal: 2 ave 3 max 1 min +Histogram: 1 0 0 0 0 2 0 0 0 1 +Nghost: 56 ave 57 max 55 min +Histogram: 1 0 0 0 0 2 0 0 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 32 ave 48 max 16 min +Histogram: 1 0 0 0 0 2 0 0 0 1 + +Total # of neighbors = 128 +Ave neighs/atom = 16 +Ave special neighs/atom = 0 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/USER/phonon/dynamical_matrix_command/silicon_input_file.lmp b/examples/USER/phonon/dynamical_matrix_command/silicon_input_file.lmp new file mode 100755 index 0000000000..5066049895 --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/silicon_input_file.lmp @@ -0,0 +1,29 @@ +LAMMPS description + + 8 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 5.4310000 xlo xhi + 0.0000000 5.4310000 ylo yhi + 0.0000000 5.4310000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 1.3577500 1.3577500 1.3572000 + 3 3 1 0.0000000 2.7155000 2.7155000 0.0000000 + 4 4 1 0.0000000 4.0732500 4.0732500 1.3572000 + 5 5 1 0.0000000 2.7155000 0.0000000 2.7144000 + 6 6 1 0.0000000 4.0732500 1.3577500 4.0732500 + 7 7 1 0.0000000 0.0000000 2.7155000 2.7155000 + 8 8 1 0.0000000 1.3577500 4.0732500 4.0732500 diff --git a/examples/USER/phonon/third_order_command/Manual.md b/examples/USER/phonon/third_order_command/Manual.md new file mode 100755 index 0000000000..49340cb54d --- /dev/null +++ b/examples/USER/phonon/third_order_command/Manual.md @@ -0,0 +1,48 @@ +# third_order command + +## Syntax + +``` +third_order group-ID style args keyword value ... +``` + +* group-ID = ID of group of atoms to displace +* style = *regular* or *ballistico* +``` +*regular* args = gamma + gamma = finite difference displacement length +*ballistico* args = gamma + gamma = finite difference displacement length +``` +* zero or more keyword/value pairs may be appended +* keyword = *file* or *binary* +``` +*file* value = output_file + output_file = name of file to dump the dynamical matrix into +*binary* values = *no* or *gzip* +``` + +## Examples + +``` +third_order 1 regular 0.000001 +third_order 1 ballistico 0.000001 +third_order 3 regular 0.00004 file third_order.dat +third_order 5 ballistico 0.00000001 file third_order.dat binary gzip +``` + +## Description + +Calculate the finite difference third order tensor of the selected group. + +## Restrictions + +None + +## Related commands + +None + +## Default + +The option defaults are file = "third_order.dat", binary = no diff --git a/examples/USER/phonon/third_order_command/README.md b/examples/USER/phonon/third_order_command/README.md new file mode 100755 index 0000000000..a9604e4575 --- /dev/null +++ b/examples/USER/phonon/third_order_command/README.md @@ -0,0 +1,25 @@ +# LAMMPS LATTICE DYNAMICS COMMANDS + +## THIRD ORDER TENSOR CALCULATOR + +This directory contains the ingredients to calculate a third order tensor. + +Example: +``` +$THIRD_ORDER=third_order #tensor output file +NP=4 #number of processors +mpirun -np $NP lmp_mpi < in.silicon > out.silicon +combine.sh third_order +``` + +To test out a different silicon example: +``` +$THIRD_ORDER=third_order +$LMP_FILE=amorphous_silicon.lmp +cp lmp_bank/$LMP_FILE ./silicon_input_file.lmp +NP=4 #number of processors +mpirun -np $NP lmp_mpi < in.silicon > out.silicon +bash combine.sh $THIRD_ORDER +``` + +## Requires: MANYBODY and MOLECULE packages diff --git a/examples/USER/phonon/third_order_command/Si.opt.tersoff b/examples/USER/phonon/third_order_command/Si.opt.tersoff new file mode 100755 index 0000000000..3bc19f0581 --- /dev/null +++ b/examples/USER/phonon/third_order_command/Si.opt.tersoff @@ -0,0 +1,66 @@ +# Tersoff 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: +# A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms +# other quantities are unitless + +# Aidan Thompson (athomps at sandia.gov) takes full blame for this +# file. It specifies various potentials published by J. Tersoff for +# silicon, carbon and germanium. Since Tersoff published several +# different silicon potentials, I refer to them using atom types +# Si(B), Si(C) and Si(D). The last two are almost almost identical but +# refer to two different publications. These names should be used in +# the LAMMPS command when the file is invoked. For example: +# pair_coeff * * SiCGe.tersoff Si(B). The Si(D), C and Ge potentials +# can be used pure silicon, pure carbon, pure germanium, binary SiC, +# and binary SiGe, but not binary GeC or ternary SiGeC. LAMMPS will +# generate an error if this file is used with any combination +# involving C and Ge, since there are no entries for the GeC +# interactions (Tersoff did not publish parameters for this +# cross-interaction.) + +# format of a single entry (one or more lines): +# element 1, element 2, element 3, +# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A + +# The original Tersoff potential for Silicon, Si(B) +# J. Tersoff, PRB, 37, 6991 (1988) + +Si(B) Si(B) Si(B) 3.0 1.0 1.3258 4.8381 2.0417 0.0000 22.956 + 0.33675 1.3258 95.373 3.0 0.2 3.2394 3264.7 + +# The later Tersoff potential for Silicon, Si(C) +# J. Tersoff, PRB, 38, 9902 (1988) + +Si(C) Si(C) Si(C) 3.0 1.0 1.7322 1.0039e5 16.218 -0.59826 0.78734 + 1.0999e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 + +# The later Tersoff potential for Carbon, Silicon, and Germanium +# J. Tersoff, PRB, 39, 5566 (1989) + errata (PRB 41, 3248) +# The Si and C parameters are very close to those in SiC.tersoff + +C C C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 2.2119 346.74 1.95 0.15 3.4879 1393.6 +Si(D) Si(D) Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 +Ge Ge Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.7047 419.23 2.95 0.15 2.4451 1769.0 + +C Si(D) Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 +C Si(D) C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 1.95 0.15 0.0 0.0 +C C Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 + +Si(D) C C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 +Si(D) Si(D) C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 +Si(D) C Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 + +Si(D) Ge Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 +Si(D) Si(D) Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 +Si(D) Ge Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 + +Ge Si(D) Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 +Ge Si(D) Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.95 0.15 0.0 0.0 +Ge Ge Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 + +# Optimized Tersoff for Carbon: Lindsay and Broido PRB 81, 205441 (2010) +# element 1, element 2, element 3, +# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A +C(O) C(O) C(O) 3.0 1.0 0.0 3.8049e4 4.3484 -0.930 0.72751 1.5724e-7 2.2119 430.0 1.95 0.15 3.4879 1393.6 + diff --git a/examples/USER/phonon/third_order_command/combine.sh b/examples/USER/phonon/third_order_command/combine.sh new file mode 100755 index 0000000000..3eca2537be --- /dev/null +++ b/examples/USER/phonon/third_order_command/combine.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +#This script takes one argument +#The argument is the base name for the split up tensor +#The script then combines and sorts the tensor +#$1 file name + +echo "$1" +[ -f $1 ] && rm $1 + +for i in $(ls ./$1*); do + cat $i >> temp + rm $i +done + +sort temp | sort -s -n -k 3 | sort -s -n -k 1 > $1 +rm temp diff --git a/examples/USER/phonon/third_order_command/ff-silicon.lmp b/examples/USER/phonon/third_order_command/ff-silicon.lmp new file mode 100755 index 0000000000..f3b895f168 --- /dev/null +++ b/examples/USER/phonon/third_order_command/ff-silicon.lmp @@ -0,0 +1,19 @@ +############################# +#Atoms types - mass - charge# +############################# +#@ 1 atom types #!THIS LINE IS NECESSARY DON'T SPEND HOURS FINDING THAT OUT!# + +variable Si equal 1 + +############# +#Atom Masses# +############# + +mass ${Si} 28.08550 + +########################### +#Pair Potentials - Tersoff# +########################### + +pair_style tersoff +pair_coeff * * Si.opt.tersoff Si(D) diff --git a/examples/USER/phonon/third_order_command/in.silicon b/examples/USER/phonon/third_order_command/in.silicon new file mode 100755 index 0000000000..b8a9e214c4 --- /dev/null +++ b/examples/USER/phonon/third_order_command/in.silicon @@ -0,0 +1,84 @@ +###############################mm +# Atom style - charge/vdw/bonded# +################################# +atom_style full + +############################################## +#Units Metal : eV - ps - angstrom - bar# +# Real : kcal/mol - fs - angstrom - atm# +############################################## +units metal + +############ +#Run number# +############ +variable run_no equal 0 # is it a restart? +variable res_no equal ${run_no}-1 # restart file number + +####################################### +#Random Seeds and Domain Decomposition# +####################################### +variable iseed0 equal 2357 +variable iseed1 equal 26488 +variable iseed2 equal 10669 +processors * * 1 + +########### +#Data File# +########### +variable inpfile string silicon_input_file.lmp +variable resfile string final_restart.${res_no} +variable ff_file string ff-silicon.lmp + +########## +#Run Type# +########## +variable minimise equal 0 #Energy Minimization + +############################### +#Molecular Dynamics Parameters# +############################### +neighbor 1 bin + +################################ +#Energy Minimization Parameters# +################################ +variable mtraj equal 1 # trajectory output frequency - all system +variable etol equal 1e-5 # % change in energy +variable ftol equal 1e-5 # max force threshold (force units) +variable maxiter equal 10000 # max # of iterations + +######################## +#3D Periodic Simulation# +######################## +boundary p p p + +############################# +#Reading the input structure# +############################# +if "${run_no} == 0" then "read_data ${inpfile}" else "read_restart ${resfile}" + +############# +#Force Field# +############# +include ${ff_file} + +##################### +#Energy Minimization# +##################### +if "${minimise} <= 0 || ${run_no} > 0" then "jump SELF end_minimise" + print "Doing CG minimisation" + dump mdcd all dcd ${mtraj} min.dcd + dump_modify mdcd unwrap yes + min_style cg + min_modify line quadratic + minimize ${etol} ${ftol} ${maxiter} ${maxiter} + reset_timestep 0 + undump mdcd +label end_minimise + +################## +#Dynamical Matrix# +################## +third_order all ballistico 0.00001 file third_order binary no + diff --git a/examples/USER/phonon/third_order_command/lmp_bank/silicon_216.lmp b/examples/USER/phonon/third_order_command/lmp_bank/silicon_216.lmp new file mode 100755 index 0000000000..893d75e69b --- /dev/null +++ b/examples/USER/phonon/third_order_command/lmp_bank/silicon_216.lmp @@ -0,0 +1,238 @@ +LAMMPS description + + 216 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 16.293000 xlo xhi + 0.0000000 16.293000 ylo yhi + 0.0000000 16.293000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 0.0000000 2.7160000 2.7160000 + 3 3 1 0.0000000 2.7160000 2.7160000 0.0000000 + 4 4 1 0.0000000 2.7160000 0.0000000 2.7160000 + 5 5 1 0.0000000 4.0730000 1.3580000 4.0730000 + 6 6 1 0.0000000 1.3580000 1.3580000 1.3580000 + 7 7 1 0.0000000 1.3580000 4.0730000 4.0730000 + 8 8 1 0.0000000 4.0730000 4.0730000 1.3580000 + 9 9 1 0.0000000 0.0000000 0.0000000 5.4310000 + 10 10 1 0.0000000 0.0000000 2.7160000 8.1460000 + 11 11 1 0.0000000 2.7160000 2.7160000 5.4310000 + 12 12 1 0.0000000 2.7160000 0.0000000 8.1460000 + 13 13 1 0.0000000 4.0730000 1.3580000 9.5040000 + 14 14 1 0.0000000 1.3580000 1.3580000 6.7890000 + 15 15 1 0.0000000 1.3580000 4.0730000 9.5040000 + 16 16 1 0.0000000 4.0730000 4.0730000 6.7890000 + 17 17 1 0.0000000 0.0000000 0.0000000 10.8620000 + 18 18 1 0.0000000 0.0000000 2.7160000 13.5780000 + 19 19 1 0.0000000 2.7160000 2.7160000 10.8620000 + 20 20 1 0.0000000 2.7160000 0.0000000 13.5780000 + 21 21 1 0.0000000 4.0730000 1.3580000 14.9350000 + 22 22 1 0.0000000 1.3580000 1.3580000 12.2200000 + 23 23 1 0.0000000 1.3580000 4.0730000 14.9350000 + 24 24 1 0.0000000 4.0730000 4.0730000 12.2200000 + 25 25 1 0.0000000 0.0000000 5.4310000 0.0000000 + 26 26 1 0.0000000 0.0000000 8.1460000 2.7160000 + 27 27 1 0.0000000 2.7160000 8.1460000 0.0000000 + 28 28 1 0.0000000 2.7160000 5.4310000 2.7160000 + 29 29 1 0.0000000 4.0730000 6.7890000 4.0730000 + 30 30 1 0.0000000 1.3580000 6.7890000 1.3580000 + 31 31 1 0.0000000 1.3580000 9.5040000 4.0730000 + 32 32 1 0.0000000 4.0730000 9.5040000 1.3580000 + 33 33 1 0.0000000 0.0000000 5.4310000 5.4310000 + 34 34 1 0.0000000 0.0000000 8.1460000 8.1460000 + 35 35 1 0.0000000 2.7160000 8.1460000 5.4310000 + 36 36 1 0.0000000 2.7160000 5.4310000 8.1460000 + 37 37 1 0.0000000 4.0730000 6.7890000 9.5040000 + 38 38 1 0.0000000 1.3580000 6.7890000 6.7890000 + 39 39 1 0.0000000 1.3580000 9.5040000 9.5040000 + 40 40 1 0.0000000 4.0730000 9.5040000 6.7890000 + 41 41 1 0.0000000 0.0000000 5.4310000 10.8620000 + 42 42 1 0.0000000 0.0000000 8.1460000 13.5780000 + 43 43 1 0.0000000 2.7160000 8.1460000 10.8620000 + 44 44 1 0.0000000 2.7160000 5.4310000 13.5780000 + 45 45 1 0.0000000 4.0730000 6.7890000 14.9350000 + 46 46 1 0.0000000 1.3580000 6.7890000 12.2200000 + 47 47 1 0.0000000 1.3580000 9.5040000 14.9350000 + 48 48 1 0.0000000 4.0730000 9.5040000 12.2200000 + 49 49 1 0.0000000 0.0000000 10.8620000 0.0000000 + 50 50 1 0.0000000 0.0000000 13.5780000 2.7160000 + 51 51 1 0.0000000 2.7160000 13.5780000 0.0000000 + 52 52 1 0.0000000 2.7160000 10.8620000 2.7160000 + 53 53 1 0.0000000 4.0730000 12.2200000 4.0730000 + 54 54 1 0.0000000 1.3580000 12.2200000 1.3580000 + 55 55 1 0.0000000 1.3580000 14.9350000 4.0730000 + 56 56 1 0.0000000 4.0730000 14.9350000 1.3580000 + 57 57 1 0.0000000 0.0000000 10.8620000 5.4310000 + 58 58 1 0.0000000 0.0000000 13.5780000 8.1460000 + 59 59 1 0.0000000 2.7160000 13.5780000 5.4310000 + 60 60 1 0.0000000 2.7160000 10.8620000 8.1460000 + 61 61 1 0.0000000 4.0730000 12.2200000 9.5040000 + 62 62 1 0.0000000 1.3580000 12.2200000 6.7890000 + 63 63 1 0.0000000 1.3580000 14.9350000 9.5040000 + 64 64 1 0.0000000 4.0730000 14.9350000 6.7890000 + 65 65 1 0.0000000 0.0000000 10.8620000 10.8620000 + 66 66 1 0.0000000 0.0000000 13.5780000 13.5780000 + 67 67 1 0.0000000 2.7160000 13.5780000 10.8620000 + 68 68 1 0.0000000 2.7160000 10.8620000 13.5780000 + 69 69 1 0.0000000 4.0730000 12.2200000 14.9350000 + 70 70 1 0.0000000 1.3580000 12.2200000 12.2200000 + 71 71 1 0.0000000 1.3580000 14.9350000 14.9350000 + 72 72 1 0.0000000 4.0730000 14.9350000 12.2200000 + 73 73 1 0.0000000 5.4310000 0.0000000 0.0000000 + 74 74 1 0.0000000 5.4310000 2.7160000 2.7160000 + 75 75 1 0.0000000 8.1460000 2.7160000 0.0000000 + 76 76 1 0.0000000 8.1460000 0.0000000 2.7160000 + 77 77 1 0.0000000 9.5040000 1.3580000 4.0730000 + 78 78 1 0.0000000 6.7890000 1.3580000 1.3580000 + 79 79 1 0.0000000 6.7890000 4.0730000 4.0730000 + 80 80 1 0.0000000 9.5040000 4.0730000 1.3580000 + 81 81 1 0.0000000 5.4310000 0.0000000 5.4310000 + 82 82 1 0.0000000 5.4310000 2.7160000 8.1460000 + 83 83 1 0.0000000 8.1460000 2.7160000 5.4310000 + 84 84 1 0.0000000 8.1460000 0.0000000 8.1460000 + 85 85 1 0.0000000 9.5040000 1.3580000 9.5040000 + 86 86 1 0.0000000 6.7890000 1.3580000 6.7890000 + 87 87 1 0.0000000 6.7890000 4.0730000 9.5040000 + 88 88 1 0.0000000 9.5040000 4.0730000 6.7890000 + 89 89 1 0.0000000 5.4310000 0.0000000 10.8620000 + 90 90 1 0.0000000 5.4310000 2.7160000 13.5780000 + 91 91 1 0.0000000 8.1460000 2.7160000 10.8620000 + 92 92 1 0.0000000 8.1460000 0.0000000 13.5780000 + 93 93 1 0.0000000 9.5040000 1.3580000 14.9350000 + 94 94 1 0.0000000 6.7890000 1.3580000 12.2200000 + 95 95 1 0.0000000 6.7890000 4.0730000 14.9350000 + 96 96 1 0.0000000 9.5040000 4.0730000 12.2200000 + 97 97 1 0.0000000 5.4310000 5.4310000 0.0000000 + 98 98 1 0.0000000 5.4310000 8.1460000 2.7160000 + 99 99 1 0.0000000 8.1460000 8.1460000 0.0000000 + 100 100 1 0.0000000 8.1460000 5.4310000 2.7160000 + 101 101 1 0.0000000 9.5040000 6.7890000 4.0730000 + 102 102 1 0.0000000 6.7890000 6.7890000 1.3580000 + 103 103 1 0.0000000 6.7890000 9.5040000 4.0730000 + 104 104 1 0.0000000 9.5040000 9.5040000 1.3580000 + 105 105 1 0.0000000 5.4310000 5.4310000 5.4310000 + 106 106 1 0.0000000 5.4310000 8.1460000 8.1460000 + 107 107 1 0.0000000 8.1460000 8.1460000 5.4310000 + 108 108 1 0.0000000 8.1460000 5.4310000 8.1460000 + 109 109 1 0.0000000 9.5040000 6.7890000 9.5040000 + 110 110 1 0.0000000 6.7890000 6.7890000 6.7890000 + 111 111 1 0.0000000 6.7890000 9.5040000 9.5040000 + 112 112 1 0.0000000 9.5040000 9.5040000 6.7890000 + 113 113 1 0.0000000 5.4310000 5.4310000 10.8620000 + 114 114 1 0.0000000 5.4310000 8.1460000 13.5780000 + 115 115 1 0.0000000 8.1460000 8.1460000 10.8620000 + 116 116 1 0.0000000 8.1460000 5.4310000 13.5780000 + 117 117 1 0.0000000 9.5040000 6.7890000 14.9350000 + 118 118 1 0.0000000 6.7890000 6.7890000 12.2200000 + 119 119 1 0.0000000 6.7890000 9.5040000 14.9350000 + 120 120 1 0.0000000 9.5040000 9.5040000 12.2200000 + 121 121 1 0.0000000 5.4310000 10.8620000 0.0000000 + 122 122 1 0.0000000 5.4310000 13.5780000 2.7160000 + 123 123 1 0.0000000 8.1460000 13.5780000 0.0000000 + 124 124 1 0.0000000 8.1460000 10.8620000 2.7160000 + 125 125 1 0.0000000 9.5040000 12.2200000 4.0730000 + 126 126 1 0.0000000 6.7890000 12.2200000 1.3580000 + 127 127 1 0.0000000 6.7890000 14.9350000 4.0730000 + 128 128 1 0.0000000 9.5040000 14.9350000 1.3580000 + 129 129 1 0.0000000 5.4310000 10.8620000 5.4310000 + 130 130 1 0.0000000 5.4310000 13.5780000 8.1460000 + 131 131 1 0.0000000 8.1460000 13.5780000 5.4310000 + 132 132 1 0.0000000 8.1460000 10.8620000 8.1460000 + 133 133 1 0.0000000 9.5040000 12.2200000 9.5040000 + 134 134 1 0.0000000 6.7890000 12.2200000 6.7890000 + 135 135 1 0.0000000 6.7890000 14.9350000 9.5040000 + 136 136 1 0.0000000 9.5040000 14.9350000 6.7890000 + 137 137 1 0.0000000 5.4310000 10.8620000 10.8620000 + 138 138 1 0.0000000 5.4310000 13.5780000 13.5780000 + 139 139 1 0.0000000 8.1460000 13.5780000 10.8620000 + 140 140 1 0.0000000 8.1460000 10.8620000 13.5780000 + 141 141 1 0.0000000 9.5040000 12.2200000 14.9350000 + 142 142 1 0.0000000 6.7890000 12.2200000 12.2200000 + 143 143 1 0.0000000 6.7890000 14.9350000 14.9350000 + 144 144 1 0.0000000 9.5040000 14.9350000 12.2200000 + 145 145 1 0.0000000 10.8620000 0.0000000 0.0000000 + 146 146 1 0.0000000 10.8620000 2.7160000 2.7160000 + 147 147 1 0.0000000 13.5780000 2.7160000 0.0000000 + 148 148 1 0.0000000 13.5780000 0.0000000 2.7160000 + 149 149 1 0.0000000 14.9350000 1.3580000 4.0730000 + 150 150 1 0.0000000 12.2200000 1.3580000 1.3580000 + 151 151 1 0.0000000 12.2200000 4.0730000 4.0730000 + 152 152 1 0.0000000 14.9350000 4.0730000 1.3580000 + 153 153 1 0.0000000 10.8620000 0.0000000 5.4310000 + 154 154 1 0.0000000 10.8620000 2.7160000 8.1460000 + 155 155 1 0.0000000 13.5780000 2.7160000 5.4310000 + 156 156 1 0.0000000 13.5780000 0.0000000 8.1460000 + 157 157 1 0.0000000 14.9350000 1.3580000 9.5040000 + 158 158 1 0.0000000 12.2200000 1.3580000 6.7890000 + 159 159 1 0.0000000 12.2200000 4.0730000 9.5040000 + 160 160 1 0.0000000 14.9350000 4.0730000 6.7890000 + 161 161 1 0.0000000 10.8620000 0.0000000 10.8620000 + 162 162 1 0.0000000 10.8620000 2.7160000 13.5780000 + 163 163 1 0.0000000 13.5780000 2.7160000 10.8620000 + 164 164 1 0.0000000 13.5780000 0.0000000 13.5780000 + 165 165 1 0.0000000 14.9350000 1.3580000 14.9350000 + 166 166 1 0.0000000 12.2200000 1.3580000 12.2200000 + 167 167 1 0.0000000 12.2200000 4.0730000 14.9350000 + 168 168 1 0.0000000 14.9350000 4.0730000 12.2200000 + 169 169 1 0.0000000 10.8620000 5.4310000 0.0000000 + 170 170 1 0.0000000 10.8620000 8.1460000 2.7160000 + 171 171 1 0.0000000 13.5780000 8.1460000 0.0000000 + 172 172 1 0.0000000 13.5780000 5.4310000 2.7160000 + 173 173 1 0.0000000 14.9350000 6.7890000 4.0730000 + 174 174 1 0.0000000 12.2200000 6.7890000 1.3580000 + 175 175 1 0.0000000 12.2200000 9.5040000 4.0730000 + 176 176 1 0.0000000 14.9350000 9.5040000 1.3580000 + 177 177 1 0.0000000 10.8620000 5.4310000 5.4310000 + 178 178 1 0.0000000 10.8620000 8.1460000 8.1460000 + 179 179 1 0.0000000 13.5780000 8.1460000 5.4310000 + 180 180 1 0.0000000 13.5780000 5.4310000 8.1460000 + 181 181 1 0.0000000 14.9350000 6.7890000 9.5040000 + 182 182 1 0.0000000 12.2200000 6.7890000 6.7890000 + 183 183 1 0.0000000 12.2200000 9.5040000 9.5040000 + 184 184 1 0.0000000 14.9350000 9.5040000 6.7890000 + 185 185 1 0.0000000 10.8620000 5.4310000 10.8620000 + 186 186 1 0.0000000 10.8620000 8.1460000 13.5780000 + 187 187 1 0.0000000 13.5780000 8.1460000 10.8620000 + 188 188 1 0.0000000 13.5780000 5.4310000 13.5780000 + 189 189 1 0.0000000 14.9350000 6.7890000 14.9350000 + 190 190 1 0.0000000 12.2200000 6.7890000 12.2200000 + 191 191 1 0.0000000 12.2200000 9.5040000 14.9350000 + 192 192 1 0.0000000 14.9350000 9.5040000 12.2200000 + 193 193 1 0.0000000 10.8620000 10.8620000 0.0000000 + 194 194 1 0.0000000 10.8620000 13.5780000 2.7160000 + 195 195 1 0.0000000 13.5780000 13.5780000 0.0000000 + 196 196 1 0.0000000 13.5780000 10.8620000 2.7160000 + 197 197 1 0.0000000 14.9350000 12.2200000 4.0730000 + 198 198 1 0.0000000 12.2200000 12.2200000 1.3580000 + 199 199 1 0.0000000 12.2200000 14.9350000 4.0730000 + 200 200 1 0.0000000 14.9350000 14.9350000 1.3580000 + 201 201 1 0.0000000 10.8620000 10.8620000 5.4310000 + 202 202 1 0.0000000 10.8620000 13.5780000 8.1460000 + 203 203 1 0.0000000 13.5780000 13.5780000 5.4310000 + 204 204 1 0.0000000 13.5780000 10.8620000 8.1460000 + 205 205 1 0.0000000 14.9350000 12.2200000 9.5040000 + 206 206 1 0.0000000 12.2200000 12.2200000 6.7890000 + 207 207 1 0.0000000 12.2200000 14.9350000 9.5040000 + 208 208 1 0.0000000 14.9350000 14.9350000 6.7890000 + 209 209 1 0.0000000 10.8620000 10.8620000 10.8620000 + 210 210 1 0.0000000 10.8620000 13.5780000 13.5780000 + 211 211 1 0.0000000 13.5780000 13.5780000 10.8620000 + 212 212 1 0.0000000 13.5780000 10.8620000 13.5780000 + 213 213 1 0.0000000 14.9350000 12.2200000 14.9350000 + 214 214 1 0.0000000 12.2200000 12.2200000 12.2200000 + 215 215 1 0.0000000 12.2200000 14.9350000 14.9350000 + 216 216 1 0.0000000 14.9350000 14.9350000 12.2200000 + diff --git a/examples/USER/phonon/third_order_command/lmp_bank/silicon_512.lmp b/examples/USER/phonon/third_order_command/lmp_bank/silicon_512.lmp new file mode 100755 index 0000000000..8c1ecd30bd --- /dev/null +++ b/examples/USER/phonon/third_order_command/lmp_bank/silicon_512.lmp @@ -0,0 +1,534 @@ +LAMMPS description + + 512 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 21.724000 xlo xhi + 0.0000000 21.724000 ylo yhi + 0.0000000 21.724000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 0.0000000 2.7150000 2.7150000 + 3 3 1 0.0000000 2.7150000 2.7150000 0.0000000 + 4 4 1 0.0000000 2.7150000 0.0000000 2.7150000 + 5 5 1 0.0000000 4.0730000 1.3580000 4.0730000 + 6 6 1 0.0000000 1.3580000 1.3580000 1.3580000 + 7 7 1 0.0000000 1.3580000 4.0730000 4.0730000 + 8 8 1 0.0000000 4.0730000 4.0730000 1.3580000 + 9 9 1 0.0000000 0.0000000 0.0000000 5.4310000 + 10 10 1 0.0000000 0.0000000 2.7150000 8.1460000 + 11 11 1 0.0000000 2.7150000 2.7150000 5.4310000 + 12 12 1 0.0000000 2.7150000 0.0000000 8.1460000 + 13 13 1 0.0000000 4.0730000 1.3580000 9.5040000 + 14 14 1 0.0000000 1.3580000 1.3580000 6.7890000 + 15 15 1 0.0000000 1.3580000 4.0730000 9.5040000 + 16 16 1 0.0000000 4.0730000 4.0730000 6.7890000 + 17 17 1 0.0000000 0.0000000 0.0000000 10.8620000 + 18 18 1 0.0000000 0.0000000 2.7150000 13.5770000 + 19 19 1 0.0000000 2.7150000 2.7150000 10.8620000 + 20 20 1 0.0000000 2.7150000 0.0000000 13.5770000 + 21 21 1 0.0000000 4.0730000 1.3580000 14.9350000 + 22 22 1 0.0000000 1.3580000 1.3580000 12.2200000 + 23 23 1 0.0000000 1.3580000 4.0730000 14.9350000 + 24 24 1 0.0000000 4.0730000 4.0730000 12.2200000 + 25 25 1 0.0000000 0.0000000 0.0000000 16.2930000 + 26 26 1 0.0000000 0.0000000 2.7150000 19.0080000 + 27 27 1 0.0000000 2.7150000 2.7150000 16.2930000 + 28 28 1 0.0000000 2.7150000 0.0000000 19.0080000 + 29 29 1 0.0000000 4.0730000 1.3580000 20.3660000 + 30 30 1 0.0000000 1.3580000 1.3580000 17.6510000 + 31 31 1 0.0000000 1.3580000 4.0730000 20.3660000 + 32 32 1 0.0000000 4.0730000 4.0730000 17.6510000 + 33 33 1 0.0000000 0.0000000 5.4310000 0.0000000 + 34 34 1 0.0000000 0.0000000 8.1460000 2.7150000 + 35 35 1 0.0000000 2.7150000 8.1460000 0.0000000 + 36 36 1 0.0000000 2.7150000 5.4310000 2.7150000 + 37 37 1 0.0000000 4.0730000 6.7890000 4.0730000 + 38 38 1 0.0000000 1.3580000 6.7890000 1.3580000 + 39 39 1 0.0000000 1.3580000 9.5040000 4.0730000 + 40 40 1 0.0000000 4.0730000 9.5040000 1.3580000 + 41 41 1 0.0000000 0.0000000 5.4310000 5.4310000 + 42 42 1 0.0000000 0.0000000 8.1460000 8.1460000 + 43 43 1 0.0000000 2.7150000 8.1460000 5.4310000 + 44 44 1 0.0000000 2.7150000 5.4310000 8.1460000 + 45 45 1 0.0000000 4.0730000 6.7890000 9.5040000 + 46 46 1 0.0000000 1.3580000 6.7890000 6.7890000 + 47 47 1 0.0000000 1.3580000 9.5040000 9.5040000 + 48 48 1 0.0000000 4.0730000 9.5040000 6.7890000 + 49 49 1 0.0000000 0.0000000 5.4310000 10.8620000 + 50 50 1 0.0000000 0.0000000 8.1460000 13.5770000 + 51 51 1 0.0000000 2.7150000 8.1460000 10.8620000 + 52 52 1 0.0000000 2.7150000 5.4310000 13.5770000 + 53 53 1 0.0000000 4.0730000 6.7890000 14.9350000 + 54 54 1 0.0000000 1.3580000 6.7890000 12.2200000 + 55 55 1 0.0000000 1.3580000 9.5040000 14.9350000 + 56 56 1 0.0000000 4.0730000 9.5040000 12.2200000 + 57 57 1 0.0000000 0.0000000 5.4310000 16.2930000 + 58 58 1 0.0000000 0.0000000 8.1460000 19.0080000 + 59 59 1 0.0000000 2.7150000 8.1460000 16.2930000 + 60 60 1 0.0000000 2.7150000 5.4310000 19.0080000 + 61 61 1 0.0000000 4.0730000 6.7890000 20.3660000 + 62 62 1 0.0000000 1.3580000 6.7890000 17.6510000 + 63 63 1 0.0000000 1.3580000 9.5040000 20.3660000 + 64 64 1 0.0000000 4.0730000 9.5040000 17.6510000 + 65 65 1 0.0000000 0.0000000 10.8620000 0.0000000 + 66 66 1 0.0000000 0.0000000 13.5770000 2.7150000 + 67 67 1 0.0000000 2.7150000 13.5770000 0.0000000 + 68 68 1 0.0000000 2.7150000 10.8620000 2.7150000 + 69 69 1 0.0000000 4.0730000 12.2200000 4.0730000 + 70 70 1 0.0000000 1.3580000 12.2200000 1.3580000 + 71 71 1 0.0000000 1.3580000 14.9350000 4.0730000 + 72 72 1 0.0000000 4.0730000 14.9350000 1.3580000 + 73 73 1 0.0000000 0.0000000 10.8620000 5.4310000 + 74 74 1 0.0000000 0.0000000 13.5770000 8.1460000 + 75 75 1 0.0000000 2.7150000 13.5770000 5.4310000 + 76 76 1 0.0000000 2.7150000 10.8620000 8.1460000 + 77 77 1 0.0000000 4.0730000 12.2200000 9.5040000 + 78 78 1 0.0000000 1.3580000 12.2200000 6.7890000 + 79 79 1 0.0000000 1.3580000 14.9350000 9.5040000 + 80 80 1 0.0000000 4.0730000 14.9350000 6.7890000 + 81 81 1 0.0000000 0.0000000 10.8620000 10.8620000 + 82 82 1 0.0000000 0.0000000 13.5770000 13.5770000 + 83 83 1 0.0000000 2.7150000 13.5770000 10.8620000 + 84 84 1 0.0000000 2.7150000 10.8620000 13.5770000 + 85 85 1 0.0000000 4.0730000 12.2200000 14.9350000 + 86 86 1 0.0000000 1.3580000 12.2200000 12.2200000 + 87 87 1 0.0000000 1.3580000 14.9350000 14.9350000 + 88 88 1 0.0000000 4.0730000 14.9350000 12.2200000 + 89 89 1 0.0000000 0.0000000 10.8620000 16.2930000 + 90 90 1 0.0000000 0.0000000 13.5770000 19.0080000 + 91 91 1 0.0000000 2.7150000 13.5770000 16.2930000 + 92 92 1 0.0000000 2.7150000 10.8620000 19.0080000 + 93 93 1 0.0000000 4.0730000 12.2200000 20.3660000 + 94 94 1 0.0000000 1.3580000 12.2200000 17.6510000 + 95 95 1 0.0000000 1.3580000 14.9350000 20.3660000 + 96 96 1 0.0000000 4.0730000 14.9350000 17.6510000 + 97 97 1 0.0000000 0.0000000 16.2930000 0.0000000 + 98 98 1 0.0000000 0.0000000 19.0080000 2.7150000 + 99 99 1 0.0000000 2.7150000 19.0080000 0.0000000 + 100 100 1 0.0000000 2.7150000 16.2930000 2.7150000 + 101 101 1 0.0000000 4.0730000 17.6510000 4.0730000 + 102 102 1 0.0000000 1.3580000 17.6510000 1.3580000 + 103 103 1 0.0000000 1.3580000 20.3660000 4.0730000 + 104 104 1 0.0000000 4.0730000 20.3660000 1.3580000 + 105 105 1 0.0000000 0.0000000 16.2930000 5.4310000 + 106 106 1 0.0000000 0.0000000 19.0080000 8.1460000 + 107 107 1 0.0000000 2.7150000 19.0080000 5.4310000 + 108 108 1 0.0000000 2.7150000 16.2930000 8.1460000 + 109 109 1 0.0000000 4.0730000 17.6510000 9.5040000 + 110 110 1 0.0000000 1.3580000 17.6510000 6.7890000 + 111 111 1 0.0000000 1.3580000 20.3660000 9.5040000 + 112 112 1 0.0000000 4.0730000 20.3660000 6.7890000 + 113 113 1 0.0000000 0.0000000 16.2930000 10.8620000 + 114 114 1 0.0000000 0.0000000 19.0080000 13.5770000 + 115 115 1 0.0000000 2.7150000 19.0080000 10.8620000 + 116 116 1 0.0000000 2.7150000 16.2930000 13.5770000 + 117 117 1 0.0000000 4.0730000 17.6510000 14.9350000 + 118 118 1 0.0000000 1.3580000 17.6510000 12.2200000 + 119 119 1 0.0000000 1.3580000 20.3660000 14.9350000 + 120 120 1 0.0000000 4.0730000 20.3660000 12.2200000 + 121 121 1 0.0000000 0.0000000 16.2930000 16.2930000 + 122 122 1 0.0000000 0.0000000 19.0080000 19.0080000 + 123 123 1 0.0000000 2.7150000 19.0080000 16.2930000 + 124 124 1 0.0000000 2.7150000 16.2930000 19.0080000 + 125 125 1 0.0000000 4.0730000 17.6510000 20.3660000 + 126 126 1 0.0000000 1.3580000 17.6510000 17.6510000 + 127 127 1 0.0000000 1.3580000 20.3660000 20.3660000 + 128 128 1 0.0000000 4.0730000 20.3660000 17.6510000 + 129 129 1 0.0000000 5.4310000 0.0000000 0.0000000 + 130 130 1 0.0000000 5.4310000 2.7150000 2.7150000 + 131 131 1 0.0000000 8.1460000 2.7150000 0.0000000 + 132 132 1 0.0000000 8.1460000 0.0000000 2.7150000 + 133 133 1 0.0000000 9.5040000 1.3580000 4.0730000 + 134 134 1 0.0000000 6.7890000 1.3580000 1.3580000 + 135 135 1 0.0000000 6.7890000 4.0730000 4.0730000 + 136 136 1 0.0000000 9.5040000 4.0730000 1.3580000 + 137 137 1 0.0000000 5.4310000 0.0000000 5.4310000 + 138 138 1 0.0000000 5.4310000 2.7150000 8.1460000 + 139 139 1 0.0000000 8.1460000 2.7150000 5.4310000 + 140 140 1 0.0000000 8.1460000 0.0000000 8.1460000 + 141 141 1 0.0000000 9.5040000 1.3580000 9.5040000 + 142 142 1 0.0000000 6.7890000 1.3580000 6.7890000 + 143 143 1 0.0000000 6.7890000 4.0730000 9.5040000 + 144 144 1 0.0000000 9.5040000 4.0730000 6.7890000 + 145 145 1 0.0000000 5.4310000 0.0000000 10.8620000 + 146 146 1 0.0000000 5.4310000 2.7150000 13.5770000 + 147 147 1 0.0000000 8.1460000 2.7150000 10.8620000 + 148 148 1 0.0000000 8.1460000 0.0000000 13.5770000 + 149 149 1 0.0000000 9.5040000 1.3580000 14.9350000 + 150 150 1 0.0000000 6.7890000 1.3580000 12.2200000 + 151 151 1 0.0000000 6.7890000 4.0730000 14.9350000 + 152 152 1 0.0000000 9.5040000 4.0730000 12.2200000 + 153 153 1 0.0000000 5.4310000 0.0000000 16.2930000 + 154 154 1 0.0000000 5.4310000 2.7150000 19.0080000 + 155 155 1 0.0000000 8.1460000 2.7150000 16.2930000 + 156 156 1 0.0000000 8.1460000 0.0000000 19.0080000 + 157 157 1 0.0000000 9.5040000 1.3580000 20.3660000 + 158 158 1 0.0000000 6.7890000 1.3580000 17.6510000 + 159 159 1 0.0000000 6.7890000 4.0730000 20.3660000 + 160 160 1 0.0000000 9.5040000 4.0730000 17.6510000 + 161 161 1 0.0000000 5.4310000 5.4310000 0.0000000 + 162 162 1 0.0000000 5.4310000 8.1460000 2.7150000 + 163 163 1 0.0000000 8.1460000 8.1460000 0.0000000 + 164 164 1 0.0000000 8.1460000 5.4310000 2.7150000 + 165 165 1 0.0000000 9.5040000 6.7890000 4.0730000 + 166 166 1 0.0000000 6.7890000 6.7890000 1.3580000 + 167 167 1 0.0000000 6.7890000 9.5040000 4.0730000 + 168 168 1 0.0000000 9.5040000 9.5040000 1.3580000 + 169 169 1 0.0000000 5.4310000 5.4310000 5.4310000 + 170 170 1 0.0000000 5.4310000 8.1460000 8.1460000 + 171 171 1 0.0000000 8.1460000 8.1460000 5.4310000 + 172 172 1 0.0000000 8.1460000 5.4310000 8.1460000 + 173 173 1 0.0000000 9.5040000 6.7890000 9.5040000 + 174 174 1 0.0000000 6.7890000 6.7890000 6.7890000 + 175 175 1 0.0000000 6.7890000 9.5040000 9.5040000 + 176 176 1 0.0000000 9.5040000 9.5040000 6.7890000 + 177 177 1 0.0000000 5.4310000 5.4310000 10.8620000 + 178 178 1 0.0000000 5.4310000 8.1460000 13.5770000 + 179 179 1 0.0000000 8.1460000 8.1460000 10.8620000 + 180 180 1 0.0000000 8.1460000 5.4310000 13.5770000 + 181 181 1 0.0000000 9.5040000 6.7890000 14.9350000 + 182 182 1 0.0000000 6.7890000 6.7890000 12.2200000 + 183 183 1 0.0000000 6.7890000 9.5040000 14.9350000 + 184 184 1 0.0000000 9.5040000 9.5040000 12.2200000 + 185 185 1 0.0000000 5.4310000 5.4310000 16.2930000 + 186 186 1 0.0000000 5.4310000 8.1460000 19.0080000 + 187 187 1 0.0000000 8.1460000 8.1460000 16.2930000 + 188 188 1 0.0000000 8.1460000 5.4310000 19.0080000 + 189 189 1 0.0000000 9.5040000 6.7890000 20.3660000 + 190 190 1 0.0000000 6.7890000 6.7890000 17.6510000 + 191 191 1 0.0000000 6.7890000 9.5040000 20.3660000 + 192 192 1 0.0000000 9.5040000 9.5040000 17.6510000 + 193 193 1 0.0000000 5.4310000 10.8620000 0.0000000 + 194 194 1 0.0000000 5.4310000 13.5770000 2.7150000 + 195 195 1 0.0000000 8.1460000 13.5770000 0.0000000 + 196 196 1 0.0000000 8.1460000 10.8620000 2.7150000 + 197 197 1 0.0000000 9.5040000 12.2200000 4.0730000 + 198 198 1 0.0000000 6.7890000 12.2200000 1.3580000 + 199 199 1 0.0000000 6.7890000 14.9350000 4.0730000 + 200 200 1 0.0000000 9.5040000 14.9350000 1.3580000 + 201 201 1 0.0000000 5.4310000 10.8620000 5.4310000 + 202 202 1 0.0000000 5.4310000 13.5770000 8.1460000 + 203 203 1 0.0000000 8.1460000 13.5770000 5.4310000 + 204 204 1 0.0000000 8.1460000 10.8620000 8.1460000 + 205 205 1 0.0000000 9.5040000 12.2200000 9.5040000 + 206 206 1 0.0000000 6.7890000 12.2200000 6.7890000 + 207 207 1 0.0000000 6.7890000 14.9350000 9.5040000 + 208 208 1 0.0000000 9.5040000 14.9350000 6.7890000 + 209 209 1 0.0000000 5.4310000 10.8620000 10.8620000 + 210 210 1 0.0000000 5.4310000 13.5770000 13.5770000 + 211 211 1 0.0000000 8.1460000 13.5770000 10.8620000 + 212 212 1 0.0000000 8.1460000 10.8620000 13.5770000 + 213 213 1 0.0000000 9.5040000 12.2200000 14.9350000 + 214 214 1 0.0000000 6.7890000 12.2200000 12.2200000 + 215 215 1 0.0000000 6.7890000 14.9350000 14.9350000 + 216 216 1 0.0000000 9.5040000 14.9350000 12.2200000 + 217 217 1 0.0000000 5.4310000 10.8620000 16.2930000 + 218 218 1 0.0000000 5.4310000 13.5770000 19.0080000 + 219 219 1 0.0000000 8.1460000 13.5770000 16.2930000 + 220 220 1 0.0000000 8.1460000 10.8620000 19.0080000 + 221 221 1 0.0000000 9.5040000 12.2200000 20.3660000 + 222 222 1 0.0000000 6.7890000 12.2200000 17.6510000 + 223 223 1 0.0000000 6.7890000 14.9350000 20.3660000 + 224 224 1 0.0000000 9.5040000 14.9350000 17.6510000 + 225 225 1 0.0000000 5.4310000 16.2930000 0.0000000 + 226 226 1 0.0000000 5.4310000 19.0080000 2.7150000 + 227 227 1 0.0000000 8.1460000 19.0080000 0.0000000 + 228 228 1 0.0000000 8.1460000 16.2930000 2.7150000 + 229 229 1 0.0000000 9.5040000 17.6510000 4.0730000 + 230 230 1 0.0000000 6.7890000 17.6510000 1.3580000 + 231 231 1 0.0000000 6.7890000 20.3660000 4.0730000 + 232 232 1 0.0000000 9.5040000 20.3660000 1.3580000 + 233 233 1 0.0000000 5.4310000 16.2930000 5.4310000 + 234 234 1 0.0000000 5.4310000 19.0080000 8.1460000 + 235 235 1 0.0000000 8.1460000 19.0080000 5.4310000 + 236 236 1 0.0000000 8.1460000 16.2930000 8.1460000 + 237 237 1 0.0000000 9.5040000 17.6510000 9.5040000 + 238 238 1 0.0000000 6.7890000 17.6510000 6.7890000 + 239 239 1 0.0000000 6.7890000 20.3660000 9.5040000 + 240 240 1 0.0000000 9.5040000 20.3660000 6.7890000 + 241 241 1 0.0000000 5.4310000 16.2930000 10.8620000 + 242 242 1 0.0000000 5.4310000 19.0080000 13.5770000 + 243 243 1 0.0000000 8.1460000 19.0080000 10.8620000 + 244 244 1 0.0000000 8.1460000 16.2930000 13.5770000 + 245 245 1 0.0000000 9.5040000 17.6510000 14.9350000 + 246 246 1 0.0000000 6.7890000 17.6510000 12.2200000 + 247 247 1 0.0000000 6.7890000 20.3660000 14.9350000 + 248 248 1 0.0000000 9.5040000 20.3660000 12.2200000 + 249 249 1 0.0000000 5.4310000 16.2930000 16.2930000 + 250 250 1 0.0000000 5.4310000 19.0080000 19.0080000 + 251 251 1 0.0000000 8.1460000 19.0080000 16.2930000 + 252 252 1 0.0000000 8.1460000 16.2930000 19.0080000 + 253 253 1 0.0000000 9.5040000 17.6510000 20.3660000 + 254 254 1 0.0000000 6.7890000 17.6510000 17.6510000 + 255 255 1 0.0000000 6.7890000 20.3660000 20.3660000 + 256 256 1 0.0000000 9.5040000 20.3660000 17.6510000 + 257 257 1 0.0000000 10.8620000 0.0000000 0.0000000 + 258 258 1 0.0000000 10.8620000 2.7150000 2.7150000 + 259 259 1 0.0000000 13.5770000 2.7150000 0.0000000 + 260 260 1 0.0000000 13.5770000 0.0000000 2.7150000 + 261 261 1 0.0000000 14.9350000 1.3580000 4.0730000 + 262 262 1 0.0000000 12.2200000 1.3580000 1.3580000 + 263 263 1 0.0000000 12.2200000 4.0730000 4.0730000 + 264 264 1 0.0000000 14.9350000 4.0730000 1.3580000 + 265 265 1 0.0000000 10.8620000 0.0000000 5.4310000 + 266 266 1 0.0000000 10.8620000 2.7150000 8.1460000 + 267 267 1 0.0000000 13.5770000 2.7150000 5.4310000 + 268 268 1 0.0000000 13.5770000 0.0000000 8.1460000 + 269 269 1 0.0000000 14.9350000 1.3580000 9.5040000 + 270 270 1 0.0000000 12.2200000 1.3580000 6.7890000 + 271 271 1 0.0000000 12.2200000 4.0730000 9.5040000 + 272 272 1 0.0000000 14.9350000 4.0730000 6.7890000 + 273 273 1 0.0000000 10.8620000 0.0000000 10.8620000 + 274 274 1 0.0000000 10.8620000 2.7150000 13.5770000 + 275 275 1 0.0000000 13.5770000 2.7150000 10.8620000 + 276 276 1 0.0000000 13.5770000 0.0000000 13.5770000 + 277 277 1 0.0000000 14.9350000 1.3580000 14.9350000 + 278 278 1 0.0000000 12.2200000 1.3580000 12.2200000 + 279 279 1 0.0000000 12.2200000 4.0730000 14.9350000 + 280 280 1 0.0000000 14.9350000 4.0730000 12.2200000 + 281 281 1 0.0000000 10.8620000 0.0000000 16.2930000 + 282 282 1 0.0000000 10.8620000 2.7150000 19.0080000 + 283 283 1 0.0000000 13.5770000 2.7150000 16.2930000 + 284 284 1 0.0000000 13.5770000 0.0000000 19.0080000 + 285 285 1 0.0000000 14.9350000 1.3580000 20.3660000 + 286 286 1 0.0000000 12.2200000 1.3580000 17.6510000 + 287 287 1 0.0000000 12.2200000 4.0730000 20.3660000 + 288 288 1 0.0000000 14.9350000 4.0730000 17.6510000 + 289 289 1 0.0000000 10.8620000 5.4310000 0.0000000 + 290 290 1 0.0000000 10.8620000 8.1460000 2.7150000 + 291 291 1 0.0000000 13.5770000 8.1460000 0.0000000 + 292 292 1 0.0000000 13.5770000 5.4310000 2.7150000 + 293 293 1 0.0000000 14.9350000 6.7890000 4.0730000 + 294 294 1 0.0000000 12.2200000 6.7890000 1.3580000 + 295 295 1 0.0000000 12.2200000 9.5040000 4.0730000 + 296 296 1 0.0000000 14.9350000 9.5040000 1.3580000 + 297 297 1 0.0000000 10.8620000 5.4310000 5.4310000 + 298 298 1 0.0000000 10.8620000 8.1460000 8.1460000 + 299 299 1 0.0000000 13.5770000 8.1460000 5.4310000 + 300 300 1 0.0000000 13.5770000 5.4310000 8.1460000 + 301 301 1 0.0000000 14.9350000 6.7890000 9.5040000 + 302 302 1 0.0000000 12.2200000 6.7890000 6.7890000 + 303 303 1 0.0000000 12.2200000 9.5040000 9.5040000 + 304 304 1 0.0000000 14.9350000 9.5040000 6.7890000 + 305 305 1 0.0000000 10.8620000 5.4310000 10.8620000 + 306 306 1 0.0000000 10.8620000 8.1460000 13.5770000 + 307 307 1 0.0000000 13.5770000 8.1460000 10.8620000 + 308 308 1 0.0000000 13.5770000 5.4310000 13.5770000 + 309 309 1 0.0000000 14.9350000 6.7890000 14.9350000 + 310 310 1 0.0000000 12.2200000 6.7890000 12.2200000 + 311 311 1 0.0000000 12.2200000 9.5040000 14.9350000 + 312 312 1 0.0000000 14.9350000 9.5040000 12.2200000 + 313 313 1 0.0000000 10.8620000 5.4310000 16.2930000 + 314 314 1 0.0000000 10.8620000 8.1460000 19.0080000 + 315 315 1 0.0000000 13.5770000 8.1460000 16.2930000 + 316 316 1 0.0000000 13.5770000 5.4310000 19.0080000 + 317 317 1 0.0000000 14.9350000 6.7890000 20.3660000 + 318 318 1 0.0000000 12.2200000 6.7890000 17.6510000 + 319 319 1 0.0000000 12.2200000 9.5040000 20.3660000 + 320 320 1 0.0000000 14.9350000 9.5040000 17.6510000 + 321 321 1 0.0000000 10.8620000 10.8620000 0.0000000 + 322 322 1 0.0000000 10.8620000 13.5770000 2.7150000 + 323 323 1 0.0000000 13.5770000 13.5770000 0.0000000 + 324 324 1 0.0000000 13.5770000 10.8620000 2.7150000 + 325 325 1 0.0000000 14.9350000 12.2200000 4.0730000 + 326 326 1 0.0000000 12.2200000 12.2200000 1.3580000 + 327 327 1 0.0000000 12.2200000 14.9350000 4.0730000 + 328 328 1 0.0000000 14.9350000 14.9350000 1.3580000 + 329 329 1 0.0000000 10.8620000 10.8620000 5.4310000 + 330 330 1 0.0000000 10.8620000 13.5770000 8.1460000 + 331 331 1 0.0000000 13.5770000 13.5770000 5.4310000 + 332 332 1 0.0000000 13.5770000 10.8620000 8.1460000 + 333 333 1 0.0000000 14.9350000 12.2200000 9.5040000 + 334 334 1 0.0000000 12.2200000 12.2200000 6.7890000 + 335 335 1 0.0000000 12.2200000 14.9350000 9.5040000 + 336 336 1 0.0000000 14.9350000 14.9350000 6.7890000 + 337 337 1 0.0000000 10.8620000 10.8620000 10.8620000 + 338 338 1 0.0000000 10.8620000 13.5770000 13.5770000 + 339 339 1 0.0000000 13.5770000 13.5770000 10.8620000 + 340 340 1 0.0000000 13.5770000 10.8620000 13.5770000 + 341 341 1 0.0000000 14.9350000 12.2200000 14.9350000 + 342 342 1 0.0000000 12.2200000 12.2200000 12.2200000 + 343 343 1 0.0000000 12.2200000 14.9350000 14.9350000 + 344 344 1 0.0000000 14.9350000 14.9350000 12.2200000 + 345 345 1 0.0000000 10.8620000 10.8620000 16.2930000 + 346 346 1 0.0000000 10.8620000 13.5770000 19.0080000 + 347 347 1 0.0000000 13.5770000 13.5770000 16.2930000 + 348 348 1 0.0000000 13.5770000 10.8620000 19.0080000 + 349 349 1 0.0000000 14.9350000 12.2200000 20.3660000 + 350 350 1 0.0000000 12.2200000 12.2200000 17.6510000 + 351 351 1 0.0000000 12.2200000 14.9350000 20.3660000 + 352 352 1 0.0000000 14.9350000 14.9350000 17.6510000 + 353 353 1 0.0000000 10.8620000 16.2930000 0.0000000 + 354 354 1 0.0000000 10.8620000 19.0080000 2.7150000 + 355 355 1 0.0000000 13.5770000 19.0080000 0.0000000 + 356 356 1 0.0000000 13.5770000 16.2930000 2.7150000 + 357 357 1 0.0000000 14.9350000 17.6510000 4.0730000 + 358 358 1 0.0000000 12.2200000 17.6510000 1.3580000 + 359 359 1 0.0000000 12.2200000 20.3660000 4.0730000 + 360 360 1 0.0000000 14.9350000 20.3660000 1.3580000 + 361 361 1 0.0000000 10.8620000 16.2930000 5.4310000 + 362 362 1 0.0000000 10.8620000 19.0080000 8.1460000 + 363 363 1 0.0000000 13.5770000 19.0080000 5.4310000 + 364 364 1 0.0000000 13.5770000 16.2930000 8.1460000 + 365 365 1 0.0000000 14.9350000 17.6510000 9.5040000 + 366 366 1 0.0000000 12.2200000 17.6510000 6.7890000 + 367 367 1 0.0000000 12.2200000 20.3660000 9.5040000 + 368 368 1 0.0000000 14.9350000 20.3660000 6.7890000 + 369 369 1 0.0000000 10.8620000 16.2930000 10.8620000 + 370 370 1 0.0000000 10.8620000 19.0080000 13.5770000 + 371 371 1 0.0000000 13.5770000 19.0080000 10.8620000 + 372 372 1 0.0000000 13.5770000 16.2930000 13.5770000 + 373 373 1 0.0000000 14.9350000 17.6510000 14.9350000 + 374 374 1 0.0000000 12.2200000 17.6510000 12.2200000 + 375 375 1 0.0000000 12.2200000 20.3660000 14.9350000 + 376 376 1 0.0000000 14.9350000 20.3660000 12.2200000 + 377 377 1 0.0000000 10.8620000 16.2930000 16.2930000 + 378 378 1 0.0000000 10.8620000 19.0080000 19.0080000 + 379 379 1 0.0000000 13.5770000 19.0080000 16.2930000 + 380 380 1 0.0000000 13.5770000 16.2930000 19.0080000 + 381 381 1 0.0000000 14.9350000 17.6510000 20.3660000 + 382 382 1 0.0000000 12.2200000 17.6510000 17.6510000 + 383 383 1 0.0000000 12.2200000 20.3660000 20.3660000 + 384 384 1 0.0000000 14.9350000 20.3660000 17.6510000 + 385 385 1 0.0000000 16.2930000 0.0000000 0.0000000 + 386 386 1 0.0000000 16.2930000 2.7150000 2.7150000 + 387 387 1 0.0000000 19.0080000 2.7150000 0.0000000 + 388 388 1 0.0000000 19.0080000 0.0000000 2.7150000 + 389 389 1 0.0000000 20.3660000 1.3580000 4.0730000 + 390 390 1 0.0000000 17.6510000 1.3580000 1.3580000 + 391 391 1 0.0000000 17.6510000 4.0730000 4.0730000 + 392 392 1 0.0000000 20.3660000 4.0730000 1.3580000 + 393 393 1 0.0000000 16.2930000 0.0000000 5.4310000 + 394 394 1 0.0000000 16.2930000 2.7150000 8.1460000 + 395 395 1 0.0000000 19.0080000 2.7150000 5.4310000 + 396 396 1 0.0000000 19.0080000 0.0000000 8.1460000 + 397 397 1 0.0000000 20.3660000 1.3580000 9.5040000 + 398 398 1 0.0000000 17.6510000 1.3580000 6.7890000 + 399 399 1 0.0000000 17.6510000 4.0730000 9.5040000 + 400 400 1 0.0000000 20.3660000 4.0730000 6.7890000 + 401 401 1 0.0000000 16.2930000 0.0000000 10.8620000 + 402 402 1 0.0000000 16.2930000 2.7150000 13.5770000 + 403 403 1 0.0000000 19.0080000 2.7150000 10.8620000 + 404 404 1 0.0000000 19.0080000 0.0000000 13.5770000 + 405 405 1 0.0000000 20.3660000 1.3580000 14.9350000 + 406 406 1 0.0000000 17.6510000 1.3580000 12.2200000 + 407 407 1 0.0000000 17.6510000 4.0730000 14.9350000 + 408 408 1 0.0000000 20.3660000 4.0730000 12.2200000 + 409 409 1 0.0000000 16.2930000 0.0000000 16.2930000 + 410 410 1 0.0000000 16.2930000 2.7150000 19.0080000 + 411 411 1 0.0000000 19.0080000 2.7150000 16.2930000 + 412 412 1 0.0000000 19.0080000 0.0000000 19.0080000 + 413 413 1 0.0000000 20.3660000 1.3580000 20.3660000 + 414 414 1 0.0000000 17.6510000 1.3580000 17.6510000 + 415 415 1 0.0000000 17.6510000 4.0730000 20.3660000 + 416 416 1 0.0000000 20.3660000 4.0730000 17.6510000 + 417 417 1 0.0000000 16.2930000 5.4310000 0.0000000 + 418 418 1 0.0000000 16.2930000 8.1460000 2.7150000 + 419 419 1 0.0000000 19.0080000 8.1460000 0.0000000 + 420 420 1 0.0000000 19.0080000 5.4310000 2.7150000 + 421 421 1 0.0000000 20.3660000 6.7890000 4.0730000 + 422 422 1 0.0000000 17.6510000 6.7890000 1.3580000 + 423 423 1 0.0000000 17.6510000 9.5040000 4.0730000 + 424 424 1 0.0000000 20.3660000 9.5040000 1.3580000 + 425 425 1 0.0000000 16.2930000 5.4310000 5.4310000 + 426 426 1 0.0000000 16.2930000 8.1460000 8.1460000 + 427 427 1 0.0000000 19.0080000 8.1460000 5.4310000 + 428 428 1 0.0000000 19.0080000 5.4310000 8.1460000 + 429 429 1 0.0000000 20.3660000 6.7890000 9.5040000 + 430 430 1 0.0000000 17.6510000 6.7890000 6.7890000 + 431 431 1 0.0000000 17.6510000 9.5040000 9.5040000 + 432 432 1 0.0000000 20.3660000 9.5040000 6.7890000 + 433 433 1 0.0000000 16.2930000 5.4310000 10.8620000 + 434 434 1 0.0000000 16.2930000 8.1460000 13.5770000 + 435 435 1 0.0000000 19.0080000 8.1460000 10.8620000 + 436 436 1 0.0000000 19.0080000 5.4310000 13.5770000 + 437 437 1 0.0000000 20.3660000 6.7890000 14.9350000 + 438 438 1 0.0000000 17.6510000 6.7890000 12.2200000 + 439 439 1 0.0000000 17.6510000 9.5040000 14.9350000 + 440 440 1 0.0000000 20.3660000 9.5040000 12.2200000 + 441 441 1 0.0000000 16.2930000 5.4310000 16.2930000 + 442 442 1 0.0000000 16.2930000 8.1460000 19.0080000 + 443 443 1 0.0000000 19.0080000 8.1460000 16.2930000 + 444 444 1 0.0000000 19.0080000 5.4310000 19.0080000 + 445 445 1 0.0000000 20.3660000 6.7890000 20.3660000 + 446 446 1 0.0000000 17.6510000 6.7890000 17.6510000 + 447 447 1 0.0000000 17.6510000 9.5040000 20.3660000 + 448 448 1 0.0000000 20.3660000 9.5040000 17.6510000 + 449 449 1 0.0000000 16.2930000 10.8620000 0.0000000 + 450 450 1 0.0000000 16.2930000 13.5770000 2.7150000 + 451 451 1 0.0000000 19.0080000 13.5770000 0.0000000 + 452 452 1 0.0000000 19.0080000 10.8620000 2.7150000 + 453 453 1 0.0000000 20.3660000 12.2200000 4.0730000 + 454 454 1 0.0000000 17.6510000 12.2200000 1.3580000 + 455 455 1 0.0000000 17.6510000 14.9350000 4.0730000 + 456 456 1 0.0000000 20.3660000 14.9350000 1.3580000 + 457 457 1 0.0000000 16.2930000 10.8620000 5.4310000 + 458 458 1 0.0000000 16.2930000 13.5770000 8.1460000 + 459 459 1 0.0000000 19.0080000 13.5770000 5.4310000 + 460 460 1 0.0000000 19.0080000 10.8620000 8.1460000 + 461 461 1 0.0000000 20.3660000 12.2200000 9.5040000 + 462 462 1 0.0000000 17.6510000 12.2200000 6.7890000 + 463 463 1 0.0000000 17.6510000 14.9350000 9.5040000 + 464 464 1 0.0000000 20.3660000 14.9350000 6.7890000 + 465 465 1 0.0000000 16.2930000 10.8620000 10.8620000 + 466 466 1 0.0000000 16.2930000 13.5770000 13.5770000 + 467 467 1 0.0000000 19.0080000 13.5770000 10.8620000 + 468 468 1 0.0000000 19.0080000 10.8620000 13.5770000 + 469 469 1 0.0000000 20.3660000 12.2200000 14.9350000 + 470 470 1 0.0000000 17.6510000 12.2200000 12.2200000 + 471 471 1 0.0000000 17.6510000 14.9350000 14.9350000 + 472 472 1 0.0000000 20.3660000 14.9350000 12.2200000 + 473 473 1 0.0000000 16.2930000 10.8620000 16.2930000 + 474 474 1 0.0000000 16.2930000 13.5770000 19.0080000 + 475 475 1 0.0000000 19.0080000 13.5770000 16.2930000 + 476 476 1 0.0000000 19.0080000 10.8620000 19.0080000 + 477 477 1 0.0000000 20.3660000 12.2200000 20.3660000 + 478 478 1 0.0000000 17.6510000 12.2200000 17.6510000 + 479 479 1 0.0000000 17.6510000 14.9350000 20.3660000 + 480 480 1 0.0000000 20.3660000 14.9350000 17.6510000 + 481 481 1 0.0000000 16.2930000 16.2930000 0.0000000 + 482 482 1 0.0000000 16.2930000 19.0080000 2.7150000 + 483 483 1 0.0000000 19.0080000 19.0080000 0.0000000 + 484 484 1 0.0000000 19.0080000 16.2930000 2.7150000 + 485 485 1 0.0000000 20.3660000 17.6510000 4.0730000 + 486 486 1 0.0000000 17.6510000 17.6510000 1.3580000 + 487 487 1 0.0000000 17.6510000 20.3660000 4.0730000 + 488 488 1 0.0000000 20.3660000 20.3660000 1.3580000 + 489 489 1 0.0000000 16.2930000 16.2930000 5.4310000 + 490 490 1 0.0000000 16.2930000 19.0080000 8.1460000 + 491 491 1 0.0000000 19.0080000 19.0080000 5.4310000 + 492 492 1 0.0000000 19.0080000 16.2930000 8.1460000 + 493 493 1 0.0000000 20.3660000 17.6510000 9.5040000 + 494 494 1 0.0000000 17.6510000 17.6510000 6.7890000 + 495 495 1 0.0000000 17.6510000 20.3660000 9.5040000 + 496 496 1 0.0000000 20.3660000 20.3660000 6.7890000 + 497 497 1 0.0000000 16.2930000 16.2930000 10.8620000 + 498 498 1 0.0000000 16.2930000 19.0080000 13.5770000 + 499 499 1 0.0000000 19.0080000 19.0080000 10.8620000 + 500 500 1 0.0000000 19.0080000 16.2930000 13.5770000 + 501 501 1 0.0000000 20.3660000 17.6510000 14.9350000 + 502 502 1 0.0000000 17.6510000 17.6510000 12.2200000 + 503 503 1 0.0000000 17.6510000 20.3660000 14.9350000 + 504 504 1 0.0000000 20.3660000 20.3660000 12.2200000 + 505 505 1 0.0000000 16.2930000 16.2930000 16.2930000 + 506 506 1 0.0000000 16.2930000 19.0080000 19.0080000 + 507 507 1 0.0000000 19.0080000 19.0080000 16.2930000 + 508 508 1 0.0000000 19.0080000 16.2930000 19.0080000 + 509 509 1 0.0000000 20.3660000 17.6510000 20.3660000 + 510 510 1 0.0000000 17.6510000 17.6510000 17.6510000 + 511 511 1 0.0000000 17.6510000 20.3660000 20.3660000 + 512 512 1 0.0000000 20.3660000 20.3660000 17.6510000 + diff --git a/examples/USER/phonon/third_order_command/lmp_bank/silicon_8.lmp b/examples/USER/phonon/third_order_command/lmp_bank/silicon_8.lmp new file mode 100755 index 0000000000..5066049895 --- /dev/null +++ b/examples/USER/phonon/third_order_command/lmp_bank/silicon_8.lmp @@ -0,0 +1,29 @@ +LAMMPS description + + 8 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 5.4310000 xlo xhi + 0.0000000 5.4310000 ylo yhi + 0.0000000 5.4310000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 1.3577500 1.3577500 1.3572000 + 3 3 1 0.0000000 2.7155000 2.7155000 0.0000000 + 4 4 1 0.0000000 4.0732500 4.0732500 1.3572000 + 5 5 1 0.0000000 2.7155000 0.0000000 2.7144000 + 6 6 1 0.0000000 4.0732500 1.3577500 4.0732500 + 7 7 1 0.0000000 0.0000000 2.7155000 2.7155000 + 8 8 1 0.0000000 1.3577500 4.0732500 4.0732500 diff --git a/examples/USER/phonon/third_order_command/results/out.silicon b/examples/USER/phonon/third_order_command/results/out.silicon new file mode 100755 index 0000000000..0729dc549c --- /dev/null +++ b/examples/USER/phonon/third_order_command/results/out.silicon @@ -0,0 +1,58 @@ +LAMMPS (16 Jul 2018) +Reading data file ... + orthogonal box = (0 0 0) to (5.431 5.431 5.431) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 8 atoms +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 0 = max # of 1-2 neighbors + 0 = max # of 1-3 neighbors + 0 = max # of 1-4 neighbors + 1 = max # of special neighbors +Neighbor list info ... + update every 1 steps, delay 10 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 4 + ghost atom cutoff = 4 + binsize = 2, bins = 3 3 3 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair tersoff, perpetual + attributes: full, newton on + pair build: full/bin + stencil: full/bin/3d + bin: standard +Calculating Anharmonic Dynamical Matrix... +Third Order calculation took 0.043923 seconds +Finished Calculating Third Order Tensor +Loop time of 1.22619e+06 on 4 procs for 0 steps with 8 atoms + +0.0% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.013707 | 0.016582 | 0.019588 | 2.2 | 0.00 +Bond | 8.1341e-05 | 8.7207e-05 | 9.3228e-05 | 0.0 | 0.00 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.019285 | 0.022435 | 0.025684 | 2.0 | 0.00 +Output | 0 | 0 | 0 | 0.0 | 0.00 +Modify | 0 | 0 | 0 | 0.0 | 0.00 +Other | | 1.226e+06 | | |100.00 + +Nlocal: 2 ave 2 max 2 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Nghost: 56 ave 56 max 56 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 32 ave 32 max 32 min +Histogram: 4 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 128 +Ave neighs/atom = 16 +Ave special neighs/atom = 0 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/USER/phonon/third_order_command/results/third_order b/examples/USER/phonon/third_order_command/results/third_order new file mode 100755 index 0000000000..276896aa1f --- /dev/null +++ b/examples/USER/phonon/third_order_command/results/third_order @@ -0,0 +1,4608 @@ +1 1 1 1 1 -0.08569589 0.16067980 137.35980742 +1 1 1 1 2 -74170.35399415 -67130.60762609 -67084.85673024 +1 1 1 1 3 -0.10711987 -0.00000000 -5.61308111 +1 1 1 1 4 74170.34328216 67130.75759390 -67084.54608262 +1 1 1 1 5 -0.00000000 -0.00000000 -15.01820557 +1 1 1 1 6 74116.35486843 -67012.24017136 67025.88724261 +1 1 1 1 7 -0.00000000 -0.00000000 1.11404663 +1 1 1 1 8 -74116.23703657 67011.98308368 67025.60873095 +1 1 1 2 1 -0.23566371 -0.27851166 329269.69018077 +1 1 1 2 2 -72106.38979127 -72095.95631608 -80899.99905481 +1 1 1 2 3 -0.05355993 -0.00000000 -11783.78540967 +1 1 1 2 4 72106.62545498 72096.21340376 -80900.41682229 +1 1 1 2 5 -0.03213596 -0.00000000 2960.49323056 +1 1 1 2 6 -71998.20943604 72010.66747675 -80803.98751664 +1 1 1 2 7 0.02142397 -0.00000000 2961.59656521 +1 1 1 2 8 71998.19872405 -72010.69961271 -80803.91253273 +1 1 1 3 1 141.59104222 329281.45194233 0.41776749 +1 1 1 3 2 -72074.53234237 -80911.53586465 -72064.09886718 +1 1 1 3 3 3.98485911 2969.85550707 0.02142397 +1 1 1 3 4 -72074.54305436 -80911.38589683 72064.09886718 +1 1 1 3 5 -9.64078817 -11781.34307667 0.02142397 +1 1 1 3 6 72006.30769810 -80801.86654325 72002.14073522 +1 1 1 3 7 0.14996782 2957.19393861 0.04284795 +1 1 1 3 8 72006.66119367 -80802.35929464 -72002.55850270 +1 2 1 1 1 -0.40705550 -0.47132742 329270.04367633 +1 2 1 1 2 -72106.28267140 -72095.84919621 -80899.90264692 +1 2 1 1 3 -0.01071199 0.02142397 -11783.93537749 +1 2 1 1 4 72106.66830293 72096.21340376 -80900.26685448 +1 2 1 1 5 0.02142397 -0.04284795 2960.53607851 +1 2 1 1 6 -71998.40225180 72010.90314046 -80804.15890843 +1 2 1 1 7 0.02142397 -0.00000000 2961.59656521 +1 2 1 1 8 71998.34869187 -72010.95670040 -80804.09463651 +1 2 1 2 1 -0.04284795 0.67485517 115.02531483 +1 2 1 2 2 -67122.33797224 -74173.02127888 -67083.27135618 +1 2 1 2 3 -0.02142397 -0.00000000 -9.94072380 +1 2 1 2 4 67121.93091674 74172.77490318 -67083.11067638 +1 2 1 2 5 0.05355993 0.06427192 9.89787585 +1 2 1 2 6 67020.89545674 -74109.38136498 67027.62258448 +1 2 1 2 7 0.02142397 0.05355993 -3.84560328 +1 2 1 2 8 -67020.63836905 74109.15641326 67027.31193686 +1 2 1 3 1 329282.72666877 112.65796573 -0.08569589 +1 2 1 3 2 -80915.37075594 -72065.54498540 -72064.36666685 +1 2 1 3 3 2970.09117078 3.04220427 0.14996782 +1 2 1 3 4 -80913.63541407 -72065.98417686 72064.89155420 +1 2 1 3 5 2958.71504075 -9.59794022 -0.14996782 +1 2 1 3 6 -80800.75249661 72013.73110499 -72002.46209482 +1 2 1 3 7 -11780.59323759 -2.52802890 -0.67485517 +1 2 1 3 8 -80801.13812814 72014.00961665 72002.82630238 +1 3 1 1 1 140.26275585 329282.54456499 0.53559934 +1 3 1 1 2 -72074.61803826 -80911.60013657 -72064.25954698 +1 3 1 1 3 3.90987520 2969.74838720 -0.02142397 +1 3 1 1 4 -72074.26454270 -80911.32162491 72063.88462744 +1 3 1 1 5 -9.58722823 -11781.32165269 0.04284795 +1 3 1 1 6 72007.00397725 -80802.53068643 72002.74060648 +1 3 1 1 7 0.06427192 2957.16180265 -0.00000000 +1 3 1 1 8 72007.17536904 -80802.77706213 -72002.90128628 +1 3 1 2 1 329282.94090850 111.04045572 0.63200722 +1 3 1 2 2 -80915.52072376 -72065.59854533 -72064.48449870 +1 3 1 2 3 2969.99476290 2.93508440 -0.04284795 +1 3 1 2 4 -80913.01411883 -72065.17006586 72064.14171512 +1 3 1 2 5 2958.13659346 -10.43347519 0.42847947 +1 3 1 2 6 -80801.11670417 72014.05246460 -72002.80487840 +1 3 1 2 7 -11780.50754169 -2.72084466 -0.54631133 +1 3 1 2 8 -80800.85961648 72016.01275819 72002.63348661 +1 3 1 3 1 0.29993563 0.22495172 -12.59729654 +1 3 1 3 2 -67096.11502842 -67094.33683860 -74102.86847698 +1 3 1 3 3 -0.02142397 -0.04284795 1.13547061 +1 3 1 3 4 67095.81509279 67094.12259887 -74102.69708519 +1 3 1 3 5 -0.01071199 0.02142397 6.64143185 +1 3 1 3 6 67033.98550467 -67031.45747577 74105.22511409 +1 3 1 3 7 0.06427192 0.04284795 -0.27851166 +1 3 1 3 8 -67033.98550467 67031.28608399 74105.19297812 +1 1 2 1 1 -74175.17438824 -72109.17490785 -72075.08936569 +1 1 2 1 2 74174.06034160 72107.35387009 72071.88648162 +1 1 2 1 3 -0.43919146 538.62012295 1558.31557547 +1 1 2 1 4 -0.35349557 -538.98433050 -1559.15111044 +1 1 2 1 5 -0.36420755 1559.70813376 538.94148255 +1 1 2 1 6 -0.12854384 -1560.65078860 -539.26284216 +1 1 2 1 7 -9470.57469669 -3063.11406462 -3059.55768498 +1 1 2 1 8 9472.97418175 3066.31694869 3063.78891979 +1 1 2 2 1 -67136.04931541 -72094.55304580 -80912.33926366 +1 1 2 2 2 72108.78927633 67119.37075188 80912.66062327 +1 1 2 2 3 0.12854384 -537.80601195 3074.38307479 +1 1 2 2 4 538.66297089 -0.51417537 -3074.31880286 +1 1 2 2 5 -888.64500536 3068.44863407 94.71538776 +1 1 2 2 6 -1558.04777580 -0.68556716 -3077.83233455 +1 1 2 2 7 -1.34971034 1557.43719255 3075.86132897 +1 1 2 2 8 -3063.41400025 888.27008582 -93.10858973 +1 1 2 3 1 -67090.58764320 -80900.65248600 -72062.44922120 +1 1 2 3 2 72070.46178737 80911.33233690 67094.67962218 +1 1 2 3 3 -893.59394329 83.29640977 3055.78706561 +1 1 2 3 4 -1559.26894230 -3074.61873850 -0.59987126 +1 1 2 3 5 0.09640788 3080.91738677 -536.26348584 +1 1 2 3 6 535.97426219 -3081.11020253 0.40705550 +1 1 2 3 7 2.59230082 3075.91488891 1559.82596561 +1 1 2 3 8 -3065.72778941 -94.97247544 888.65571735 +1 2 2 1 1 -72106.94681459 -67126.03360770 -80913.12123870 +1 2 2 1 2 67141.76951639 72094.19955023 80912.06075200 +1 2 2 1 3 -539.33782607 0.81411100 3074.21168300 +1 2 2 1 4 -0.52488736 538.66297089 -3074.36165081 +1 2 2 1 5 1559.22609435 1.82103777 3080.51033127 +1 2 2 1 6 888.24866185 -3063.37115230 -93.06574178 +1 2 2 1 7 3058.20797464 -887.99157416 91.65175952 +1 2 2 1 8 -0.68556716 -1558.01563984 -3077.80019859 +1 2 2 2 1 -72096.51333939 -74176.32057083 -72068.06230231 +1 2 2 2 2 72097.11321066 74179.99478232 72069.75479623 +1 2 2 2 3 539.58420176 0.83553497 1559.92237350 +1 2 2 2 4 -539.03789043 -0.38563153 -1559.19395839 +1 2 2 2 5 -3068.12727446 -9477.28040046 -3066.73471617 +1 2 2 2 6 3066.27410074 9473.03845367 3063.79963178 +1 2 2 2 7 1561.40062768 0.28922365 539.62704971 +1 2 2 2 8 -1560.62936463 -0.13925583 -539.18785825 +1 2 2 3 1 -80898.98141606 -67086.42068032 -72061.12093483 +1 2 2 3 2 80909.30777138 72063.89533942 67096.43638803 +1 2 2 3 3 82.96433818 -893.33685560 3055.82991356 +1 2 2 3 4 -3074.65087446 -1559.32250223 -0.51417537 +1 2 2 3 5 3079.44984457 2.18524532 1557.22295281 +1 2 2 3 6 -94.92962749 -3065.77063736 888.60215741 +1 2 2 3 7 3077.91803045 2.61372479 -536.88478108 +1 2 2 3 8 -3081.11020253 535.98497418 0.33207159 +1 3 2 1 1 -72074.61803826 -80912.03932803 -67095.49373318 +1 3 2 1 2 67095.17237358 80902.98769914 72062.60990100 +1 3 2 1 3 1560.09376528 3074.55446658 0.55702332 +1 3 2 1 4 893.75462309 -83.27498580 -3055.65852177 +1 3 2 1 5 -535.98497418 3081.32444227 0.36420755 +1 3 2 1 6 -1.04977471 -3079.24631682 536.43487763 +1 3 2 1 7 3063.56396806 94.23334835 -889.21274066 +1 3 2 1 8 -1.07119869 -3078.63573357 -1559.47247005 +1 3 2 2 1 -80910.85029749 -72067.94447046 -67097.26121101 +1 3 2 2 2 80903.20193888 67084.63177851 72063.35974008 +1 3 2 2 3 3074.38307479 1558.70120699 0.29993563 +1 3 2 2 4 -83.26427381 893.74391110 -3055.63709779 +1 3 2 2 5 95.32597101 3067.67737102 -887.93801423 +1 3 2 2 6 -3078.63573357 -1.07119869 -1559.49389402 +1 3 2 2 7 3079.13919695 -534.68882377 0.25708768 +1 3 2 2 8 -3079.24631682 -1.03906272 536.42416564 +1 3 2 3 1 -72064.05601923 -72064.52734665 -74113.78399158 +1 3 2 3 2 72063.22048425 72066.00560083 74113.03415250 +1 3 2 3 3 -3055.10149845 -3055.55140190 -9478.75865465 +1 3 2 3 4 3055.31573819 3055.31573819 9478.65153478 +1 3 2 3 5 539.07002640 1555.42333902 -1.69249392 +1 3 2 3 6 -538.30947533 -1556.36599386 2.82796453 +1 3 2 3 7 1556.32314591 538.11665957 -3.12790016 +1 3 2 3 8 -1556.38741783 -538.30947533 2.82796453 +1 1 3 1 1 -0.04284795 -0.11783186 8.28036584 +1 1 3 1 2 -0.59987126 -0.00000000 -897.62165034 +1 1 3 1 3 0.01071199 0.02142397 8.03399014 +1 1 3 1 4 0.71770312 -0.08569589 -897.27886676 +1 1 3 1 5 0.05355993 0.04284795 2.27094121 +1 1 3 1 6 -0.68556716 -0.10711987 887.72377449 +1 1 3 1 7 -0.02142397 -0.00000000 1.26401445 +1 1 3 1 8 0.66414318 0.06427192 887.68092654 +1 1 3 2 1 -0.02142397 0.08569589 2968.58078064 +1 1 3 2 2 538.32018732 -538.32018732 85.43880714 +1 1 3 2 3 0.01071199 0.02142397 2968.54864468 +1 1 3 2 4 -538.30947533 538.32018732 85.52450304 +1 1 3 2 5 -0.06427192 -0.06427192 -3372.04776546 +1 1 3 2 6 538.38445924 538.25591539 89.29512241 +1 1 3 2 7 0.02142397 0.02142397 -2914.08890352 +1 1 3 2 8 -538.27733937 -538.30947533 89.25227446 +1 1 3 3 1 -6.23437635 -11785.64929538 -0.03213596 +1 1 3 3 2 1558.93687070 3074.91867413 3058.37936643 +1 1 3 3 3 5.55952118 2970.56249821 -0.04284795 +1 1 3 3 4 1559.02256660 3074.85440221 -3058.22939861 +1 1 3 3 5 0.74983908 -2915.35291796 -0.00000000 +1 1 3 3 6 -1559.30107826 3076.86825574 -3062.21425772 +1 1 3 3 7 0.62129524 -573.29482439 -0.01071199 +1 1 3 3 8 -1559.38677415 3076.90039170 3062.23568169 +1 2 3 1 1 -0.04284795 0.05355993 2968.54864468 +1 2 3 1 2 -539.11287434 538.98433050 85.03175164 +1 2 3 1 3 0.03213596 -0.02142397 2968.54864468 +1 2 3 1 4 539.09145037 -539.02717845 85.09602356 +1 2 3 1 5 0.01071199 0.02142397 -2914.00320762 +1 2 3 1 6 -537.57034824 -537.63462016 89.59505804 +1 2 3 1 7 0.02142397 -0.00000000 -3372.06918943 +1 2 3 1 8 537.61319618 537.57034824 89.45580221 +1 2 3 2 1 -0.02142397 -0.08569589 8.09826206 +1 2 3 2 2 0.04284795 0.68556716 -897.55737842 +1 2 3 2 3 0.04284795 -0.00000000 8.29107782 +1 2 3 2 4 -0.04284795 -0.66414318 -897.45025855 +1 2 3 2 5 -0.09640788 0.06427192 2.22809327 +1 2 3 2 6 -0.12854384 -0.66414318 887.76662244 +1 2 3 2 7 -0.00000000 -0.04284795 1.24259047 +1 2 3 2 8 0.12854384 0.57844729 887.45597482 +1 2 3 3 1 -11785.58502346 -11.39755401 0.05355993 +1 2 3 3 2 3074.81155426 1560.56509271 3058.33651848 +1 2 3 3 3 2970.42324238 5.74162495 -0.02142397 +1 2 3 3 4 3074.92938612 1560.54366873 -3058.18655066 +1 2 3 3 5 -573.21984048 -0.64271921 -0.04284795 +1 2 3 3 6 3076.93252766 -1557.95136791 3062.29995362 +1 2 3 3 7 -2915.35291796 0.93194286 0.03213596 +1 2 3 3 8 3076.99679958 -1557.88709599 -3062.38564951 +1 3 3 1 1 5.84874482 2970.57321019 -0.05355993 +1 3 3 1 2 1560.52224476 3074.89725015 -3058.31509451 +1 3 3 1 3 -11.38684202 -11785.64929538 0.02142397 +1 3 3 1 4 1560.46868482 3074.89725015 3058.22939861 +1 3 3 1 5 -0.64271921 -573.24126446 -0.04284795 +1 3 3 1 6 -1557.92994394 3076.95395163 3062.29995362 +1 3 3 1 7 0.87838292 -2915.31007002 0.01071199 +1 3 3 1 8 -1557.84424805 3077.00751156 -3062.35351355 +1 3 3 2 1 2970.51965026 5.62379310 0.02142397 +1 3 3 2 2 3075.02579400 1559.04399057 -3058.50791027 +1 3 3 2 3 -11785.63858339 -6.36292019 -0.02142397 +1 3 3 2 4 3074.98294605 1559.00114263 3058.40079040 +1 3 3 2 5 -2915.36362995 0.68556716 0.02142397 +1 3 3 2 6 3076.86825574 -1559.45104607 -3062.29995362 +1 3 3 2 7 -573.30553638 0.65343120 0.07498391 +1 3 3 2 8 3076.82540779 -1559.41891011 3062.05357792 +1 3 3 3 1 0.02142397 -0.02142397 3.99557110 +1 3 3 3 2 0.12854384 -0.14996782 -9480.12978896 +1 3 3 3 3 0.01071199 -0.04284795 4.11340295 +1 3 3 3 4 -0.11783186 0.21423974 -9480.02266909 +1 3 3 3 5 -0.03213596 -0.04284795 2.63514877 +1 3 3 3 6 0.17139179 0.17139179 9473.93826056 +1 3 3 3 7 -0.04284795 -0.01071199 1.81032578 +1 3 3 3 8 -0.12854384 -0.18210378 9473.88470063 +1 1 4 1 1 74175.53859579 72109.64623527 -72075.37858933 +1 1 4 1 2 0.38563153 539.01646646 -1559.19395839 +1 1 4 1 3 0.43919146 -538.55585103 1558.25130355 +1 1 4 1 4 -74174.42454916 -72107.78234956 72072.32567308 +1 1 4 1 5 0.35349557 -1559.70813376 538.96290653 +1 1 4 1 6 -9473.02774168 -3066.32766067 3063.77820780 +1 1 4 1 7 9470.57469669 3063.09264064 -3059.56839697 +1 1 4 1 8 0.12854384 1560.64007661 -539.19857024 +1 1 4 2 1 67136.69203462 72095.08864514 -80912.77845512 +1 1 4 2 2 -538.66297089 0.54631133 -3074.35093883 +1 1 4 2 3 -0.11783186 537.82743592 3074.51161863 +1 1 4 2 4 -72109.31416368 -67119.98133513 80913.20693460 +1 1 4 2 5 888.67714132 -3068.49148202 94.73681173 +1 1 4 2 6 3063.40328826 -888.25937383 -93.10858973 +1 1 4 2 7 1.32828637 -1557.45861652 3075.82919301 +1 1 4 2 8 1558.01563984 0.65343120 -3077.82162257 +1 1 4 3 1 -67090.65191512 -80900.84530177 72062.58847703 +1 1 4 3 2 -1559.32250223 -3074.66158644 0.51417537 +1 1 4 3 3 -893.62607925 83.29640977 -3055.78706561 +1 1 4 3 4 72070.57961922 80911.49301670 -67094.76531808 +1 1 4 3 5 0.07498391 3080.85311485 536.26348584 +1 1 4 3 6 -3065.74921338 -94.95105147 -888.66642933 +1 1 4 3 7 2.59230082 3075.91488891 -1559.81525363 +1 1 4 3 8 535.96355021 -3081.13162650 -0.33207159 +1 2 4 1 1 72107.56810982 67126.64419095 -80913.82822983 +1 2 4 1 2 0.53559934 -538.63083493 -3074.35093883 +1 2 4 1 3 539.32711408 -0.79268703 3074.16883505 +1 2 4 1 4 -67142.43365957 -72094.82084547 80912.58563936 +1 2 4 1 5 -1559.23680634 -1.79961379 3080.44605934 +1 2 4 1 6 0.68556716 1558.03706381 -3077.81091058 +1 2 4 1 7 -3058.22939861 888.00228615 91.66247150 +1 2 4 1 8 -888.25937383 3063.38186429 -93.10858973 +1 2 4 2 1 72096.32052363 74176.06348314 -72067.88019853 +1 2 4 2 2 539.00575447 0.38563153 -1559.21538236 +1 2 4 2 3 -539.56277779 -0.83553497 1560.00806939 +1 2 4 2 4 -72096.73829112 -74179.71627066 72069.56198047 +1 2 4 2 5 3068.15941042 9477.28040046 -3066.62759630 +1 2 4 2 6 1560.67221257 0.08569589 -539.17714626 +1 2 4 2 7 -1561.46489960 -0.25708768 539.63776170 +1 2 4 2 8 -3066.32766067 -9473.00631771 3063.81034376 +1 2 4 3 1 -80898.55293658 -67086.00291283 72060.77815125 +1 2 4 3 2 -3074.66158644 -1559.30107826 0.52488736 +1 2 4 3 3 82.97505016 -893.35827957 -3055.91560945 +1 2 4 3 4 80908.90071588 72063.49899591 -67096.11502842 +1 2 4 3 5 3079.44984457 2.18524532 -1557.20152883 +1 2 4 3 6 -3081.11020253 535.98497418 -0.29993563 +1 2 4 3 7 3077.91803045 2.60301281 536.90620505 +1 2 4 3 8 -94.95105147 -3065.73850140 -888.68785331 +1 3 4 1 1 -72074.72515813 -80912.17858386 67095.54729312 +1 3 4 1 2 893.78675905 -83.20000189 3055.80848958 +1 3 4 1 3 1560.10447727 3074.55446658 -0.51417537 +1 3 4 1 4 67095.30091742 80903.13766695 -72062.59918902 +1 3 4 1 5 -535.98497418 3081.32444227 -0.29993563 +1 3 4 1 6 -1.08191067 -3078.64644555 1559.45104607 +1 3 4 1 7 3063.58539204 94.23334835 889.22345265 +1 3 4 1 8 -1.09262266 -3079.24631682 -536.45630160 +1 3 4 2 1 -80910.78602557 -72067.71951873 67097.07910724 +1 3 4 2 2 -83.18928990 893.78675905 3055.80848958 +1 3 4 2 3 3074.40449876 1558.70120699 -0.34278358 +1 3 4 2 4 80903.01983510 67084.28899493 -72063.26333220 +1 3 4 2 5 95.28312306 3067.72021896 887.87374231 +1 3 4 2 6 -3079.25702880 -1.09262266 -536.43487763 +1 3 4 2 7 3079.16062092 -534.65668781 -0.28922365 +1 3 4 2 8 -3078.60359761 -1.07119869 1559.44033409 +1 3 4 3 1 72063.67038770 72064.06673121 -74113.23768025 +1 3 4 3 2 -3055.27289024 -3055.28360223 9478.69438273 +1 3 4 3 3 3055.10149845 3055.52997792 -9478.73723067 +1 3 4 3 4 -72062.68488491 -72065.59854533 74112.61638501 +1 3 4 3 5 -539.04860242 -1555.38049107 -1.75676584 +1 3 4 3 6 1556.38741783 538.34161129 2.87081248 +1 3 4 3 7 -1556.32314591 -538.12737155 -3.14932413 +1 3 4 3 8 538.36303526 1556.38741783 2.82796453 +1 1 5 1 1 -0.04284795 0.12854384 -9.14803677 +1 1 5 1 2 -0.85695895 -890.25180339 -0.25708768 +1 1 5 1 3 -0.04284795 -0.04284795 0.94265484 +1 1 5 1 4 0.83553497 890.23037941 -0.08569589 +1 1 5 1 5 -0.01071199 -0.02142397 13.26143972 +1 1 5 1 6 -0.55702332 -889.58766020 -2.52802890 +1 1 5 1 7 0.02142397 0.02142397 0.41776749 +1 1 5 1 8 0.53559934 889.57694822 -2.50660492 +1 1 5 2 1 -0.04284795 -0.02142397 -11786.34557453 +1 1 5 2 2 1560.77933244 3069.28416904 3081.34586624 +1 1 5 2 3 0.01071199 -0.06427192 -2915.33149399 +1 1 5 2 4 -1560.81146840 -3069.32701699 3081.62437790 +1 1 5 2 5 -0.05355993 0.02142397 2966.14915962 +1 1 5 2 6 1558.05848778 -3056.34408893 3073.69750763 +1 1 5 2 7 0.10711987 -0.04284795 -574.38744705 +1 1 5 2 8 -1558.07991176 3056.32266495 3073.71893160 +1 1 5 3 1 -12.89723217 2960.13973500 -0.01071199 +1 1 5 3 2 538.34161129 94.00839662 -536.54199750 +1 1 5 3 3 1.45683021 -3372.02634149 0.12854384 +1 1 5 3 4 538.25591539 93.98697265 536.71338929 +1 1 5 3 5 14.45047026 2963.40689099 -0.02142397 +1 1 5 3 6 -539.51992984 87.23842093 536.11351802 +1 1 5 3 7 -0.47132742 -2914.42097511 0.07498391 +1 1 5 3 8 -539.51992984 87.42052471 -536.00639816 +1 2 5 1 1 -0.00000000 0.07498391 2959.63627162 +1 2 5 1 2 1560.45797284 -3069.54125673 3080.44605934 +1 2 5 1 3 0.06427192 -0.00000000 -573.09129664 +1 2 5 1 4 -1560.52224476 3069.45556083 3080.29609153 +1 2 5 1 5 0.01071199 -0.02142397 -11776.30844285 +1 2 5 1 6 1553.10954986 3059.40771717 3071.89789384 +1 2 5 1 7 -0.02142397 -0.00000000 -2914.77447067 +1 2 5 1 8 -1553.08812588 -3059.43985313 3071.76934999 +1 2 5 2 1 -0.00000000 -0.04284795 -8.79454121 +1 2 5 2 2 0.89980690 -9474.64525169 0.83553497 +1 2 5 2 3 0.02142397 -0.04284795 -0.25708768 +1 2 5 2 4 -0.86767094 9474.60240375 0.98550279 +1 2 5 2 5 0.08569589 0.02142397 13.41140754 +1 2 5 2 6 -0.06427192 -9456.17778636 -3.12790016 +1 2 5 2 7 0.04284795 0.03213596 -0.11783186 +1 2 5 2 8 -0.06427192 9456.22063431 -2.93508440 +1 2 5 3 1 2960.70747030 14.27907848 0.02142397 +1 2 5 3 2 3081.15305048 -3068.66287381 1558.33699944 +1 2 5 3 3 -2913.87466378 2.05670148 0.02142397 +1 2 5 3 4 3081.18518644 -3068.62002586 -1558.12275970 +1 2 5 3 5 -11774.21960541 16.62500360 0.02142397 +1 2 5 3 6 3069.88404031 3053.00194903 1560.52224476 +1 2 5 3 7 -574.69809467 -1.49967816 0.01071199 +1 2 5 3 8 3069.88404031 3053.05550896 -1560.61865264 +1 3 5 1 1 -12.49017667 2960.33255076 -0.07498391 +1 3 5 1 2 -536.09209405 94.73681173 538.32018732 +1 3 5 1 3 -0.23566371 -2914.62450286 -0.02142397 +1 3 5 1 4 -536.08138206 94.86535557 -538.42730718 +1 3 5 1 5 16.60357962 2963.59970675 -0.10711987 +1 3 5 1 6 534.72095973 87.49550862 -537.61319618 +1 3 5 1 7 -1.15689458 -3373.67598746 -0.03213596 +1 3 5 1 8 534.69953576 87.46337266 537.66675612 +1 3 5 2 1 -11787.12754957 -8.03399014 0.01071199 +1 3 5 2 2 3081.77434571 3069.28416904 1556.34456989 +1 3 5 2 3 -572.91990485 0.87838292 -0.02142397 +1 3 5 2 4 3081.74220975 3069.32701699 -1556.32314591 +1 3 5 2 5 2963.80323450 -7.96971822 0.10711987 +1 3 5 2 6 3074.42592273 -3061.35729877 1557.22295281 +1 3 5 2 7 -2916.01706115 -0.79268703 0.03213596 +1 3 5 2 8 3074.34022684 -3061.43228268 -1557.42648056 +1 3 5 3 1 -0.02142397 0.06427192 8.23751789 +1 3 5 3 2 -0.12854384 -886.35264017 -2.12097340 +1 3 5 3 3 -0.03213596 -0.06427192 2.54945287 +1 3 5 3 4 0.13925583 886.43833607 -2.22809327 +1 3 5 3 5 0.03213596 0.02142397 -10.17638751 +1 3 5 3 6 0.14996782 -891.38727399 3.04220427 +1 3 5 3 7 -0.00000000 -0.01071199 -2.17453333 +1 3 5 3 8 -0.14996782 891.26944214 2.83867652 +1 1 6 1 1 74116.23703657 -72002.14073522 72008.75003111 +1 1 6 1 2 0.40705550 -1558.13347169 535.67432656 +1 1 6 1 3 -1.28543842 538.64154692 -1558.85117481 +1 1 6 1 4 -9473.03845367 3064.52804688 -3066.00630107 +1 1 6 1 5 -1.07119869 1557.56573639 -539.66989766 +1 1 6 1 6 -74108.24589438 71998.04875624 -71998.13445213 +1 1 6 1 7 9466.48271771 -3061.73221831 3061.35729877 +1 1 6 1 8 0.44990345 -536.77766121 1556.92301718 +1 1 6 2 1 -67015.21810371 72015.84136640 -80796.89618135 +1 1 6 2 2 -1561.93622702 -1.75676584 -3081.76363373 +1 1 6 2 3 -0.53559934 538.51300308 3077.36100713 +1 1 6 2 4 -3066.00630107 -889.33057252 -95.12244326 +1 1 6 2 5 -891.70863360 -3053.55897234 86.12437430 +1 1 6 2 6 71998.32726790 -67051.53173914 80811.14312386 +1 1 6 2 7 0.42847947 -1557.60858433 3076.37550434 +1 1 6 2 8 536.67054134 -0.59987126 -3076.98608759 +1 1 6 3 1 67029.42219827 -80800.94531238 72003.74753324 +1 1 6 3 2 -540.03410521 -3079.38557265 -0.87838292 +1 1 6 3 3 888.95565298 90.49486493 -3062.77128104 +1 1 6 3 4 3063.40328826 -93.02289383 -888.83782112 +1 1 6 3 5 -1.48896617 3074.85440221 536.71338929 +1 1 6 3 6 -71997.32034113 80808.37943125 -67028.09391190 +1 1 6 3 7 -0.62129524 3076.85754375 -1559.46175806 +1 1 6 3 8 1557.69428023 -3077.28602322 -0.32135961 +1 2 6 1 1 -72004.24028464 67024.60180419 -80796.21061419 +1 2 6 1 2 889.39484444 3065.98487709 -95.07959531 +1 2 6 1 3 -537.82743592 0.36420755 3077.46812700 +1 2 6 1 4 1.75676584 1561.87195510 -3081.75292174 +1 2 6 1 5 1553.38806151 0.21423974 3070.18397594 +1 2 6 1 6 67035.54945475 -72006.46837791 80811.48590744 +1 2 6 1 7 3061.37872275 889.96257974 90.79480057 +1 2 6 1 8 0.59987126 -536.63840538 -3077.00751156 +1 2 6 2 1 72013.43116936 -74113.97680734 72014.96298348 +1 2 6 2 2 -3064.50662291 9473.03845367 -3065.95274113 +1 2 6 2 3 -537.93455579 -0.02142397 -1557.37292062 +1 2 6 2 4 1558.11204772 -0.40705550 535.68503855 +1 2 6 2 5 3057.04036807 -9458.66296731 3055.05865050 +1 2 6 2 6 -72005.10795558 74101.32595087 -72001.66940780 +1 2 6 2 7 -1557.77997612 -0.73912709 -537.59177221 +1 2 6 2 8 536.77766121 -0.43919146 1556.92301718 +1 2 6 3 1 -80801.90939119 67032.57152241 -72004.34740451 +1 2 6 3 2 -93.04431781 3063.43542422 888.84853311 +1 2 6 3 3 90.76266461 889.07348483 3062.79270501 +1 2 6 3 4 -3079.39628463 -540.05552919 0.87838292 +1 2 6 3 5 3072.65844490 -1.92815763 1561.37920371 +1 2 6 3 6 80810.32901286 -72001.45516806 67026.44426593 +1 2 6 3 7 3077.85375853 0.82482299 -536.22063789 +1 2 6 3 8 -3077.29673521 1557.70499222 0.35349557 +1 3 6 1 1 72007.60384851 -80795.10727954 67033.68556904 +1 3 6 1 2 -1.41398226 -3078.11084621 -538.18093149 +1 3 6 1 3 -1558.01563984 3077.59667084 0.34278358 +1 3 6 1 4 -2.82796453 -3080.16754769 1557.11583294 +1 3 6 1 5 536.20992591 3076.73971189 1.84246174 +1 3 6 1 6 -67028.08319992 80799.85268972 -72006.44695393 +1 3 6 1 7 -3061.97859401 91.86599925 890.54102703 +1 3 6 1 8 -891.51581784 -92.62655032 3061.14305904 +1 3 6 2 1 -80797.28181287 72014.55592798 -67032.51796247 +1 3 6 2 2 -3080.16754769 -2.82796453 -1557.07298499 +1 3 6 2 3 3077.28602322 -1559.83667760 -0.21423974 +1 3 6 2 4 -3078.13227018 -1.45683021 538.25591539 +1 3 6 2 5 89.83072175 -3058.57218219 -892.13711307 +1 3 6 2 6 80803.91253273 -67036.53495754 72005.35433127 +1 3 6 2 7 3077.12534342 536.01711014 -0.62129524 +1 3 6 2 8 -92.61583833 -891.49439386 -3061.14305904 +1 3 6 3 1 72000.76960090 -72000.16972964 74100.53326384 +1 3 6 3 2 536.32775776 -1559.33321422 2.37806108 +1 3 6 3 3 3063.01765673 -3062.57846527 9469.52492198 +1 3 6 3 4 1559.33321422 -536.32775776 2.35663711 +1 3 6 3 5 -536.91691704 1558.61551110 3.59922758 +1 3 6 3 6 -72003.52258152 72000.74817693 -74115.18726186 +1 3 6 3 7 -1557.73712818 537.81672393 2.24951724 +1 3 6 3 8 -3061.31445083 3061.36801076 -9465.42223101 +1 1 7 1 1 -0.10711987 -0.01071199 -5.12032972 +1 1 7 1 2 -9468.71081098 0.10711987 2.99935632 +1 1 7 1 3 -0.00000000 -0.00000000 0.53559934 +1 1 7 1 4 9468.73223495 -0.00000000 2.99935632 +1 1 7 1 5 0.05355993 -0.02142397 -0.19281576 +1 1 7 1 6 9470.91748027 0.92123087 -0.85695895 +1 1 7 1 7 -0.02142397 0.03213596 0.44990345 +1 1 7 1 8 -9470.85320835 -0.80339901 -0.84624696 +1 1 7 2 1 -0.00000000 -0.04284795 2957.22607457 +1 1 7 2 2 -3063.56396806 1556.47311373 3075.77563308 +1 1 7 2 3 0.01071199 -0.06427192 -573.32696035 +1 1 7 2 4 3063.56396806 -1556.53738565 3075.68993718 +1 1 7 2 5 -0.00000000 -0.06427192 -2914.26029531 +1 1 7 2 6 -3061.01451519 -1557.18010486 3076.39692831 +1 1 7 2 7 -0.00000000 0.07498391 -11773.68400607 +1 1 7 2 8 3061.03593917 1557.23366480 3076.37550434 +1 1 7 3 1 -1.04977471 2959.47559181 0.04284795 +1 1 7 3 2 -3058.85069385 3075.02579400 1559.60101389 +1 1 7 3 3 0.29993563 -2913.63900007 0.02142397 +1 1 7 3 4 -3058.91496577 3075.04721797 -1559.49389402 +1 1 7 3 5 0.48203941 -574.78379056 -0.00000000 +1 1 7 3 6 3060.60745969 3075.98987281 -1559.06541455 +1 1 7 3 7 -3.06362824 -11773.01986288 0.02142397 +1 1 7 3 8 3060.58603572 3075.97916083 1559.27965428 +1 2 7 1 1 -0.10711987 -0.03213596 -11783.72113775 +1 2 7 1 2 3060.50033982 1561.37920371 3077.55382289 +1 2 7 1 3 0.04284795 0.04284795 -2915.07440631 +1 2 7 1 4 -3060.44677989 -1561.40062768 3077.46812700 +1 2 7 1 5 0.03213596 -0.00000000 -574.65524672 +1 2 7 1 6 3060.82169943 -1557.45861652 3077.57524687 +1 2 7 1 7 0.04284795 -0.09640788 2963.47116291 +1 2 7 1 8 -3060.84312340 1557.54431241 3077.50026296 +1 2 7 2 1 -0.00000000 0.01071199 -2.18524532 +1 2 7 2 2 -888.96636496 0.55702332 2.37806108 +1 2 7 2 3 0.03213596 0.08569589 0.83553497 +1 2 7 2 4 888.97707695 -0.55702332 2.52802890 +1 2 7 2 5 -0.00000000 0.04284795 -1.97100558 +1 2 7 2 6 888.60215741 -0.89980690 0.21423974 +1 2 7 2 7 -0.08569589 -0.00000000 -1.89602167 +1 2 7 2 8 -888.62358139 0.88909491 0.26779967 +1 2 7 3 1 2962.01433270 -2.46375698 -0.12854384 +1 2 7 3 2 89.68075393 539.79844150 -536.49914955 +1 2 7 3 3 -3371.56572605 0.44990345 -0.00000000 +1 2 7 3 4 89.60577003 539.69132163 536.62769339 +1 2 7 3 5 -2914.09961550 0.04284795 -0.00000000 +1 2 7 3 6 89.63790599 -537.97740374 -536.15636597 +1 2 7 3 7 2965.29220067 -1.54252611 0.04284795 +1 2 7 3 8 89.55221009 -538.00953970 536.02782213 +1 3 7 1 1 -1.77818982 -11783.09984251 -0.00000000 +1 3 7 1 2 3062.98552077 3079.58910040 1556.38741783 +1 3 7 1 3 0.77126305 -573.54120009 0.08569589 +1 3 7 1 4 3062.95338481 3079.65337232 -1556.38741783 +1 3 7 1 5 -0.80339901 -2915.58858168 0.14996782 +1 3 7 1 6 -3061.20733096 3076.65401600 -1557.30864870 +1 3 7 1 7 -1.71391790 2959.94691923 0.02142397 +1 3 7 1 8 -3061.16448301 3076.60045606 1557.14796890 +1 3 7 2 1 2960.34326275 -1.67106995 -0.01071199 +1 3 7 2 2 91.99454309 -534.93519947 538.25591539 +1 3 7 2 3 -2914.64592683 0.72841511 -0.00000000 +1 3 7 2 4 91.96240713 -534.91377550 -538.06309963 +1 3 7 2 5 -3373.75097137 -1.11404663 0.08569589 +1 3 7 2 6 90.36632109 535.96355021 537.76316400 +1 3 7 2 7 2963.53543483 -0.08569589 0.02142397 +1 3 7 2 8 90.36632109 535.98497418 -537.92384380 +1 3 7 3 1 -0.02142397 -0.00000000 4.86324203 +1 3 7 3 2 -890.89452260 -0.10711987 -2.91366042 +1 3 7 3 3 -0.03213596 -0.04284795 2.18524532 +1 3 7 3 4 890.90523459 0.17139179 -2.82796453 +1 3 7 3 5 0.02142397 0.04284795 -2.48518095 +1 3 7 3 6 889.00921291 -0.14996782 1.97100558 +1 3 7 3 7 0.02142397 -0.04284795 -2.76369261 +1 3 7 3 8 -888.96636496 0.13925583 1.91744565 +1 1 8 1 1 -74116.62266810 72002.53707873 72009.10352667 +1 1 8 1 2 9473.05987764 -3064.52804688 -3065.97416511 +1 1 8 1 3 1.28543842 -538.62012295 -1558.87259878 +1 1 8 1 4 -0.41776749 1558.14418368 535.68503855 +1 1 8 1 5 1.00692676 -1557.63000831 -539.62704971 +1 1 8 1 6 -0.41776749 536.77766121 1556.98728910 +1 1 8 1 7 -9466.52556566 3061.68937036 3061.34658679 +1 1 8 1 8 74108.63152590 -71998.39153982 -71998.71289942 +1 1 8 2 1 67015.38949550 -72015.88421435 -80797.08899711 +1 1 8 2 2 3066.00630107 889.36270848 -95.13315524 +1 1 8 2 3 0.56773530 -538.55585103 3077.31815918 +1 1 8 2 4 1561.91480305 1.67106995 -3081.79576969 +1 1 8 2 5 891.70863360 3053.51612440 86.14579827 +1 1 8 2 6 -536.63840538 0.57844729 -3076.95395163 +1 1 8 2 7 -0.44990345 1557.65143228 3076.38621633 +1 1 8 2 8 -71998.52008366 67051.57458708 80811.05742797 +1 1 8 3 1 67029.10083867 -80800.48469694 -72003.19050993 +1 1 8 3 2 3063.39257627 -93.01218185 888.82710914 +1 1 8 3 3 888.99850093 90.55913686 3062.74985706 +1 1 8 3 4 -540.04481720 -3079.41770861 0.81411100 +1 1 8 3 5 -1.53181412 3074.76870631 -536.79908518 +1 1 8 3 6 1557.69428023 -3077.27531124 0.32135961 +1 1 8 3 7 -0.64271921 3076.84683176 1559.45104607 +1 1 8 3 8 -71997.02040550 80807.99379973 67027.80468826 +1 2 8 1 1 72004.28313259 -67024.49468432 -80796.04993438 +1 2 8 1 2 -1.73534187 -1561.94693901 -3081.76363373 +1 2 8 1 3 537.80601195 -0.38563153 3077.48955097 +1 2 8 1 4 -889.36270848 -3066.02772504 -95.10101928 +1 2 8 1 5 -1553.37734953 -0.27851166 3070.09828004 +1 2 8 1 6 -0.62129524 536.64911737 -3076.95395163 +1 2 8 1 7 -3061.31445083 -889.93044378 90.81622454 +1 2 8 1 8 -67035.54945475 72006.25413817 80811.43234751 +1 2 8 2 1 -72014.20243241 74114.51240669 72015.47715885 +1 2 8 2 2 -1558.14418368 0.41776749 535.66361458 +1 2 8 2 3 537.76316400 -0.06427192 -1557.28722473 +1 2 8 2 4 3064.53875887 -9473.01702969 -3065.98487709 +1 2 8 2 5 -3057.19033589 9458.79151115 3054.95153063 +1 2 8 2 6 -536.78837320 0.42847947 1557.00871307 +1 2 8 2 7 1556.85874526 0.08569589 -538.25591539 +1 2 8 2 8 72007.26106493 -74101.13313511 -72001.42303210 +1 2 8 3 1 -80801.50233569 67032.10019499 72003.81180517 +1 2 8 3 2 -3079.43913258 -540.07695316 -0.84624696 +1 2 8 3 3 90.75195262 889.07348483 -3062.79270501 +1 2 8 3 4 -93.02289383 3063.43542422 -888.81639715 +1 2 8 3 5 3072.60488497 -1.92815763 -1561.42205165 +1 2 8 3 6 -3077.27531124 1557.69428023 -0.29993563 +1 2 8 3 7 3077.81091058 0.83553497 536.22063789 +1 2 8 3 8 80809.98622928 -72001.19808037 -67025.84439466 +1 3 8 1 1 72007.94663209 -80795.42863915 -67033.99621666 +1 3 8 1 2 -2.82796453 -3080.16754769 -1557.09440897 +1 3 8 1 3 -1558.07991176 3077.55382289 -0.34278358 +1 3 8 1 4 -1.44611823 -3078.15369416 538.32018732 +1 3 8 1 5 536.27419783 3076.69686395 -1.90673366 +1 3 8 1 6 -891.52652982 -92.55156641 -3061.16448301 +1 3 8 1 7 -3061.93574606 91.88742323 -890.49817908 +1 3 8 1 8 -67028.43669548 80800.18476131 72006.76831354 +1 3 8 2 1 -80797.49605261 72014.83443964 67032.65721830 +1 3 8 2 2 -3078.11084621 -1.41398226 -538.19164347 +1 3 8 2 3 3077.30744720 -1559.79382965 0.17139179 +1 3 8 2 4 -3080.12469974 -2.82796453 1557.11583294 +1 3 8 2 5 89.78787380 -3058.57218219 892.22280897 +1 3 8 2 6 -92.57299038 -891.53724181 3061.20733096 +1 3 8 2 7 3077.12534342 536.01711014 0.65343120 +1 3 8 2 8 80804.13748446 -67036.68492536 -72005.84708267 +1 3 8 3 1 -72001.69083177 72000.93028070 74101.21883100 +1 3 8 3 2 -1559.32250223 536.32775776 2.39948506 +1 3 8 3 3 -3063.21047250 3062.49276938 9469.61061787 +1 3 8 3 4 -536.31704577 1559.34392621 2.33521313 +1 3 8 3 5 536.70267730 -1558.55123918 3.51353169 +1 3 8 3 6 3061.33587480 -3061.31445083 -9465.39009505 +1 3 8 3 7 1556.79447333 -538.44873116 1.58537405 +1 3 8 3 8 72005.69711485 -72000.76960090 -74115.17654987 +2 1 1 1 1 -74175.43147592 -72109.42128355 -72075.29289344 +2 1 1 1 2 74174.16746147 72107.66451771 72072.25068917 +2 1 1 1 3 -0.44990345 538.62012295 1558.31557547 +2 1 1 1 4 -0.38563153 -538.98433050 -1559.19395839 +2 1 1 1 5 -0.36420755 1559.72955773 539.00575447 +2 1 1 1 6 -0.13925583 -1560.62936463 -539.24141818 +2 1 1 1 7 -9470.57469669 -3063.15691256 -3059.60053293 +2 1 1 1 8 9472.99560572 3066.29552471 3063.75678383 +2 1 1 2 1 -72107.50383790 -67126.57991903 -80913.63541407 +2 1 1 2 2 67142.32653970 72094.79942150 80912.69275923 +2 1 1 2 3 -539.35925004 0.79268703 3074.21168300 +2 1 1 2 4 -0.52488736 538.66297089 -3074.38307479 +2 1 1 2 5 1559.23680634 1.79961379 3080.44605934 +2 1 1 2 6 888.25937383 -3063.39257627 -93.13001370 +2 1 1 2 7 3058.18655066 -887.94872621 91.65175952 +2 1 1 2 8 -0.68556716 -1557.99421586 -3077.84304654 +2 1 1 3 1 -72074.51091840 -80912.05004002 -67095.51515716 +2 1 1 3 2 67095.21522152 80902.98769914 72062.55634107 +2 1 1 3 3 1560.06162932 3074.55446658 0.53559934 +2 1 1 3 4 893.72248713 -83.25356182 -3055.63709779 +2 1 1 3 5 -536.00639816 3081.32444227 0.25708768 +2 1 1 3 6 -1.09262266 -3079.24631682 536.52057352 +2 1 1 3 7 3063.60681601 94.22263636 -889.20202868 +2 1 1 3 8 -1.11404663 -3078.61430959 -1559.44033409 +2 2 1 1 1 -67136.54206680 -72095.02437322 -80912.89628698 +2 2 1 1 2 72109.26060375 67119.83136731 80913.26049453 +2 2 1 1 3 0.13925583 -537.76316400 3074.46877068 +2 2 1 1 4 538.63083493 -0.51417537 -3074.34022684 +2 2 1 1 5 -888.67714132 3068.44863407 94.67253981 +2 2 1 1 6 -1558.04777580 -0.70699113 -3077.81091058 +2 2 1 1 7 -1.32828637 1557.44790453 3075.85061698 +2 2 1 1 8 -3063.41400025 888.24866185 -93.06574178 +2 2 1 2 1 -72096.40621952 -74176.12775507 -72067.75165469 +2 2 1 2 2 72096.74900310 74179.82339053 72069.50842054 +2 2 1 2 3 539.56277779 0.83553497 1560.05091734 +2 2 1 2 4 -538.98433050 -0.36420755 -1559.23680634 +2 2 1 2 5 -3068.15941042 -9477.25897649 -3066.69186823 +2 2 1 2 6 3066.30623670 9473.01702969 3063.77820780 +2 2 1 2 7 1561.42205165 0.23566371 539.62704971 +2 2 1 2 8 -1560.67221257 -0.13925583 -539.17714626 +2 2 1 3 1 -80910.72175365 -72067.80521463 -67097.01483532 +2 2 1 3 2 80903.07339503 67084.37469083 72063.07051644 +2 2 1 3 3 3074.41521075 1558.65835905 0.38563153 +2 2 1 3 4 -83.23213785 893.78675905 -3055.76564164 +2 2 1 3 5 95.28312306 3067.72021896 -887.89516628 +2 2 1 3 6 -3078.63573357 -1.09262266 -1559.47247005 +2 2 1 3 7 3079.16062092 -534.67811179 0.29993563 +2 2 1 3 8 -3079.22489284 -1.09262266 536.44558962 +2 3 1 1 1 -67090.71618705 -80900.89886170 -72062.63132498 +2 3 1 1 2 72070.67602710 80911.55728862 67094.80816602 +2 3 1 1 3 -893.60465527 83.31783374 3055.82991356 +2 3 1 1 4 -1559.30107826 -3074.68301042 -0.51417537 +2 3 1 1 5 0.05355993 3080.78884292 -536.26348584 +2 3 1 1 6 535.98497418 -3081.15305048 0.38563153 +2 3 1 1 7 2.59230082 3075.90417692 1559.79382965 +2 3 1 1 8 -3065.68494146 -94.96176345 888.66642933 +2 3 1 2 1 -80900.00976679 -67087.20265536 -72062.08501365 +2 3 1 2 2 80911.66440849 72064.10957916 67096.63991578 +2 3 1 2 3 82.79294639 -893.25115971 3055.78706561 +2 3 1 2 4 -3074.65087446 -1559.34392621 -0.51417537 +2 3 1 2 5 3079.28916476 2.07812545 1557.43719255 +2 3 1 2 6 -94.96176345 -3065.72778941 888.64500536 +2 3 1 2 7 3076.95395163 3.31000394 -536.24206187 +2 3 1 2 8 -3081.13162650 535.98497418 0.33207159 +2 3 1 3 1 -72064.22741102 -72064.68802645 -74113.93395940 +2 3 1 3 2 72063.41330002 72066.18770461 74113.30195217 +2 3 1 3 3 -3055.08007448 -3055.48712998 -9478.78007862 +2 3 1 3 4 3055.25146627 3055.23004229 9478.69438273 +2 3 1 3 5 539.02717845 1555.42333902 -1.73534187 +2 3 1 3 6 -538.32018732 -1556.40884181 2.84938850 +2 3 1 3 7 1556.32314591 538.10594758 -3.12790016 +2 3 1 3 8 -1556.36599386 -538.32018732 2.84938850 +2 1 2 1 1 74168.12590089 67132.22513610 67087.80252662 +2 1 2 1 2 112.32589414 -216.86417384 -124.98746260 +2 1 2 1 3 -74173.55687822 -67116.61777126 67078.07604256 +2 1 2 1 4 -1.77818982 5.63450508 6.59858390 +2 1 2 1 5 -74164.99800073 67112.22585665 -67087.88822252 +2 1 2 1 6 0.67485517 7.73405451 8.56958948 +2 1 2 1 7 74056.16421430 -66920.70624370 -66963.33995138 +2 1 2 1 8 2.95650837 -3.65278752 -4.61686633 +2 1 2 2 1 72106.96823856 72098.22725729 80899.65627123 +2 1 2 2 2 -223.10926218 223.90194920 -329274.64983068 +2 1 2 2 3 -72098.58075286 -72107.33244611 80900.26685448 +2 1 2 2 4 0.94265484 -0.83553497 11785.47790359 +2 1 2 2 5 72111.43513708 -72111.33872920 80901.83080456 +2 1 2 2 6 2.34592512 0.06427192 -2959.91478327 +2 1 2 2 7 -71899.86268474 71899.95909263 80707.23685139 +2 1 2 2 8 -0.08569589 -2.36734909 -2959.85051135 +2 1 2 3 1 72073.58968753 80913.77466990 72065.05223400 +2 1 2 3 2 -129.25083337 -329284.87977812 109.93712107 +2 1 2 3 3 72069.91547604 80913.33547844 -72064.80585831 +2 1 2 3 4 -4.45618653 -2968.84858031 8.54816551 +2 1 2 3 5 -72080.29539130 80898.51008863 -72064.18456307 +2 1 2 3 6 6.60929589 11783.18553841 1.22116650 +2 1 2 3 7 -71939.00428470 80702.24506551 71944.24244628 +2 1 2 3 8 2.91366042 -2957.46173828 -0.27851166 +2 2 2 1 1 72107.07535843 72098.53790491 80899.89193494 +2 2 2 1 2 -221.71670389 221.02042474 -329275.43180572 +2 2 2 1 3 -72098.35580113 -72107.09678240 80899.68840719 +2 2 2 1 4 0.74983908 -1.32828637 11785.19939193 +2 2 2 1 5 72110.97452164 -72110.84597780 80901.35947714 +2 2 2 1 6 1.10333465 -1.79961379 -2958.58649690 +2 2 2 1 7 -71900.09834845 71904.34029525 80707.24756337 +2 2 2 1 8 0.14996782 -2.78511658 -2959.80766341 +2 2 2 2 1 67116.29641165 74173.12839875 67077.72254699 +2 2 2 2 2 217.71042080 -112.00453454 -125.21241433 +2 2 2 2 3 -67132.45008783 -74168.27586870 67088.12388623 +2 2 2 2 4 -5.64521707 1.84246174 6.72712774 +2 2 2 2 5 -67112.09731280 74164.95515278 -67087.80252662 +2 2 2 2 6 3.51353169 -3.04220427 -4.62757832 +2 2 2 2 7 66920.43844403 -74055.76787078 -66963.14713561 +2 2 2 2 8 -7.81975040 -0.80339901 8.59101346 +2 2 2 3 1 80913.27120652 72067.65524681 72064.59161857 +2 2 2 3 2 -329283.26226811 -127.06558805 -110.50485638 +2 2 2 3 3 80914.07460553 72073.86819919 -72060.86384715 +2 2 2 3 4 -2970.25185059 -5.52738522 -10.28350738 +2 2 2 3 5 80898.42439274 -72080.25254335 72063.94889936 +2 2 2 3 6 -2958.29727326 4.04913103 -0.66414318 +2 2 2 3 7 80702.52357717 -71939.23994842 -71944.44597403 +2 2 2 3 8 11783.42120212 6.55573595 -1.66035796 +2 3 2 1 1 72073.86819919 80913.86036579 72065.34145765 +2 3 2 1 2 -125.65160579 -329281.95540571 105.93083799 +2 3 2 1 3 72066.89469574 80912.24285578 -72059.55698475 +2 3 2 1 4 -5.29172151 -2970.13401873 6.57715993 +2 3 2 1 5 -72080.32752726 80898.31727287 -72064.14171512 +2 3 2 1 6 6.70570377 11783.33550622 1.04977471 +2 3 2 1 7 -71941.01813823 80701.88085796 71944.09247846 +2 3 2 1 8 4.82039408 -2957.61170610 0.61058325 +2 3 2 2 1 80913.22835857 72069.79764418 72064.60233056 +2 3 2 2 2 -329283.45508387 -126.72280447 -111.57605506 +2 3 2 2 3 80914.07460553 72071.57583400 -72060.90669509 +2 3 2 2 4 -2970.28398655 -5.46311330 -10.45489917 +2 3 2 2 5 80898.46724069 -72080.12399951 72063.75608360 +2 3 2 2 6 -2958.27584929 3.96343514 0.59987126 +2 3 2 2 7 80702.69496896 -71939.53988405 -71944.78875761 +2 3 2 2 8 11783.37835417 6.53431198 -1.54252611 +2 3 2 3 1 67092.85858442 67093.52272760 74101.72229438 +2 3 2 3 2 105.49164653 -104.55970367 5.58094515 +2 3 2 3 3 -67093.96191906 -67093.15852005 74102.09721392 +2 3 2 3 4 -2.28165320 2.35663711 -4.45618653 +2 3 2 3 5 -67082.33941333 67082.38226127 -74073.73187274 +2 3 2 3 6 -0.74983908 -1.71391790 -4.79897011 +2 3 2 3 7 66979.46149159 -66979.44006762 -74121.37879026 +2 3 2 3 8 1.69249392 0.78197504 -4.72398620 +2 1 3 1 1 -0.81411100 -539.53064183 1559.94379747 +2 1 3 1 2 -74179.75911861 -72096.84541098 72069.47628458 +2 1 3 1 3 74176.10633109 72096.36337158 -72067.86948655 +2 1 3 1 4 0.36420755 538.96290653 -1559.23680634 +2 1 3 1 5 9477.30182443 3068.12727446 -3066.67044425 +2 1 3 1 6 0.10711987 1560.65078860 -539.11287434 +2 1 3 1 7 -0.29993563 -1561.43276364 539.63776170 +2 1 3 1 8 -9473.01702969 -3066.29552471 3063.76749581 +2 1 3 2 1 537.82743592 -0.10711987 3074.36165081 +2 1 3 2 2 -67119.78851937 -72109.14277189 80913.09981473 +2 1 3 2 3 72095.00294925 67136.52064283 -80912.71418320 +2 1 3 2 4 0.51417537 -538.70581884 -3074.34022684 +2 1 3 2 5 -3068.48077003 888.68785331 94.62969186 +2 1 3 2 6 -888.27008582 3063.37115230 -93.15143767 +2 1 3 2 7 -1557.45861652 1.38184630 3075.86132897 +2 1 3 2 8 0.64271921 1558.00492785 -3077.81091058 +2 1 3 3 1 1558.67978302 3074.40449876 -0.31064762 +2 1 3 3 2 67084.31041891 80902.81630735 -72062.98482054 +2 1 3 3 3 -72067.65524681 -80910.63605775 67096.88629147 +2 1 3 3 4 893.78675905 -83.23213785 3055.74421766 +2 1 3 3 5 3067.72021896 95.31525902 887.93801423 +2 1 3 3 6 -1.03906272 -3079.24631682 -536.52057352 +2 1 3 3 7 -534.67811179 3079.13919695 -0.26779967 +2 1 3 3 8 -1.04977471 -3078.61430959 1559.45104607 +2 2 3 1 1 -0.81411100 539.36996203 3074.26524293 +2 2 3 1 2 -72094.99223726 -67142.54077944 80912.70347121 +2 2 3 1 3 67126.66561492 72107.61095777 -80913.99962162 +2 2 3 1 4 -538.63083493 0.53559934 -3074.29737889 +2 2 3 1 5 -1.76747783 -1559.27965428 3080.53175524 +2 2 3 1 6 1557.99421586 0.70699113 -3077.81091058 +2 2 3 1 7 888.00228615 -3058.19726265 91.65175952 +2 2 3 1 8 3063.43542422 -888.25937383 -93.09787774 +2 2 3 2 1 -538.62012295 0.42847947 1558.30486348 +2 2 3 2 2 -72107.71807764 -74174.33885326 72072.29353712 +2 2 3 2 3 72109.50697945 74175.47432387 -72075.34645337 +2 2 3 2 4 538.97361851 0.36420755 -1559.19395839 +2 2 3 2 5 -1559.68670978 0.34278358 538.98433050 +2 2 3 2 6 -3066.29552471 -9473.05987764 3063.77820780 +2 2 3 2 7 3063.11406462 9470.57469669 -3059.60053293 +2 2 3 2 8 1560.62936463 0.12854384 -539.20928222 +2 2 3 3 1 3074.55446658 1560.10447727 -0.53559934 +2 2 3 3 2 80902.88057927 67095.07596570 -72062.42779723 +2 2 3 3 3 -80911.90007220 -72074.42522250 67095.40803729 +2 2 3 3 4 -83.26427381 893.74391110 3055.74421766 +2 2 3 3 5 3081.32444227 -535.96355021 -0.36420755 +2 2 3 3 6 -3078.63573357 -1.02835074 1559.47247005 +2 2 3 3 7 94.22263636 3063.62823999 889.23416464 +2 2 3 3 8 -3079.26774079 -1.04977471 -536.49914955 +2 3 3 1 1 -893.35827957 82.95362619 -3055.86204952 +2 3 3 1 2 72064.09886718 80909.45773920 -67096.52208392 +2 3 3 1 3 -67086.40996833 -80898.98141606 72061.18520675 +2 3 3 1 4 -1559.30107826 -3074.68301042 0.47132742 +2 3 3 1 5 2.18524532 3079.41770861 -1557.30864870 +2 3 3 1 6 535.95283822 -3081.13162650 -0.36420755 +2 3 3 1 7 2.63514877 3077.89660647 536.88478108 +2 3 3 1 8 -3065.72778941 -94.96176345 -888.60215741 +2 3 3 2 1 83.25356182 -893.61536726 -3055.86204952 +2 3 3 2 2 80911.12880915 72070.21541167 -67094.42253450 +2 3 3 2 3 -80900.47038223 -67090.39482744 72062.25640544 +2 3 3 2 4 -3074.67229843 -1559.34392621 0.47132742 +2 3 3 2 5 3080.84240286 0.10711987 536.26348584 +2 3 3 2 6 -94.96176345 -3065.70636543 -888.62358139 +2 3 3 2 7 3075.90417692 2.62443678 -1559.80454164 +2 3 3 2 8 -3081.13162650 535.95283822 -0.34278358 +2 3 3 3 1 3055.44428203 3055.24075428 -9478.87648650 +2 3 3 3 2 -72065.91990494 -72065.25576176 74112.89489667 +2 3 3 3 3 72065.13792990 72064.93440215 -74114.18033509 +2 3 3 3 4 -3055.29431421 -3055.29431421 9478.69438273 +2 3 3 3 5 -1555.32693114 -538.83436268 -1.73534187 +2 3 3 3 6 538.34161129 1556.38741783 2.76369261 +2 3 3 3 7 -538.72724282 -1555.42333902 -2.48518095 +2 3 3 3 8 1556.36599386 538.34161129 2.78511658 +2 1 4 1 1 -0.04284795 0.04284795 897.62165034 +2 1 4 1 2 -0.68556716 0.47132742 -5.48453727 +2 1 4 1 3 -0.06427192 0.12854384 897.66449829 +2 1 4 1 4 0.81411100 -0.44990345 -5.59165714 +2 1 4 1 5 -0.00000000 -0.00000000 -894.83653376 +2 1 4 1 6 -0.07498391 -0.32135961 -1.19974253 +2 1 4 1 7 0.04284795 -0.00000000 -886.58830388 +2 1 4 1 8 -0.00000000 0.27851166 -1.17831855 +2 1 4 2 1 -538.68439487 538.70581884 -83.01789811 +2 1 4 2 2 6.76997569 -1.42469425 -2969.41631561 +2 1 4 2 3 538.57727500 -538.59869897 -80.72553292 +2 1 4 2 4 -2.81725254 5.44168932 -2969.55557144 +2 1 4 2 5 -540.24834495 -540.24834495 -83.12501798 +2 1 4 2 6 -0.27851166 -0.06427192 3371.85494970 +2 1 4 2 7 535.55649471 535.55649471 -99.79286952 +2 1 4 2 8 0.98550279 0.85695895 2913.94964769 +2 1 4 3 1 -1559.83667760 -3074.96152208 -3058.42221437 +2 1 4 3 2 8.82667717 11785.60644743 6.17010443 +2 1 4 3 3 -1559.79382965 -3074.87582618 3058.40079040 +2 1 4 3 4 -5.74162495 -2970.54107423 0.85695895 +2 1 4 3 5 1560.82218039 -3075.15433784 3060.02901240 +2 1 4 3 6 -0.81411100 2915.31007002 -1.07119869 +2 1 4 3 7 1556.38741783 -3078.66786953 -3064.48519893 +2 1 4 3 8 -0.02142397 573.20912850 -1.28543842 +2 2 4 1 1 538.62012295 -538.70581884 -83.03932209 +2 2 4 1 2 2.20666929 -4.78825812 -2970.38039443 +2 2 4 1 3 -538.55585103 538.66297089 -80.89692471 +2 2 4 1 4 -6.07369655 0.92123087 -2970.34825847 +2 2 4 1 5 540.26976892 540.24834495 -80.89692471 +2 2 4 1 6 -0.94265484 -0.66414318 2913.74611994 +2 2 4 1 7 -535.66361458 -535.62076663 -99.94283734 +2 2 4 1 8 0.17139179 -0.06427192 3371.72640585 +2 2 4 2 1 -0.00000000 0.02142397 897.60022637 +2 2 4 2 2 -0.44990345 0.69627915 -5.50596124 +2 2 4 2 3 0.06427192 0.08569589 897.57880239 +2 2 4 2 4 0.51417537 -0.85695895 -5.46311330 +2 2 4 2 5 0.04284795 0.02142397 -895.00792555 +2 2 4 2 6 -0.26779967 -0.00000000 -1.19974253 +2 2 4 2 7 -0.04284795 0.08569589 -886.48118401 +2 2 4 2 8 0.27851166 -0.06427192 -1.29615041 +2 2 4 3 1 -3074.87582618 -1559.92237350 -3058.22939861 +2 2 4 3 2 11785.64929538 8.88023710 -6.13796847 +2 2 4 3 3 -3074.85440221 -1559.79382965 3058.35794245 +2 2 4 3 4 -2970.40181840 -5.69877701 -0.77126305 +2 2 4 3 5 -3075.21860976 1560.77933244 -3059.77192472 +2 2 4 3 6 573.08058465 -0.06427192 1.19974253 +2 2 4 3 7 -3078.62502158 1556.51596168 3064.54947085 +2 2 4 3 8 2915.22437412 -0.71770312 1.04977471 +2 3 4 1 1 -1559.75098171 -3074.94009810 3058.29367053 +2 3 4 1 2 -5.67735303 -2970.50893827 -0.72841511 +2 3 4 1 3 -1559.77240568 -3074.81155426 -3058.31509451 +2 3 4 1 4 8.76240525 11785.60644743 -6.14868045 +2 3 4 1 5 1560.75790847 -3075.21860976 -3059.81477267 +2 3 4 1 6 -0.04284795 573.19841651 1.24259047 +2 3 4 1 7 1556.49453770 -3078.73214145 3064.46377496 +2 3 4 1 8 -0.74983908 2915.35291796 1.03906272 +2 3 4 2 1 -3074.96152208 -1559.81525363 3058.29367053 +2 3 4 2 2 -2970.47680231 -5.67735303 0.63200722 +2 3 4 2 3 -3074.94009810 -1559.79382965 -3058.22939861 +2 3 4 2 4 11785.60644743 8.84810114 6.10583251 +2 3 4 2 5 -3075.19718579 1560.75790847 3059.81477267 +2 3 4 2 6 2915.33149399 -0.79268703 -1.09262266 +2 3 4 2 7 -3078.66786953 1556.51596168 -3064.46377496 +2 3 4 2 8 573.19841651 0.04284795 -1.30686240 +2 3 4 3 1 -0.04284795 -0.02142397 9480.08694102 +2 3 4 3 2 9.46939638 -9.45868439 -6.74855172 +2 3 4 3 3 -0.04284795 -0.02142397 9480.27975678 +2 3 4 3 4 -9.41583644 9.55509227 -6.66285582 +2 3 4 3 5 0.04284795 0.04284795 -9484.05037615 +2 3 4 3 6 -1.27472644 -1.32828637 -2.61372479 +2 3 4 3 7 -0.04284795 0.04284795 -9457.20613710 +2 3 4 3 8 1.24259047 1.33899836 -2.63514877 +2 1 5 1 1 -1.37113432 1559.48318203 -536.74552525 +2 1 5 1 2 -74173.56759021 72113.86675809 -72082.25568489 +2 1 5 1 3 9477.44108026 -3068.12727446 3067.24889154 +2 1 5 1 4 0.21423974 -540.84821621 1560.26515707 +2 1 5 1 5 74163.21981091 -72101.89075679 72063.22048425 +2 1 5 1 6 -1.04977471 -1561.03642013 541.72659913 +2 1 5 1 7 -1.13547061 538.39517122 -1558.10133573 +2 1 5 1 8 -9463.80472100 3060.09328432 -3055.18719435 +2 1 5 2 1 1560.02949336 -0.37491954 3080.53175524 +2 1 5 2 2 67117.81751378 -72109.50697945 80902.50565973 +2 1 5 2 3 3068.91996149 888.06655807 94.88677954 +2 1 5 2 4 -0.52488736 -540.18407303 -3074.68301042 +2 1 5 2 5 -72100.32680671 67159.12293509 -80923.66183376 +2 1 5 2 6 889.54481225 3054.26596348 -86.85278940 +2 1 5 2 7 -533.90684873 -3.63136354 3077.32887117 +2 1 5 2 8 -1.56395008 1552.14547104 -3070.03400812 +2 1 5 3 1 537.93455579 3080.68172306 -0.39634351 +2 1 5 3 2 -67092.28013713 80902.75203543 -72062.01002974 +2 1 5 3 3 -3066.95966790 94.73681173 888.06655807 +2 1 5 3 4 -891.08733836 -81.19686035 3057.41528761 +2 1 5 3 5 72059.81407243 -80921.73367613 67085.81009707 +2 1 5 3 6 3.05291625 -3077.59667084 -534.78523165 +2 1 5 3 7 -1556.53738565 3074.92938612 3.52424367 +2 1 5 3 8 6.08440853 -3072.58346099 1562.17189073 +2 2 5 1 1 -888.08798204 -3068.91996149 94.89749153 +2 2 5 1 2 72109.53911541 -67117.89249769 80902.48423576 +2 2 5 1 3 0.39634351 -1560.05091734 3080.57460319 +2 2 5 1 4 540.16264905 0.55702332 -3074.64016247 +2 2 5 1 5 -67159.14435906 72100.39107863 -80923.83322555 +2 2 5 1 6 -1552.10262309 1.60679803 -3070.05543210 +2 2 5 1 7 3.64207553 533.90684873 3077.29673521 +2 2 5 1 8 -3054.30881142 -889.57694822 -86.90634934 +2 2 5 2 1 3068.10585049 -9477.40894430 3067.23817955 +2 2 5 2 2 -72113.93103002 74173.47118233 -72082.21283694 +2 2 5 2 3 -1559.47247005 1.43540624 -536.73481326 +2 2 5 2 4 540.79465628 -0.23566371 1560.30800502 +2 2 5 2 5 72101.93360474 -74163.28408283 72063.02766849 +2 2 5 2 6 -3060.05043638 9463.82614497 -3055.18719435 +2 2 5 2 7 -538.38445924 1.13547061 -1558.10133573 +2 2 5 2 8 1560.99357218 1.01763875 541.66232721 +2 2 5 3 1 94.71538776 -3066.95966790 -888.12011800 +2 2 5 3 2 80902.81630735 -67092.44081693 72062.11714961 +2 2 5 3 3 3080.68172306 537.91313182 0.36420755 +2 2 5 3 4 -81.17543637 -891.10876234 -3057.45813556 +2 2 5 3 5 -80921.89435593 72059.87834435 -67085.87436899 +2 2 5 3 6 -3072.57274901 6.08440853 -1562.15046676 +2 2 5 3 7 3074.94009810 -1556.53738565 -3.53495566 +2 2 5 3 8 -3077.61809482 3.05291625 534.84950358 +2 3 5 1 1 -0.94265484 3079.87832404 538.45944314 +2 3 5 1 2 -72076.28910821 80899.54915136 -67091.74453778 +2 3 5 1 3 -0.27851166 3080.51033127 -1555.12340339 +2 3 5 1 4 1560.82218039 -3074.44734671 0.47132742 +2 3 5 1 5 67094.89386192 -80910.01476251 72055.57212564 +2 3 5 1 6 -530.70396466 -3076.84683176 0.51417537 +2 3 5 1 7 889.63050815 93.59062914 -3056.76185641 +2 3 5 1 8 3062.81412898 -92.15522290 -891.29086611 +2 3 5 2 1 3080.51033127 -0.26779967 1555.09126742 +2 3 5 2 2 80899.49559142 -72076.25697225 67091.74453778 +2 3 5 2 3 3079.86761205 -1.00692676 -538.44873116 +2 3 5 2 4 -3074.42592273 1560.86502834 -0.42847947 +2 3 5 2 5 -80910.05761046 67094.85101397 -72055.33646193 +2 3 5 2 6 -92.11237495 3062.77128104 891.32300207 +2 3 5 2 7 93.60134112 889.66264411 3056.79399237 +2 3 5 2 8 -3076.86825574 -530.67182870 -0.50346338 +2 3 5 3 1 -536.90620505 1557.46932851 -2.82796453 +2 3 5 3 2 -72066.43408031 72066.63760806 -74083.89754826 +2 3 5 3 3 -1557.42648056 536.90620505 -2.82796453 +2 3 5 3 4 -3056.79399237 3057.11535198 -9483.08629733 +2 3 5 3 5 72059.12850528 -72061.37802251 74120.17904773 +2 3 5 3 6 540.67682442 -1552.85246217 -6.34149622 +2 3 5 3 7 3064.05671946 -3064.05671946 9465.69003069 +2 3 5 3 8 1553.62372523 -539.85200144 -6.90923152 +2 1 6 1 1 0.12854384 886.41691209 -1.15689458 +2 1 6 1 2 0.08569589 2.37806108 8.83738915 +2 1 6 1 3 -0.21423974 -886.45976004 -1.19974253 +2 1 6 1 4 0.08569589 -0.04284795 -0.29993563 +2 1 6 1 5 -0.47132742 891.28015412 3.34213990 +2 1 6 1 6 0.20352775 -2.29236519 -8.86952511 +2 1 6 1 7 -0.08569589 -891.30157810 -1.09262266 +2 1 6 1 8 0.19281576 0.04284795 0.33207159 +2 1 6 2 1 -1561.16496397 -3065.98487709 -3079.41770861 +2 1 6 2 2 6.98421543 -0.08569589 11784.99586418 +2 1 6 2 3 1561.14354000 3065.92060517 -3079.22489284 +2 1 6 2 4 -0.18210378 -0.10711987 2915.26722207 +2 1 6 2 5 -1560.37227694 3055.76564164 -3077.03964753 +2 1 6 2 6 -2.32450115 3.83489129 -2964.86372120 +2 1 6 2 7 1555.18767531 -3059.10778153 -3074.06171518 +2 1 6 2 8 0.79268703 -0.23566371 574.52670288 +2 1 6 3 1 -539.04860242 -90.73052865 536.58484545 +2 1 6 3 2 6.42719211 -2961.02882991 -0.50346338 +2 1 6 3 3 -539.09145037 -90.75195262 -536.54199750 +2 1 6 3 4 -0.80339901 3371.85494970 -0.53559934 +2 1 6 3 5 542.28362245 -86.98133325 -534.31390423 +2 1 6 3 6 -5.13104170 -2964.30669788 -1.39255829 +2 1 6 3 7 535.36367894 -92.25163078 537.76316400 +2 1 6 3 8 -0.00000000 2914.30314325 -1.11404663 +2 2 6 1 1 -1558.52981520 3063.30688038 -3078.06799826 +2 2 6 1 2 1.75676584 4.67042627 -2955.29791694 +2 2 6 1 3 1558.44411931 -3063.19976051 -3078.15369416 +2 2 6 1 4 -0.67485517 -0.06427192 573.66974393 +2 2 6 1 5 -1552.65964641 -3060.92881930 -3072.66915689 +2 2 6 1 6 -6.28793628 0.74983908 11771.78798439 +2 2 6 1 7 1557.77997612 3055.33716216 -3075.58281731 +2 2 6 1 8 0.08569589 0.12854384 2914.09961550 +2 2 6 2 1 -0.42847947 9471.68874332 -1.97100558 +2 2 6 2 2 -0.02142397 -3.06362824 6.94136748 +2 2 6 2 3 0.44990345 -9471.62447140 -1.97100558 +2 2 6 2 4 -0.81411100 0.10711987 -0.21423974 +2 2 6 2 5 1.17831855 9463.44051345 5.78447290 +2 2 6 2 6 0.01071199 3.14932413 -6.98421543 +2 2 6 2 7 0.36420755 -9463.44051345 -1.94958161 +2 2 6 2 8 -0.79268703 -0.10711987 0.12854384 +2 2 6 3 1 -3078.11084621 3061.63581043 -1559.04399057 +2 2 6 3 2 -2959.50772777 -3.92058719 1.53181412 +2 2 6 3 3 -3078.15369416 3061.59296248 1559.06541455 +2 2 6 3 4 2913.71398398 -0.62129524 1.00692676 +2 2 6 3 5 -3070.37679170 -3054.33023540 -1562.40755445 +2 2 6 3 6 11772.96630295 -4.02770706 1.54252611 +2 2 6 3 7 -3075.56139334 -3061.35729877 1557.35149665 +2 2 6 3 8 574.78379056 1.11404663 1.03906272 +2 3 6 1 1 535.49222279 -94.37260418 -538.34161129 +2 3 6 1 2 5.12032972 -2955.72639641 -2.58158883 +2 3 6 1 3 535.57791868 -94.39402815 538.29876334 +2 3 6 1 4 0.03213596 2915.50288578 -1.28543842 +2 3 6 1 5 -531.78587534 -98.05752765 539.75559355 +2 3 6 1 6 -6.44861609 -2959.05782433 0.83553497 +2 3 6 1 7 -538.77009076 -88.41673949 -536.04924610 +2 3 6 1 8 0.79268703 3374.69362621 -0.55702332 +2 3 6 2 1 -3080.61745113 -3069.39128891 -1556.34456989 +2 3 6 2 2 11786.37771049 8.56958948 -3.54566765 +2 3 6 2 3 -3080.70314703 -3069.43413686 1556.32314591 +2 3 6 2 4 572.99488876 -0.14996782 -1.26401445 +2 3 6 2 5 -3078.08942224 3060.28610009 -1554.73777186 +2 3 6 2 6 -2963.12837933 8.44104564 0.36420755 +2 3 6 2 7 -3073.01194047 3060.07186035 1559.85810157 +2 3 6 2 8 2916.01706115 1.43540624 -0.68556716 +2 3 6 3 1 0.12854384 885.32428943 2.46375698 +2 3 6 3 2 -2.39948506 3.48139573 -2.67799671 +2 3 6 3 3 -0.17139179 -885.36713738 2.48518095 +2 3 6 3 4 1.07119869 -0.08569589 -1.86388571 +2 3 6 3 5 -0.42847947 890.10183557 -7.45554285 +2 3 6 3 6 1.42469425 1.94958161 2.63514877 +2 3 6 3 7 -0.34278358 -896.80753934 2.50660492 +2 3 6 3 8 0.66414318 1.27472644 1.84246174 +2 1 7 1 1 -9469.58919390 3060.51105181 3063.71393588 +2 1 7 1 2 74060.92033646 -71905.42220592 -71940.73962657 +2 1 7 1 3 -0.19281576 -1555.80897054 -535.51364676 +2 1 7 1 4 -0.69627915 535.94212623 1555.65900273 +2 1 7 1 5 -1.01763875 -534.44244807 -1556.40884181 +2 1 7 1 6 -0.96407882 1554.24502046 535.79215842 +2 1 7 1 7 -74051.60090790 71902.41213761 71937.42962264 +2 1 7 1 8 9463.16200179 -3057.43671158 -3059.97545247 +2 1 7 2 1 -3065.19219007 -890.86238664 93.19428562 +2 1 7 2 2 -66918.29604666 71901.25524303 80696.62127241 +2 1 7 2 3 -1561.19709993 0.66414318 3079.20346887 +2 1 7 2 4 0.35349557 535.42795087 -3078.30366197 +2 1 7 2 5 538.17021950 -2.74226863 3075.53996937 +2 1 7 2 6 -890.29465133 -3058.82926988 -90.85907249 +2 1 7 2 7 71896.13491332 -66927.43337144 -80700.32761986 +2 1 7 2 8 0.12854384 -1557.40505658 -3075.04721797 +2 1 7 3 1 -3060.50033982 90.22706526 -890.13397153 +2 1 7 3 2 -66969.62788766 80709.22928094 71950.99099799 +2 1 7 3 3 540.01268124 3075.39000155 -0.49275140 +2 1 7 3 4 -884.81011407 -101.65675524 -3065.12791814 +2 1 7 3 5 -1559.93308548 3079.56767642 1.77818982 +2 1 7 3 6 -0.85695895 -3073.03336444 537.46322837 +2 1 7 3 7 71939.62557994 -80702.99490459 -66976.26931951 +2 1 7 3 8 -3.96343514 -3076.83611978 -1558.30486348 +2 2 7 1 1 0.21423974 1561.78625921 3079.80334013 +2 2 7 1 2 -71903.80469591 66918.51028640 80696.89978407 +2 2 7 1 3 891.04449041 3065.10649417 93.32282946 +2 2 7 1 4 -535.42795087 -0.42847947 -3078.34650992 +2 2 7 1 5 2.99935632 -538.12737155 3075.41142552 +2 2 7 1 6 1557.39434460 -0.14996782 -3075.04721797 +2 2 7 1 7 66928.72952185 -71897.00258425 -80701.29169868 +2 2 7 1 8 3058.76499795 890.24109140 -90.79480057 +2 2 7 2 1 1555.83039452 0.23566371 -535.47079881 +2 2 7 2 2 71905.26152612 -74060.84535255 -71940.55752280 +2 2 7 2 3 -3060.53247578 9469.65346582 3063.69251191 +2 2 7 2 4 -535.97426219 0.70699113 1555.59473081 +2 2 7 2 5 534.44244807 0.96407882 -1556.51596168 +2 2 7 2 6 3057.43671158 -9463.14057781 -3060.02901240 +2 2 7 2 7 -71902.24074582 74051.44022810 71937.32250277 +2 2 7 2 8 -1554.18074854 1.02835074 535.80287040 +2 2 7 3 1 3075.39000155 539.99125726 0.47132742 +2 2 7 3 2 80709.40067273 -66969.85283938 -71951.14096581 +2 2 7 3 3 90.21635328 -3060.52176380 890.12325954 +2 2 7 3 4 -101.65675524 -884.78869009 3065.04222225 +2 2 7 3 5 3079.64266033 -1559.90094952 -1.79961379 +2 2 7 3 6 -3076.85754375 -4.02770706 1558.31557547 +2 2 7 3 7 -80703.27341625 71939.86124365 66976.37643938 +2 2 7 3 8 -3073.03336444 -0.83553497 -537.45251638 +2 3 7 1 1 3.53495566 3077.93945442 1556.83732128 +2 3 7 1 2 -71942.21788076 80699.11716535 66981.27181737 +2 3 7 1 3 2.48518095 3075.53996937 -537.99882771 +2 3 7 1 4 1556.86945724 -3078.90353324 0.51417537 +2 3 7 1 5 891.39798598 92.57299038 3063.88532767 +2 3 7 1 6 -538.50229109 -3072.51918907 -0.29993563 +2 3 7 1 7 66969.13513626 -80705.09445401 -71954.82588929 +2 3 7 1 8 3057.32959172 -88.63097922 890.76597876 +2 3 7 2 1 3075.51854539 2.47446896 538.03096367 +2 3 7 2 2 80699.28855714 -71942.34642460 -66981.41107320 +2 3 7 2 3 3077.88589449 3.51353169 -1556.85874526 +2 3 7 2 4 -3078.93566920 1556.83732128 -0.47132742 +2 3 7 2 5 92.50871846 891.38727399 -3063.79963178 +2 3 7 2 6 -88.57741929 3057.39386364 -890.72313081 +2 3 7 2 7 -80705.30869375 66969.18869620 71955.05084101 +2 3 7 2 8 -3072.51918907 -538.44873116 0.36420755 +2 3 7 3 1 1559.10826249 -536.75623723 -3.21359606 +2 3 7 3 2 71946.24558782 -71946.22416384 -74126.15633640 +2 3 7 3 3 536.79908518 -1559.08683852 -3.21359606 +2 3 7 3 4 3067.70950698 -3067.69879499 -9458.19163989 +2 3 7 3 5 -3058.14370272 3058.20797464 9466.35417387 +2 3 7 3 6 -536.20992591 1559.45104607 2.91366042 +2 3 7 3 7 -71955.95064791 71956.00420784 74118.46512984 +2 3 7 3 8 -1559.42962210 536.20992591 2.99935632 +2 1 8 1 1 9471.64589538 -0.38563153 -1.99242955 +2 1 8 1 2 3.02078029 0.02142397 6.95207947 +2 1 8 1 3 -9471.53877551 0.38563153 -1.97100558 +2 1 8 1 4 -0.08569589 0.81411100 -0.23566371 +2 1 8 1 5 -9463.50478537 -1.19974253 5.74162495 +2 1 8 1 6 0.13925583 0.77126305 0.25708768 +2 1 8 1 7 9463.48336139 -0.49275140 -1.99242955 +2 1 8 1 8 -3.08505221 0.06427192 -6.88780755 +2 1 8 2 1 3063.32830435 -1558.52981520 -3077.98230237 +2 1 8 2 2 -4.69185024 -1.77818982 -2955.30862893 +2 1 8 2 3 -3063.22118448 1558.50839123 -3078.17511813 +2 1 8 2 4 0.08569589 0.68556716 573.75543983 +2 1 8 2 5 3060.84312340 1552.55252654 -3072.58346099 +2 1 8 2 6 -0.04284795 -0.19281576 2914.04605557 +2 1 8 2 7 -3055.20861832 -1557.71570420 -3075.58281731 +2 1 8 2 8 -0.81411100 6.39505615 11771.69157651 +2 1 8 3 1 3061.50726659 -3078.08942224 -1559.04399057 +2 1 8 3 2 -4.77754614 -2958.82216061 -0.83553497 +2 1 8 3 3 3061.61438646 -3078.08942224 1558.89402276 +2 1 8 3 4 -0.79268703 2913.66042404 -0.85695895 +2 1 8 3 5 -3054.39450732 -3070.33394376 1562.55752226 +2 1 8 3 6 0.95336683 574.82663851 -1.11404663 +2 1 8 3 7 -3059.08635756 -3075.43284950 -1557.28722473 +2 1 8 3 8 -4.94893793 11772.39856764 -2.31378916 +2 2 8 1 1 -3065.96345312 -1561.10069205 -3079.46055655 +2 2 8 1 2 0.10711987 -6.98421543 11784.98515220 +2 2 8 1 3 3066.00630107 1561.12211602 -3079.16062092 +2 2 8 1 4 0.05355993 0.17139179 2915.28864604 +2 2 8 1 5 -3055.74421766 1560.26515707 -3076.99679958 +2 2 8 1 6 0.17139179 -0.77126305 574.46243096 +2 2 8 1 7 3059.12920551 -1555.18767531 -3074.14741108 +2 2 8 1 8 -3.79204335 2.48518095 -2964.81016127 +2 2 8 2 1 886.39548812 0.17139179 -1.09262266 +2 2 8 2 2 -2.42090903 -0.13925583 8.76240525 +2 2 8 2 3 -886.45976004 -0.25708768 -1.17831855 +2 2 8 2 4 -0.00000000 -0.06427192 -0.32135961 +2 2 8 2 5 -891.21588220 0.40705550 3.34213990 +2 2 8 2 6 -0.05355993 -0.06427192 0.27851166 +2 2 8 2 7 891.36585002 0.23566371 -1.09262266 +2 2 8 2 8 2.37806108 -0.18210378 -8.86952511 +2 2 8 3 1 -90.75195262 -539.02717845 536.60626942 +2 2 8 3 2 -2961.97148475 7.03777536 -0.23566371 +2 2 8 3 3 -90.81622454 -539.13429832 -536.62769339 +2 2 8 3 4 3371.66213393 -0.96407882 0.53559934 +2 2 8 3 5 -84.90320780 542.19792656 534.14251244 +2 2 8 3 6 2914.08890352 0.14996782 1.24259047 +2 2 8 3 7 -92.23020681 535.29940702 -537.78458797 +2 2 8 3 8 -2965.14223286 -5.70948899 1.94958161 +2 3 8 1 1 -3069.34844096 -3080.59602716 -1556.32314591 +2 3 8 1 2 8.50531756 11786.39913446 2.34592512 +2 3 8 1 3 -3069.26274507 -3080.59602716 1556.43026578 +2 3 8 1 4 -0.19281576 573.02702472 1.00692676 +2 3 8 1 5 3062.55704130 -3078.02515032 1554.60922802 +2 3 8 1 6 1.45683021 2916.01706115 1.04977471 +2 3 8 1 7 3057.84376708 -3072.90482060 -1559.90094952 +2 3 8 1 8 8.39819769 -2963.10695536 0.92123087 +2 3 8 2 1 -94.43687610 535.57791868 -538.32018732 +2 3 8 2 2 -2955.75853237 5.20602561 2.49589294 +2 3 8 2 3 -94.52257199 535.53507073 538.25591539 +2 3 8 2 4 2915.46003783 -0.02142397 1.28543842 +2 3 8 2 5 -98.03610368 -531.82872328 -539.62704971 +2 3 8 2 6 3374.60793032 0.74983908 0.47132742 +2 3 8 2 7 -88.45958743 -538.83436268 536.02782213 +2 3 8 2 8 -2958.99355240 -6.39505615 -0.91051888 +2 3 8 3 1 885.30286546 0.17139179 2.37806108 +2 3 8 3 2 -1.73534187 1.22116650 -2.57087684 +2 3 8 3 3 -885.36713738 -0.19281576 2.46375698 +2 3 8 3 4 0.52488736 -0.92123087 -1.79961379 +2 3 8 3 5 -892.24423294 0.40705550 -7.45554285 +2 3 8 3 6 -0.86767094 -0.72841511 1.75676584 +2 3 8 3 7 894.47232621 0.17139179 2.42090903 +2 3 8 3 8 -0.19281576 -0.09640788 2.64586075 +3 1 1 1 1 -0.04284795 0.08569589 4.69185024 +3 1 1 1 2 -0.64271921 -0.00000000 -897.66449829 +3 1 1 1 3 0.01071199 0.02142397 4.54188243 +3 1 1 1 4 0.67485517 -0.08569589 -897.49310650 +3 1 1 1 5 0.04284795 0.02142397 1.60679803 +3 1 1 1 6 -0.70699113 0.06427192 891.92287334 +3 1 1 1 7 -0.00000000 0.06427192 0.55702332 +3 1 1 1 8 0.62129524 -0.00000000 891.86931340 +3 1 1 2 1 0.06427192 0.02142397 2970.18757867 +3 1 1 2 2 -539.11287434 539.09145037 80.63983703 +3 1 1 2 3 0.06427192 0.08569589 2970.36968244 +3 1 1 2 4 538.97361851 -538.89863461 80.68268498 +3 1 1 2 5 0.02142397 -0.12854384 -2913.72469596 +3 1 1 2 6 -537.54892426 -537.63462016 91.65175952 +3 1 1 2 7 0.04284795 0.01071199 -3371.82281374 +3 1 1 2 8 537.61319618 537.65604413 91.69460746 +3 1 1 3 1 7.02706338 2969.23421184 0.11783186 +3 1 1 3 2 1560.54366873 3074.81155426 -3058.35794245 +3 1 1 3 3 -12.64014449 -11784.25673709 0.02142397 +3 1 1 3 4 1560.58651668 3074.83297823 3058.40079040 +3 1 1 3 5 -0.71770312 -573.39123227 0.08569589 +3 1 1 3 6 -1557.95136791 3077.01822355 3060.07186035 +3 1 1 3 7 1.00692676 -2915.16010220 -0.02142397 +3 1 1 3 8 -1557.84424805 3076.98608759 -3059.95402849 +3 2 1 1 1 0.04284795 -0.11783186 2970.23042661 +3 2 1 1 2 538.27733937 -538.34161129 81.04689253 +3 2 1 1 3 0.04284795 -0.00000000 2970.15544271 +3 2 1 1 4 -538.26662738 538.34161129 81.19686035 +3 2 1 1 5 -0.01071199 0.04284795 -3371.81210175 +3 2 1 1 6 538.19164347 538.32018732 91.52321567 +3 2 1 1 7 0.02142397 0.03213596 -2913.68184802 +3 2 1 1 8 -538.29876334 -538.34161129 91.42680779 +3 2 1 2 1 -0.14996782 -0.05355993 4.53117044 +3 2 1 2 2 -0.00000000 0.74983908 -897.49310650 +3 2 1 2 3 0.05355993 -0.08569589 4.71327422 +3 2 1 2 4 0.07498391 -0.72841511 -897.32171471 +3 2 1 2 5 0.06427192 0.04284795 1.58537405 +3 2 1 2 6 -0.23566371 -0.59987126 891.92287334 +3 2 1 2 7 0.02142397 0.03213596 0.46061543 +3 2 1 2 8 -0.00000000 0.62129524 891.85860142 +3 2 1 3 1 2969.12709197 6.95207947 0.01071199 +3 2 1 3 2 3074.91867413 1559.02256660 -3058.46506232 +3 2 1 3 3 -11784.26744908 -7.66978259 -0.04284795 +3 2 1 3 4 3074.96152208 1559.04399057 3058.31509451 +3 2 1 3 5 -2915.17081419 0.89980690 0.06427192 +3 2 1 3 6 3076.91110368 -1559.25823031 -3059.72907677 +3 2 1 3 7 -573.41265625 0.44990345 0.02142397 +3 2 1 3 8 3076.80398381 -1559.34392621 3059.88975657 +3 3 1 1 1 -7.58408669 -11784.32100901 -0.03213596 +3 3 1 1 2 1559.04399057 3074.96152208 3058.50791027 +3 3 1 1 3 6.89851953 2969.19136389 0.06427192 +3 3 1 1 4 1559.04399057 3075.02579400 -3058.44363835 +3 3 1 1 5 0.88909491 -2915.16010220 0.06427192 +3 3 1 1 6 -1559.38677415 3076.86825574 -3059.94331651 +3 3 1 1 7 0.53559934 -573.32696035 0.01071199 +3 3 1 1 8 -1559.40819813 3076.83611978 3059.93260452 +3 3 1 2 1 -11784.42812888 -12.51160064 0.07498391 +3 3 1 2 2 3074.94009810 1560.47939681 3058.25082259 +3 3 1 2 3 2969.15922793 7.15560722 -0.06427192 +3 3 1 2 4 3074.86511419 1560.58651668 -3058.10085477 +3 3 1 2 5 -573.27340042 -0.72841511 -0.06427192 +3 3 1 2 6 3076.91110368 -1557.95136791 3060.11470830 +3 3 1 2 7 -2915.22437412 1.00692676 -0.05355993 +3 3 1 2 8 3076.97537560 -1557.95136791 -3060.11470830 +3 3 1 3 1 -0.06427192 0.06427192 11.24758620 +3 3 1 3 2 0.10711987 -0.06427192 -9480.12978896 +3 3 1 3 3 0.02142397 -0.06427192 11.16189030 +3 3 1 3 4 -0.07498391 -0.00000000 -9480.06551704 +3 3 1 3 5 0.01071199 0.02142397 3.92058719 +3 3 1 3 6 0.17139179 0.12854384 9465.28297519 +3 3 1 3 7 -0.02142397 -0.02142397 3.11718817 +3 3 1 3 8 -0.21423974 -0.12854384 9465.26155121 +3 1 2 1 1 -0.85695895 -539.56277779 1559.91166151 +3 1 2 1 2 -74179.69484669 -72096.74900310 72069.39058868 +3 1 2 1 3 74175.97778725 72096.19197979 -72067.48385502 +3 1 2 1 4 0.37491954 538.98433050 -1559.15111044 +3 1 2 1 5 9477.31253642 3068.17012241 -3066.67044425 +3 1 2 1 6 0.16067980 1560.65078860 -539.21999421 +3 1 2 1 7 -0.25708768 -1561.43276364 539.66989766 +3 1 2 1 8 -9473.05987764 -3066.27410074 3063.74607184 +3 1 2 2 1 -0.57844729 538.99504249 3074.40449876 +3 1 2 2 2 -72093.98531050 -67136.92769833 80911.73939240 +3 1 2 2 3 67125.08024087 72103.30473906 -80912.20000783 +3 1 2 2 4 -538.69510686 0.74983908 -3074.38307479 +3 1 2 2 5 -1.98171757 -1559.53674197 3080.25324358 +3 1 2 2 6 1557.35149665 1.58537405 -3077.14676739 +3 1 2 2 7 889.24487662 -3060.01830042 90.39845705 +3 1 2 2 8 3063.49969614 -888.05584608 -93.03360582 +3 1 2 3 1 -893.33685560 82.97505016 -3055.85133753 +3 1 2 3 2 72063.69181167 80909.16851555 -67096.30784418 +3 1 2 3 3 -67086.14216866 -80898.70290440 72061.14235880 +3 1 2 3 4 -1559.26894230 -3074.64016247 0.59987126 +3 1 2 3 5 2.18524532 3079.46055655 -1557.26580076 +3 1 2 3 6 536.02782213 -3081.17447445 -0.34278358 +3 1 2 3 7 2.63514877 3077.88589449 536.89549306 +3 1 2 3 8 -3065.72778941 -94.97247544 -888.66642933 +3 2 2 1 1 537.89170784 -0.31064762 3074.43663472 +3 2 2 1 2 -67119.38146386 -72106.87183068 80913.15337466 +3 2 2 1 3 72091.97145697 67135.51371607 -80913.99962162 +3 2 2 1 4 1.34971034 -538.10594758 -3073.52611584 +3 2 2 1 5 -3068.60931387 888.49503754 94.60826789 +3 2 2 1 6 -887.97015019 3063.41400025 -92.91577396 +3 2 2 1 7 -1556.79447333 0.47132742 3075.22932175 +3 2 2 1 8 1.49967816 1557.42648056 -3076.98608759 +3 2 2 2 1 -538.64154692 0.42847947 1558.26201553 +3 2 2 2 2 -72107.65380572 -74174.14603750 72072.33638507 +3 2 2 2 3 72109.41057156 74175.38862797 -72075.34645337 +3 2 2 2 4 538.97361851 0.38563153 -1559.19395839 +3 2 2 2 5 -1559.71884575 0.36420755 538.92005858 +3 2 2 2 6 -3066.30623670 -9473.01702969 3063.82105575 +3 2 2 2 7 3063.13548859 9470.58540868 -3059.57910895 +3 2 2 2 8 1560.69363655 0.09640788 -539.20928222 +3 2 2 3 1 83.29640977 -893.59394329 -3055.82991356 +3 2 2 3 2 80911.27877696 72070.39751544 -67094.63677423 +3 2 2 3 3 -80900.57750210 -67090.39482744 72062.44922120 +3 2 2 3 4 -3074.67229843 -1559.30107826 0.47132742 +3 2 2 3 5 3080.88525081 0.10711987 536.28490981 +3 2 2 3 6 -94.95105147 -3065.77063736 -888.68785331 +3 2 2 3 7 3075.88275295 2.62443678 -1559.79382965 +3 2 2 3 8 -3081.13162650 535.98497418 -0.35349557 +3 3 2 1 1 1558.74405494 3074.40449876 -0.32135961 +3 3 2 1 2 67084.16045109 80902.76274741 -72062.98482054 +3 3 2 1 3 -72067.52670297 -80910.57178583 67096.80059558 +3 3 2 1 4 893.76533507 -83.21071387 3055.74421766 +3 3 2 1 5 3067.72021896 95.22956312 888.02371012 +3 3 2 1 6 -1.11404663 -3079.20346887 -536.39202968 +3 3 2 1 7 -534.72095973 3079.14990894 -0.26779967 +3 3 2 1 8 -1.02835074 -3078.63573357 1559.50460601 +3 3 2 2 1 3074.59731452 1560.11518926 -0.54631133 +3 3 2 2 2 80902.79488338 67095.00098179 -72062.32067736 +3 3 2 2 3 -80911.81437631 -72074.38237455 67095.25806947 +3 3 2 2 4 -83.22142586 893.78675905 3055.74421766 +3 3 2 2 5 3081.30301829 -535.98497418 -0.38563153 +3 3 2 2 6 -3078.64644555 -1.04977471 1559.49389402 +3 3 2 2 7 94.24406033 3063.59610402 889.20202868 +3 3 2 2 8 -3079.18204490 -1.11404663 -536.40274167 +3 3 2 3 1 3055.48712998 3055.31573819 -9478.86577451 +3 3 2 3 2 -72065.34145765 -72064.62375453 74112.07007368 +3 3 2 3 3 72065.08436997 72064.91297818 -74112.16648157 +3 3 2 3 4 -3055.92632144 -3055.93703342 9477.79457583 +3 3 2 3 5 -1555.29479517 -538.92005858 -1.64964598 +3 3 2 3 6 538.24520341 1556.45168975 2.59230082 +3 3 2 3 7 -538.77009076 -1555.44476299 -2.49589294 +3 3 2 3 8 1556.47311373 538.24520341 2.63514877 +3 1 3 1 1 0.64271921 -0.07498391 -11.75104958 +3 1 3 1 2 74172.21787986 67121.29890951 -67081.84666193 +3 1 3 1 3 3.37427586 -0.42847947 107.03417264 +3 1 3 1 4 -74176.08490712 -67120.94541395 -67081.37533451 +3 1 3 1 5 3.62065156 0.08569589 9.85502790 +3 1 3 1 6 -74114.57667861 67021.68814376 67030.98614835 +3 1 3 1 7 0.74983908 0.03213596 -4.16696289 +3 1 3 1 8 74110.19547598 -67021.61315986 67031.22181206 +3 1 3 2 1 -0.08569589 -0.20352775 -11785.57431147 +3 1 3 2 2 72096.29909966 72106.66830293 -80899.92407090 +3 1 3 2 3 -1.83174975 -3.29929195 329268.90820573 +3 1 3 2 4 -72094.36023004 -72104.91153709 -80898.81002427 +3 1 3 2 5 0.08569589 -0.12854384 2960.08617506 +3 1 3 2 6 72011.81365935 -71998.67005148 -80802.48783848 +3 1 3 2 7 -0.70699113 -0.91051888 2960.71818229 +3 1 3 2 8 -72011.28877199 72001.30520024 -80802.65923027 +3 1 3 3 1 4.69185024 2970.58392218 1.94958161 +3 1 3 3 2 -72069.49770855 -80912.14644790 72059.73908853 +3 1 3 3 3 111.45822321 329278.05624250 2.35663711 +3 1 3 3 4 -72068.66217357 -80911.19308107 -72063.00624452 +3 1 3 3 5 -8.89094909 2954.21600627 -0.29993563 +3 1 3 3 6 72017.66240417 -80799.61702601 -72002.26927906 +3 1 3 3 7 -1.58537405 -11781.05385302 0.28922365 +3 1 3 3 8 72014.75945573 -80798.96359481 72001.43374408 +3 2 3 1 1 -0.04284795 -0.21423974 -11785.60644743 +3 2 3 1 2 72094.69230163 72105.02936894 -80898.76717632 +3 2 3 1 3 0.84624696 -0.53559934 329269.31526123 +3 2 3 1 4 -72094.91725335 -72105.44713643 -80898.98141606 +3 2 3 1 5 0.05355993 -0.10711987 2960.10759904 +3 2 3 1 6 72012.35997067 -71999.78409811 -80803.40906935 +3 2 3 1 7 -0.70699113 -0.97479080 2960.64319838 +3 2 3 1 8 -72012.31712273 72001.85151157 -80803.26981352 +3 2 3 2 1 0.49275140 0.17139179 -6.94136748 +3 2 3 2 2 67130.41481032 74170.00049859 -67084.05333122 +3 2 3 2 3 5.58094515 0.98550279 133.83556374 +3 2 3 2 4 -67134.68889308 -74174.48882108 -67084.07475520 +3 2 3 2 5 3.82417931 0.29993563 -15.36098915 +3 2 3 2 6 -67016.97486955 74116.72978797 67028.92944688 +3 2 3 2 7 -1.19974253 0.93194286 -1.14618259 +3 2 3 2 8 67012.69007481 -74114.59810258 67028.84375098 +3 2 3 3 1 2972.70489558 6.17010443 0.10711987 +3 2 3 3 2 -80912.37139962 -72074.20027078 72059.29989706 +3 2 3 3 3 329275.20685400 138.95589346 0.66414318 +3 2 3 3 4 -80911.60013657 -72073.28975189 -72058.33581825 +3 2 3 3 5 -11779.81126255 -10.71198685 -0.06427192 +3 2 3 3 6 -80800.24903323 72005.41860319 72001.30520024 +3 2 3 3 7 2957.23678656 -0.95336683 -0.65343120 +3 2 3 3 8 -80800.98816032 72008.40724753 -72002.08717528 +3 3 3 1 1 5.93444072 2971.92292054 0.04284795 +3 3 3 1 2 -72069.26204484 -80911.93220816 72059.47128885 +3 3 3 1 3 110.68696015 329276.19235679 0.68556716 +3 3 3 1 4 -72068.94068523 -80911.53586465 -72059.10708130 +3 3 3 1 5 -9.04091690 2954.38739806 -0.66414318 +3 3 3 1 6 72017.40531648 -80799.35993832 -72002.01219137 +3 3 3 1 7 -1.39255829 -11781.28951673 -0.06427192 +3 3 3 1 8 72014.50236805 -80798.67437116 72001.34804819 +3 3 3 2 1 2972.61919968 6.15939244 0.19281576 +3 3 3 2 2 -80912.32855167 -72074.10386290 72059.29989706 +3 3 3 2 3 329275.39966976 139.19155717 0.85695895 +3 3 3 2 4 -80911.87864823 -72073.58968753 -72058.67860183 +3 3 3 2 5 -11779.85411049 -10.71198685 -0.14996782 +3 3 3 2 6 -80800.23832124 72005.37575525 72001.34804819 +3 3 3 2 7 2957.27963451 -0.98550279 -0.67485517 +3 3 3 2 8 -80801.03100827 72008.36439958 -72002.09788727 +3 3 3 3 1 0.62129524 0.04284795 1.09262266 +3 3 3 3 2 67094.78674205 67096.50065995 -74104.17533937 +3 3 3 3 3 3.98485911 0.59987126 -4.52045845 +3 3 3 3 4 -67098.84658507 -67098.38596963 -74104.02537156 +3 3 3 3 5 3.72777142 0.23566371 6.62000788 +3 3 3 3 6 -67033.97479269 67032.44297857 74102.71850916 +3 3 3 3 7 -0.00000000 0.89980690 -0.86767094 +3 3 3 3 8 67029.82925377 -67032.30372274 74103.00773281 +3 1 4 1 1 0.94265484 539.35925004 1559.84738959 +3 1 4 1 2 -0.34278358 -538.98433050 -1559.19395839 +3 1 4 1 3 -74176.69549037 -72097.19890655 -72068.66217357 +3 1 4 1 4 74179.78054258 72098.95567239 72069.56198047 +3 1 4 1 5 -9477.41965629 -3068.34151420 -3066.54190041 +3 1 4 1 6 9473.03845367 3066.28481272 3063.75678383 +3 1 4 1 7 0.89980690 1560.53295675 540.29119290 +3 1 4 1 8 -0.08569589 -1560.72577251 -539.16643428 +3 1 4 2 1 0.57844729 -539.01646646 3074.45805869 +3 1 4 2 2 538.44873116 -0.42847947 -3074.42592273 +3 1 4 2 3 -67122.94855549 -72105.46856040 -80912.30712770 +3 1 4 2 4 72093.73893480 67137.39902575 80911.92149617 +3 1 4 2 5 1.99242955 1559.55816594 3080.27466756 +3 1 4 2 6 -3064.30309516 888.90209304 -92.48729449 +3 1 4 2 7 -889.26630060 3060.01830042 90.38774507 +3 1 4 2 8 -1558.16560765 -0.77126305 -3077.73592667 +3 1 4 3 1 -893.31543163 82.95362619 3055.88347349 +3 1 4 3 2 -1559.40819813 -3074.46877068 -0.42847947 +3 1 4 3 3 -67086.38854436 -80901.01669356 -72061.07808688 +3 1 4 3 4 72064.54877062 80910.14330636 67097.05768326 +3 1 4 3 5 2.20666929 3079.46055655 1557.26580076 +3 1 4 3 6 -3065.64209351 -94.80108365 888.60215741 +3 1 4 3 7 2.63514877 3077.89660647 -536.89549306 +3 1 4 3 8 535.36367894 -3080.22110762 -0.29993563 +3 2 4 1 1 -537.87028387 0.28922365 3074.45805869 +3 2 4 1 2 -1.02835074 537.81672393 -3073.52611584 +3 2 4 1 3 -72094.59589375 -67133.64983035 -80914.49237302 +3 2 4 1 4 67120.01347109 72106.98966253 80913.54971818 +3 2 4 1 5 3068.57717791 -888.49503754 94.60826789 +3 2 4 1 6 -0.65343120 -1558.29415149 -3077.53239892 +3 2 4 1 7 1556.83732128 -0.43919146 3075.20789777 +3 2 4 1 8 888.79497318 -3064.20668728 -92.27305475 +3 2 4 2 1 539.00575447 -0.58915928 1558.46554328 +3 2 4 2 2 -539.00575447 -0.33207159 -1559.20467038 +3 2 4 2 3 -72107.23603823 -74173.80325392 -72073.71823137 +3 2 4 2 4 72102.90839554 74174.06034160 72071.96146553 +3 2 4 2 5 1561.55059550 -1.69249392 537.63462016 +3 2 4 2 6 -1560.68292456 -0.12854384 -539.15572229 +3 2 4 2 7 -3062.74985706 -9470.44615285 -3059.72907677 +3 2 4 2 8 3066.30623670 9473.01702969 3063.77820780 +3 2 4 3 1 83.31783374 -893.60465527 3055.82991356 +3 2 4 3 2 -3074.46877068 -1559.37606217 -0.42847947 +3 2 4 3 3 -80902.91271523 -67090.58764320 -72062.83485273 +3 2 4 3 4 80912.40353558 72071.06165863 67095.81509279 +3 2 4 3 5 3080.87453882 0.08569589 -536.26348584 +3 2 4 3 6 -3080.22110762 535.29940702 -0.27851166 +3 2 4 3 7 3075.90417692 2.62443678 1559.81525363 +3 2 4 3 8 -94.82250762 -3065.60995755 888.58073344 +3 3 4 1 1 1558.67978302 3074.40449876 0.28922365 +3 3 4 1 2 893.42255150 -83.06074606 -3055.91560945 +3 3 4 1 3 -72063.40258803 -80910.85029749 -67097.10053121 +3 3 4 1 4 67082.62863697 80901.74510866 72062.02074173 +3 3 4 1 5 3067.73093095 95.27241107 -887.95943820 +3 3 4 1 6 -2.84938850 -3077.33958316 -1558.14418368 +3 3 4 1 7 -534.67811179 3079.11777297 0.28922365 +3 3 4 1 8 -1.41398226 -3079.41770861 536.58484545 +3 3 4 2 1 3074.55446658 1560.07234131 0.56773530 +3 3 4 2 2 -83.06074606 893.41183951 -3055.93703342 +3 3 4 2 3 -80911.84651227 -72070.09757981 -67095.21522152 +3 3 4 2 4 80901.59514085 67093.32991184 72061.46371841 +3 3 4 2 5 3081.32444227 -535.98497418 0.32135961 +3 3 4 2 6 -3079.41770861 -1.45683021 536.60626942 +3 3 4 2 7 94.24406033 3063.60681601 -889.22345265 +3 3 4 2 8 -3077.31815918 -2.86010049 -1558.18703163 +3 3 4 3 1 -3055.42285806 -3055.26217825 -9478.83363855 +3 3 4 3 2 3056.06557727 3056.03344131 9478.00881557 +3 3 4 3 3 -72067.38744714 -72067.22676734 -74112.38072130 +3 3 4 3 4 72067.00181561 72066.24126455 74113.70900767 +3 3 4 3 5 1555.31621915 538.87721063 -1.69249392 +3 3 4 3 6 -1555.43405100 -538.70581884 1.88530969 +3 3 4 3 7 538.68439487 1555.42333902 -2.52802890 +3 3 4 3 8 -538.68439487 -1555.43405100 1.92815763 +3 1 5 1 1 -0.02142397 0.01071199 -0.12854384 +3 1 5 1 2 9474.64525169 -0.81411100 0.92123087 +3 1 5 1 3 0.09640788 -0.10711987 -8.67670935 +3 1 5 1 4 -9474.69881163 0.89980690 0.89980690 +3 1 5 1 5 0.08569589 0.02142397 13.38998357 +3 1 5 1 6 -9456.28490623 -0.00000000 -3.08505221 +3 1 5 1 7 0.02142397 0.03213596 -0.16067980 +3 1 5 1 8 9456.17778636 0.07498391 -3.09576420 +3 1 5 2 1 0.12854384 0.07498391 -573.11272061 +3 1 5 2 2 3069.58410468 -1560.52224476 3080.36036345 +3 1 5 2 3 0.99621478 -0.64271921 2958.99355240 +3 1 5 2 4 -3069.50912077 1560.52224476 3080.42463537 +3 1 5 2 5 0.88909491 0.55702332 -11775.53717979 +3 1 5 2 6 3057.22247185 1553.23809370 3071.89789384 +3 1 5 2 7 0.23566371 -0.11783186 -2914.66735081 +3 1 5 2 8 -3059.40771717 -1553.18453376 3071.72650205 +3 1 5 3 1 1.99242955 -2913.89608775 -0.04284795 +3 1 5 3 2 -3068.74856970 3081.19589842 -1558.05848778 +3 1 5 3 3 14.17195861 2960.92171004 -0.04284795 +3 1 5 3 4 -3068.69500977 3081.19589842 1558.37984739 +3 1 5 3 5 16.69998750 -11774.25174137 0.02142397 +3 1 5 3 6 3053.10906890 3069.81976839 1560.43654886 +3 1 5 3 7 -1.54252611 -574.69809467 -0.03213596 +3 1 5 3 8 3052.95910108 3069.83048037 -1560.50082079 +3 2 5 1 1 -0.12854384 -0.13925583 -2915.42790187 +3 2 5 1 2 -3069.24132110 -1560.80075642 3081.41013816 +3 2 5 1 3 -0.89980690 0.57844729 -11785.62787141 +3 2 5 1 4 3069.29488103 1560.82218039 3081.23874637 +3 2 5 1 5 -0.93194286 -0.66414318 2965.42074452 +3 2 5 1 6 -3054.05172374 1558.07991176 3073.61181173 +3 2 5 1 7 -0.17139179 0.07498391 -574.35531109 +3 2 5 1 8 3056.21554508 -1558.02635182 3073.75106756 +3 2 5 2 1 0.23566371 0.17139179 0.81411100 +3 2 5 2 2 890.27322736 0.89980690 -0.25708768 +3 2 5 2 3 0.91051888 -0.77126305 -8.41962167 +3 2 5 2 4 -890.25180339 -0.89980690 -0.08569589 +3 2 5 2 5 0.92123087 0.66414318 12.61872051 +3 2 5 2 6 -889.45911636 -0.55702332 -2.31378916 +3 2 5 2 7 0.17139179 -0.08569589 0.37491954 +3 2 5 2 8 887.31671899 0.54631133 -2.52802890 +3 2 5 3 1 -3372.09061341 1.34971034 0.10711987 +3 2 5 3 2 94.02982060 538.23449142 536.43487763 +3 2 5 3 3 2959.25064009 -12.23308899 0.64271921 +3 2 5 3 4 93.96554868 538.25591539 -536.62769339 +3 2 5 3 5 2962.47494813 13.75419112 -0.59987126 +3 2 5 3 6 89.53078612 -539.51992984 536.19921392 +3 2 5 3 7 -2914.66735081 -0.28922365 -0.01071199 +3 2 5 3 8 87.36696477 -539.57348978 -536.02782213 +3 3 5 1 1 0.72841511 -573.03773671 0.17139179 +3 3 5 1 2 3069.26274507 3081.79576969 -1556.45168975 +3 3 5 1 3 -8.98735697 -11786.31343857 0.68556716 +3 3 5 1 4 3069.31630500 3081.62437790 1556.40884181 +3 3 5 1 5 -8.90166107 2963.10695536 -0.66414318 +3 3 5 1 6 -3059.15062948 3074.55446658 1557.39434460 +3 3 5 1 7 -0.94265484 -2915.98492519 -0.07498391 +3 3 5 1 8 -3061.35729877 3074.46877068 -1557.36220864 +3 3 5 2 1 -2915.22437412 -0.32135961 -0.02142397 +3 3 5 2 2 94.71538776 -536.22063789 -538.29876334 +3 3 5 2 3 2957.64384206 -11.84745746 -0.64271921 +3 3 5 2 4 96.90063307 -536.28490981 538.42730718 +3 3 5 2 5 2960.80387818 16.02513233 0.66414318 +3 3 5 2 6 89.70217791 534.78523165 -537.78458797 +3 3 5 2 7 -3374.31870667 -1.07119869 0.09640788 +3 3 5 2 8 89.61648201 534.69953576 537.81672393 +3 3 5 3 1 0.17139179 -0.10711987 2.88152446 +3 3 5 3 2 888.55930946 0.08569589 -2.03527750 +3 3 5 3 3 0.89980690 0.64271921 10.13353956 +3 3 5 3 4 -890.69099485 -0.08569589 -2.27094121 +3 3 5 3 5 0.83553497 -0.66414318 -12.12596912 +3 3 5 3 6 -891.21588220 0.08569589 2.91366042 +3 3 5 3 7 0.17139179 0.05355993 -2.45304499 +3 3 5 3 8 891.32300207 -0.09640788 2.88152446 +3 1 6 1 1 -1.54252611 -536.68125333 -1558.99043064 +3 1 6 1 2 -0.04284795 1558.21916759 536.16707796 +3 1 6 1 3 -74117.21182737 72014.13816049 72010.47466099 +3 1 6 1 4 9473.78829275 -3064.07814343 -3064.99937430 +3 1 6 1 5 -9460.46258110 3056.06557727 3053.38758055 +3 1 6 1 6 74104.98945037 -72006.46837791 -71995.75639105 +3 1 6 1 7 -0.64271921 -1556.90159320 -538.74866679 +3 1 6 1 8 0.98550279 535.57791868 1558.62622309 +3 1 6 2 1 -0.44990345 -537.24898863 3076.66472799 +3 1 6 2 2 1562.06477087 1.86388571 -3081.60295392 +3 1 6 2 3 67024.11976478 -72004.13316477 -80798.58867527 +3 1 6 2 4 3065.93131716 889.26630060 -94.95105147 +3 1 6 2 5 -0.58915928 1552.85246217 3069.32701699 +3 1 6 2 6 -72004.77588398 67036.04220615 80814.39956786 +3 1 6 2 7 889.69478007 3061.36801076 90.54842487 +3 1 6 2 8 -536.00639816 -0.05355993 -3076.03272076 +3 1 6 3 1 888.43076562 91.43751978 3061.92503408 +3 1 6 3 2 -539.92698534 -3079.48198053 0.92123087 +3 1 6 3 3 67030.68621272 -80802.29502272 -72004.69018809 +3 1 6 3 4 3064.37807907 -92.42302257 889.48054033 +3 1 6 3 5 -1.83174975 3072.69058086 1561.12211602 +3 1 6 3 6 -72000.35183341 80809.42920596 67027.49404064 +3 1 6 3 7 0.72841511 3077.75735064 -536.42416564 +3 1 6 3 8 1557.84424805 -3077.17890335 0.23566371 +3 2 6 1 1 537.87028387 0.08569589 3076.40764030 +3 2 6 1 2 -889.22345265 -3065.89918120 -94.94033948 +3 2 6 1 3 72016.49479760 -67015.92509484 -80800.02408151 +3 2 6 1 4 -1.84246174 -1562.02192292 -3081.58152995 +3 2 6 1 5 -3053.48398844 -891.62293770 85.99583046 +3 2 6 1 6 -67052.13161040 71998.99141108 80813.84254455 +3 2 6 1 7 -1557.71570420 0.36420755 3076.20411255 +3 2 6 1 8 0.02142397 536.01711014 -3076.08628070 +3 2 6 2 1 537.39895645 -0.02142397 -1560.56509271 +3 2 6 2 2 3064.72086264 -9472.85634989 -3065.58853358 +3 2 6 2 3 -72000.95170468 74114.99444610 72002.82630238 +3 2 6 2 4 -1558.27272752 0.23566371 535.98497418 +3 2 6 2 5 1557.82282407 -0.85695895 -540.14122508 +3 2 6 2 6 71996.82758974 -74107.02472788 -71992.24285936 +3 2 6 2 7 -3061.95717004 9466.34346188 3060.99309122 +3 2 6 2 8 -535.49222279 -0.82482299 1558.73334295 +3 2 6 3 1 91.03046428 888.21652588 -3061.74293030 +3 2 6 3 2 -92.85150204 3063.33901634 -888.75212523 +3 2 6 3 3 -80804.00894062 67030.08634146 72004.54022027 +3 2 6 3 4 -3078.46434178 -539.39138600 -0.17139179 +3 2 6 3 5 3073.79391551 -2.31378916 536.32775776 +3 2 6 3 6 80810.84318823 -71997.40603703 -67030.32200517 +3 2 6 3 7 3076.76113587 -0.42847947 -1559.37606217 +3 2 6 3 8 -3077.12534342 1557.79068811 -0.36420755 +3 3 6 1 1 -1559.85810157 3077.32887117 -0.18210378 +3 3 6 1 2 -1.37113432 -3078.00372634 538.37374725 +3 3 6 1 3 72014.83443964 -80797.34608479 -67034.79961567 +3 3 6 1 4 -2.93508440 -3080.29609153 -1556.92301718 +3 3 6 1 5 -3058.51862226 89.83072175 -892.22280897 +3 3 6 1 6 -67037.15625278 80804.56596393 72006.40410598 +3 3 6 1 7 536.04924610 3077.12534342 -0.65343120 +3 3 6 1 8 -890.85167465 -93.22642158 -3060.23254015 +3 3 6 2 1 3077.03964753 -1558.29415149 0.54631133 +3 3 6 2 2 -3080.44605934 -2.87081248 1556.85874526 +3 3 6 2 3 -80795.49291107 72009.21064654 67037.41334046 +3 3 6 2 4 -3078.90353324 -1.94958161 -538.98433050 +3 3 6 2 5 3073.93317134 534.22820834 -0.04284795 +3 3 6 2 6 80805.85140235 -67027.64400845 -72006.31841009 +3 3 6 2 7 91.37324786 -3061.65723440 890.20895544 +3 3 6 2 8 -93.40852536 -890.94808253 3060.32894803 +3 3 6 3 1 -3063.00694475 3064.00315953 9468.50728323 +3 3 6 3 2 -536.37060571 1559.31179024 2.42090903 +3 3 6 3 3 -71999.58057036 72000.59820911 74099.69772887 +3 3 6 3 4 -1559.31179024 536.32775776 2.39948506 +3 3 6 3 5 1559.54745396 -535.96355021 3.94201116 +3 3 6 3 6 71998.74503538 -72005.93277856 -74113.02344051 +3 3 6 3 7 538.57727500 -1556.96586512 1.48896617 +3 3 6 3 8 3061.33587480 -3061.36801076 -9465.39009505 +3 1 7 1 1 0.06427192 -0.04284795 0.64271921 +3 1 7 1 2 -0.57844729 889.00921291 2.39948506 +3 1 7 1 3 0.08569589 0.06427192 -2.20666929 +3 1 7 1 4 0.55702332 -889.05206086 2.14239737 +3 1 7 1 5 -0.06427192 0.10711987 -1.92815763 +3 1 7 1 6 -0.83553497 888.60215741 0.21423974 +3 1 7 1 7 0.02142397 -0.04284795 -1.92815763 +3 1 7 1 8 0.85695895 -888.62358139 0.24637570 +3 1 7 2 1 0.06427192 0.18210378 -2915.08511829 +3 1 7 2 2 -1561.33635576 -3058.27224656 3077.57524687 +3 1 7 2 3 -0.62129524 0.87838292 -11783.14269046 +3 1 7 2 4 1561.35777973 3058.22939861 3077.85375853 +3 1 7 2 5 -0.09640788 0.10711987 -574.86948646 +3 1 7 2 6 -1557.37292062 3060.80027546 3077.38243110 +3 1 7 2 7 0.66414318 0.92123087 2962.94627555 +3 1 7 2 8 1557.39434460 -3063.01765673 3077.44670303 +3 1 7 3 1 0.70699113 -3372.07990142 -0.01071199 +3 1 7 3 2 539.79844150 91.80172733 536.58484545 +3 1 7 3 3 -3.94201116 2960.30041480 0.04284795 +3 1 7 3 4 539.83057746 91.84457528 -536.71338929 +3 1 7 3 5 -0.16067980 -2914.49595902 -0.04284795 +3 1 7 3 6 -538.06309963 89.42366625 -536.02782213 +3 1 7 3 7 -0.25708768 2963.38546701 -0.07498391 +3 1 7 3 8 -537.93455579 89.63790599 536.14565398 +3 2 7 1 1 -0.08569589 -0.19281576 -573.42336823 +3 2 7 1 2 -1556.45168975 3063.52112012 3075.66851321 +3 2 7 1 3 0.68556716 -0.96407882 2957.90092975 +3 2 7 1 4 1556.47311373 -3063.56396806 3075.96844884 +3 2 7 1 5 0.07498391 -0.17139179 -2914.53880696 +3 2 7 1 6 -1557.33007268 -3061.10021109 3076.35408037 +3 2 7 1 7 -0.62129524 -0.88909491 -11774.32672528 +3 2 7 1 8 1557.15868089 3063.25332045 3076.33265639 +3 2 7 2 1 -0.02142397 -0.03213596 0.66414318 +3 2 7 2 2 -0.08569589 9468.73223495 2.97793235 +3 2 7 2 3 -0.03213596 -0.02142397 -3.83489129 +3 2 7 2 4 0.12854384 -9468.68938700 2.78511658 +3 2 7 2 5 0.04284795 0.12854384 -0.32135961 +3 2 7 2 6 0.66414318 9468.71081098 -0.94265484 +3 2 7 2 7 -0.02142397 0.02142397 -0.93194286 +3 2 7 2 8 -0.79268703 -9468.67867502 -0.98550279 +3 2 7 3 1 -2913.78896788 0.06427192 0.02142397 +3 2 7 3 2 3074.98294605 -3058.85069385 -1559.68670978 +3 2 7 3 3 2960.15044698 -1.92815763 0.64271921 +3 2 7 3 4 3075.04721797 -3058.87211782 1559.45104607 +3 2 7 3 5 -574.76236659 0.32135961 -0.06427192 +3 2 7 3 6 3076.13984063 3060.54318777 -1559.36535018 +3 2 7 3 7 -11773.78041395 -4.17767487 -0.74983908 +3 2 7 3 8 3076.07556871 3062.82484097 1559.31179024 +3 3 7 1 1 0.85695895 -2914.62450286 0.04284795 +3 3 7 1 2 -534.87092755 92.03739104 -538.27733937 +3 3 7 1 3 -1.67106995 2960.27899083 -0.04284795 +3 3 7 1 4 -534.94591146 91.97311912 538.34161129 +3 3 7 1 5 -1.04977471 -3373.78310733 0.02142397 +3 3 7 1 6 535.89927829 90.40916904 537.91313182 +3 3 7 1 7 -0.00000000 2963.53543483 -0.02142397 +3 3 7 1 8 535.89927829 90.32347315 -537.87028387 +3 3 7 2 1 -573.45550419 1.02835074 -0.13925583 +3 3 7 2 2 3079.56767642 3062.94267283 -1556.38741783 +3 3 7 2 3 -11783.83896960 -0.87838292 -0.70699113 +3 3 7 2 4 3079.59981238 3062.98552077 1556.15175412 +3 3 7 2 5 -2915.63142962 -0.53559934 -0.00000000 +3 3 7 2 6 3076.56832010 -3061.07878711 -1557.18010486 +3 3 7 2 7 2960.57892646 -0.73912709 0.62129524 +3 3 7 2 8 3076.58974408 -3063.37115230 1557.19081685 +3 3 7 3 1 -0.02142397 -0.03213596 2.19595730 +3 3 7 3 2 0.19281576 890.91594657 -2.84938850 +3 3 7 3 3 -0.05355993 -0.00000000 4.77754614 +3 3 7 3 4 -0.10711987 -890.74455478 -2.78511658 +3 3 7 3 5 0.02142397 0.02142397 -2.48518095 +3 3 7 3 6 -0.14996782 888.96636496 1.97100558 +3 3 7 3 7 0.04284795 -0.01071199 -2.77440459 +3 3 7 3 8 0.08569589 -888.95565298 2.00314154 +3 1 8 1 1 1.22116650 536.49914955 -1559.18324640 +3 1 8 1 2 -9472.84563790 3064.68872668 -3065.65280550 +3 1 8 1 3 74113.44120800 -72013.13123373 72009.44631025 +3 1 8 1 4 0.21423974 -1558.31557547 535.98497418 +3 1 8 1 5 9458.56655943 -3057.37243966 3054.60874706 +3 1 8 1 6 -0.85695895 -535.44937484 1558.82975084 +3 1 8 1 7 0.23566371 1557.07298499 -538.60941096 +3 1 8 1 8 -74099.91196861 72006.06132240 -71995.43503145 +3 1 8 2 1 0.23566371 537.18471671 3076.51476017 +3 1 8 2 2 -3065.85633325 -889.27701258 -94.91891551 +3 1 8 2 3 -67025.19096347 72004.77588398 -80799.06000269 +3 1 8 2 4 -1562.04334689 -1.84246174 -3081.53868200 +3 1 8 2 5 -0.31064762 -1553.47375741 3069.92688826 +3 1 8 2 6 536.00639816 0.06427192 -3076.07556871 +3 1 8 2 7 -889.84474789 -3061.26089089 90.63412076 +3 1 8 2 8 72006.98255327 -67036.17074999 80814.66736753 +3 1 8 3 1 888.38791767 91.38395984 -3061.93574606 +3 1 8 3 2 3063.32830435 -92.83007807 -888.75212523 +3 1 8 3 3 67032.96786592 -80804.43742009 72004.60449219 +3 1 8 3 4 -539.45565792 -3078.47505376 -0.21423974 +3 1 8 3 5 -1.83174975 3072.75485278 -1561.20781192 +3 1 8 3 6 1557.79068811 -3077.12534342 -0.47132742 +3 1 8 3 7 0.74983908 3077.77877462 536.42416564 +3 1 8 3 8 -72001.94791945 80810.93959611 -67028.77947906 +3 2 8 1 1 -537.89170784 -0.11783186 3076.42906427 +3 2 8 1 2 1.79961379 1562.04334689 -3081.61366591 +3 2 8 1 3 -72016.45194965 67015.98936676 -80800.19547330 +3 2 8 1 4 889.26630060 3065.87775722 -94.95105147 +3 2 8 1 5 3053.47327645 891.66578565 85.93155854 +3 2 8 1 6 -0.04284795 -536.00639816 -3076.05414473 +3 2 8 1 7 1557.71570420 -0.34278358 3076.19340056 +3 2 8 1 8 67052.13161040 -71999.02354704 80814.09963223 +3 2 8 2 1 -537.46322837 -0.18210378 -1560.51153277 +3 2 8 2 2 1558.16560765 -0.06427192 536.11351802 +3 2 8 2 3 72001.62655985 -74118.18661818 72003.29762980 +3 2 8 2 4 -3064.07814343 9473.76686877 -3064.91367841 +3 2 8 2 5 -1557.73712818 0.66414318 -540.16264905 +3 2 8 2 6 535.57791868 0.96407882 1558.59408713 +3 2 8 2 7 3061.29302685 -9467.27540474 3060.36108400 +3 2 8 2 8 -71997.44888498 74110.18476400 -71992.83201864 +3 2 8 3 1 91.15900812 888.32364575 3061.85005017 +3 2 8 3 2 -3079.48198053 -539.83057746 0.89980690 +3 2 8 3 3 -80800.89175244 67027.19410501 -72003.70468530 +3 2 8 3 4 -92.35875065 3064.35665509 889.48054033 +3 2 8 3 5 3074.72585837 -1.64964598 -536.92762902 +3 2 8 3 6 -3077.16819137 1557.82282407 0.27851166 +3 2 8 3 7 3076.97537560 -0.46061543 1559.29036627 +3 2 8 3 8 80807.07256886 -71995.79923900 67028.83303900 +3 3 8 1 1 -1559.83667760 3077.32887117 0.14996782 +3 3 8 1 2 -2.84938850 -3080.47819531 1556.83732128 +3 3 8 1 3 72014.72731977 -80795.37507921 67034.92815952 +3 3 8 1 4 -1.97100558 -3078.90353324 -539.02717845 +3 3 8 1 5 -3058.50791027 89.78787380 892.22280897 +3 3 8 1 6 -890.95879452 -93.45137331 3060.37179598 +3 3 8 1 7 536.02782213 3077.09320746 0.65343120 +3 3 8 1 8 -67036.74919728 80803.78398889 -72005.93277856 +3 3 8 2 1 3077.21103932 -1558.18703163 -0.43919146 +3 3 8 2 2 -3077.98230237 -1.36042233 538.37374725 +3 3 8 2 3 -80796.64980565 72008.82501501 -67036.85631715 +3 3 8 2 4 -3080.28537954 -2.93508440 -1556.92301718 +3 3 8 2 5 3074.86511419 534.95662344 -0.62129524 +3 3 8 2 6 -93.24784556 -890.87309862 -3060.30752406 +3 3 8 2 7 91.48036773 -3061.79649023 -890.29465133 +3 3 8 2 8 80804.67308380 -67028.64022323 72007.03611321 +3 3 8 3 1 3063.17833654 -3063.88532767 9468.58226714 +3 3 8 3 2 1559.32250223 -536.33846975 2.41019704 +3 3 8 3 3 72000.45895328 -72001.15523243 74100.55468782 +3 3 8 3 4 536.33846975 -1559.30107826 2.39948506 +3 3 8 3 5 -1558.66907103 536.62769339 3.29929195 +3 3 8 3 6 -3061.37872275 3061.33587480 -9465.34724711 +3 3 8 3 7 -538.36303526 1556.91230519 1.42469425 +3 3 8 3 8 -72000.83387282 72005.80423472 -74113.00201654 +4 1 1 1 1 74175.26008413 72107.09678240 -72075.07865370 +4 1 1 1 2 0.32135961 539.16643428 -1559.26894230 +4 1 1 1 3 0.42847947 -538.62012295 1558.20845560 +4 1 1 1 4 -74173.53545425 -72106.60403101 72071.34017029 +4 1 1 1 5 0.37491954 -1559.70813376 538.92005858 +4 1 1 1 6 -9472.92062181 -3066.09199696 3063.86390370 +4 1 1 1 7 9470.53184874 3063.13548859 -3059.60053293 +4 1 1 1 8 -0.53559934 1561.58273146 -538.52371507 +4 1 1 2 1 72106.62545498 67123.79480245 -80913.06767877 +4 1 1 2 2 0.42847947 -538.47015513 -3074.44734671 +4 1 1 2 3 539.15572229 -0.66414318 3074.42592273 +4 1 1 2 4 -67139.60569504 -72093.92103857 80911.96434412 +4 1 1 2 5 -1559.39748614 -1.84246174 3080.44605934 +4 1 1 2 6 0.73912709 1558.20845560 -3077.74663866 +4 1 1 2 7 -3059.08635756 888.61286940 90.98761633 +4 1 1 2 8 -888.92351702 3064.33523112 -92.48729449 +4 1 1 3 1 -72073.35402382 -80911.05382524 67094.51894238 +4 1 1 3 2 893.78675905 -83.22142586 3055.75492965 +4 1 1 3 3 1560.28658105 3074.42592273 -0.59987126 +4 1 1 3 4 67092.82644846 80902.68776351 -72062.34210133 +4 1 1 3 5 -535.78144643 3081.38871419 -0.23566371 +4 1 1 3 6 -1.06048670 -3078.64644555 1559.47247005 +4 1 1 3 7 3064.50662291 93.62276510 889.83403590 +4 1 1 3 8 -1.09262266 -3079.24631682 -536.45630160 +4 2 1 1 1 67134.29254956 72094.91725335 -80912.69275923 +4 2 1 1 2 -538.47015513 0.42847947 -3074.43663472 +4 2 1 1 3 -0.10711987 537.82743592 3074.38307479 +4 2 1 1 4 -72108.24296500 -67119.16722413 80912.73560717 +4 2 1 1 5 888.66642933 -3068.42721010 94.71538776 +4 2 1 1 6 3064.30309516 -888.88066907 -92.46587052 +4 2 1 1 7 1.39255829 -1557.45861652 3075.88275295 +4 2 1 1 8 1558.18703163 0.74983908 -3077.70379071 +4 2 1 2 1 72092.97838373 74174.46739710 -72066.57333614 +4 2 1 2 2 539.17714626 0.26779967 -1559.32250223 +4 2 1 2 3 -539.41280997 -1.19974253 1560.13661323 +4 2 1 2 4 -72096.06343594 -74174.89587658 72068.94068523 +4 2 1 2 5 3069.44484885 9475.43793872 -3067.95588267 +4 2 1 2 6 1561.55059550 -0.47132742 -538.57727500 +4 2 1 2 7 -1561.63629139 -0.63200722 539.44494594 +4 2 1 2 8 -3066.07057299 -9472.96346976 3063.83176774 +4 2 1 3 1 -80907.35818977 -72066.79828786 67095.99719656 +4 2 1 3 2 -83.44637759 893.85103097 3055.82991356 +4 2 1 3 3 3074.57589055 1558.59408713 -0.38563153 +4 2 1 3 4 80899.66698321 67083.49630791 -72062.04216570 +4 2 1 3 5 95.48665081 3067.78449088 888.02371012 +4 2 1 3 6 -3080.15683570 -0.42847947 -537.14186876 +4 2 1 3 7 3080.03900384 -535.31011901 0.35349557 +4 2 1 3 8 -3078.79641337 -1.14618259 1559.37606217 +4 3 1 1 1 -67090.78045897 -80901.40232508 72062.95268458 +4 3 1 1 2 -1559.30107826 -3074.61873850 0.52488736 +4 3 1 1 3 -893.34756759 83.01789811 -3055.87276150 +4 3 1 1 4 72068.69430953 80914.12816547 -67095.10810166 +4 3 1 1 5 0.92123087 3079.99615590 535.68503855 +4 3 1 1 6 -3065.71707742 -94.95105147 -888.64500536 +4 3 1 1 7 3.44925977 3075.04721797 -1559.22609435 +4 3 1 1 8 536.00639816 -3081.11020253 -0.34278358 +4 3 1 2 1 -80900.84530177 -67087.74896669 72062.40637325 +4 3 1 2 2 -3074.61873850 -1559.29036627 0.52488736 +4 3 1 2 3 82.62155460 -893.18688778 -3055.78706561 +4 3 1 2 4 80913.74253394 72064.01317128 -67096.69347571 +4 3 1 2 5 3079.08563701 2.01385353 -1557.41576857 +4 3 1 2 6 -3081.14233849 536.00639816 -0.32135961 +4 3 1 2 7 3076.09699268 3.89916321 535.63147862 +4 3 1 2 8 -94.95105147 -3065.72778941 -888.64500536 +4 3 1 3 1 72061.67795815 72062.13857358 -74113.49476794 +4 3 1 3 2 -3055.20861832 -3055.20861832 9478.51227895 +4 3 1 3 3 3055.10149845 3055.57282587 -9478.69438273 +4 3 1 3 4 -72061.52799033 -72064.27025896 74111.50233838 +4 3 1 3 5 -539.02717845 -1555.40191504 -1.75676584 +4 3 1 3 6 1557.40505658 537.82743592 3.59922758 +4 3 1 3 7 -1556.30172194 -538.08452360 -3.13861215 +4 3 1 3 8 537.82743592 1557.40505658 3.58851560 +4 1 2 1 1 -0.02142397 -0.00000000 897.49310650 +4 1 2 1 2 -0.81411100 0.51417537 -5.49524926 +4 1 2 1 3 -0.02142397 -0.00000000 897.62165034 +4 1 2 1 4 0.84624696 -0.47132742 -5.44168932 +4 1 2 1 5 0.04284795 -0.04284795 -895.17931734 +4 1 2 1 6 0.01071199 -0.29993563 -1.32828637 +4 1 2 1 7 -0.04284795 -0.08569589 -886.63115183 +4 1 2 1 8 0.04284795 0.32135961 -1.24259047 +4 1 2 2 1 538.64154692 -538.57727500 -82.99647414 +4 1 2 2 2 1.47825419 -5.47382528 -2969.45916356 +4 1 2 2 3 -538.74866679 538.72724282 -83.03932209 +4 1 2 2 4 -5.47382528 1.56395008 -2969.46987555 +4 1 2 2 5 540.20549700 540.18407303 -80.89692471 +4 1 2 2 6 -0.73912709 -0.81411100 2913.96035967 +4 1 2 2 7 -535.70646252 -535.55649471 -99.87856542 +4 1 2 2 8 0.17139179 0.17139179 3371.86566168 +4 1 2 3 1 -1559.79382965 -3074.91867413 3058.48648630 +4 1 2 3 2 -5.03463382 -2969.84479509 -1.70320591 +4 1 2 3 3 -1559.77240568 -3074.89725015 -3056.17269714 +4 1 2 3 4 8.11968603 11785.02800014 -7.17703119 +4 1 2 3 5 1560.88645231 -3075.17576181 -3060.02901240 +4 1 2 3 6 -0.04284795 573.30553638 1.07119869 +4 1 2 3 7 1556.49453770 -3078.68929350 3064.50662291 +4 1 2 3 8 -0.77126305 2915.25651008 0.87838292 +4 2 2 1 1 -538.59869897 538.62012295 -83.01789811 +4 2 2 1 2 5.50596124 -1.55323809 -2969.43773959 +4 2 2 1 3 538.70581884 -538.64154692 -83.08217003 +4 2 2 1 4 -1.58537405 5.39884137 -2969.44845157 +4 2 2 1 5 -540.24834495 -540.22692098 -80.89692471 +4 2 2 1 6 -0.09640788 -0.06427192 3371.94064559 +4 2 2 1 7 535.51364676 535.59934265 -99.79286952 +4 2 2 1 8 0.74983908 0.83553497 2914.00320762 +4 2 2 2 1 -0.02142397 -0.06427192 897.40741060 +4 2 2 2 2 -0.49275140 0.79268703 -5.40955336 +4 2 2 2 3 0.06427192 0.04284795 897.57880239 +4 2 2 2 4 0.54631133 -0.83553497 -5.44168932 +4 2 2 2 5 0.04284795 0.02142397 -895.00792555 +4 2 2 2 6 -0.27851166 0.02142397 -1.17831855 +4 2 2 2 7 0.06427192 -0.04284795 -886.60972786 +4 2 2 2 8 0.27851166 -0.03213596 -1.14618259 +4 2 2 3 1 -3074.89725015 -1559.75098171 3058.22939861 +4 2 2 3 2 -2969.74838720 -5.06676978 -0.14996782 +4 2 2 3 3 -3075.02579400 -1559.75098171 -3056.17269714 +4 2 2 3 4 11784.94230425 8.09826206 5.29172151 +4 2 2 3 5 -3075.17576181 1560.86502834 3060.02901240 +4 2 2 3 6 2915.24579810 -0.68556716 -1.32828637 +4 2 2 3 7 -3078.66786953 1556.58023360 -3064.39950304 +4 2 2 3 8 573.24126446 -0.14996782 -1.51039015 +4 3 2 1 1 -1559.79382965 -3074.85440221 -3058.35794245 +4 3 2 1 2 8.76240525 11785.57431147 6.13796847 +4 3 2 1 3 -1559.77240568 -3074.85440221 3058.35794245 +4 3 2 1 4 -5.72020098 -2970.47680231 0.81411100 +4 3 2 1 5 1560.84360436 -3075.11148989 3059.85762061 +4 3 2 1 6 -0.85695895 2915.35291796 -0.98550279 +4 3 2 1 7 1556.58023360 -3078.71071747 -3064.50662291 +4 3 2 1 8 0.02142397 573.13414459 -1.26401445 +4 3 2 2 1 -3074.89725015 -1559.81525363 -3058.33651848 +4 3 2 2 2 11785.67071936 8.88023710 -6.14868045 +4 3 2 2 3 -3074.96152208 -1559.77240568 3058.35794245 +4 3 2 2 4 -2970.55178622 -5.72020098 -0.79268703 +4 3 2 2 5 -3075.17576181 1560.77933244 -3059.85762061 +4 3 2 2 6 573.15556856 -0.00000000 1.26401445 +4 3 2 2 7 -3078.62502158 1556.55880962 3064.46377496 +4 3 2 2 8 2915.31007002 -0.82482299 1.09262266 +4 3 2 3 1 0.02142397 0.04284795 9477.92311967 +4 3 2 3 2 10.06926764 -8.89094909 -7.55195073 +4 3 2 3 3 0.02142397 0.06427192 9480.19406088 +4 3 2 3 4 -10.10140360 8.80525319 -7.64835861 +4 3 2 3 5 -0.02142397 -0.00000000 -9481.99367468 +4 3 2 3 6 -1.34971034 -1.15689458 -2.89223645 +4 3 2 3 7 0.02142397 -0.02142397 -9454.99946781 +4 3 2 3 8 1.37113432 1.27472644 -2.92437241 +4 1 3 1 1 1.11404663 539.33782607 1559.91166151 +4 1 3 1 2 -0.98550279 -539.63776170 -1558.30486348 +4 1 3 1 3 -74175.68856360 -72096.66330721 -72070.11900379 +4 1 3 1 4 74178.28086442 72099.64123955 72070.54748326 +4 1 3 1 5 -9476.48771343 -3068.94138546 -3067.31316346 +4 1 3 1 6 9473.11343757 3066.24196478 3063.99244754 +4 1 3 1 7 1.11404663 1560.60794065 540.18407303 +4 1 3 1 8 -0.23566371 -1560.57580469 -539.02717845 +4 1 3 2 1 -537.97740374 0.28922365 3074.46877068 +4 1 3 2 2 -1.09262266 537.79529996 -3073.51540385 +4 1 3 2 3 -72094.52090984 -67133.64983035 -80914.36382918 +4 1 3 2 4 67120.10987897 72106.92539061 80913.67826202 +4 1 3 2 5 3068.55575394 -888.51646152 94.58684391 +4 1 3 2 6 -0.68556716 -1558.31557547 -3077.59667084 +4 1 3 2 7 1556.83732128 -0.44990345 3075.21860976 +4 1 3 2 8 888.79497318 -3064.20668728 -92.28376674 +4 1 3 3 1 1558.65835905 3074.39378677 0.33207159 +4 1 3 3 2 893.40112752 -83.06074606 -3055.92632144 +4 1 3 3 3 -72063.34902810 -80910.63605775 -67096.92913942 +4 1 3 3 4 67082.62863697 80901.68083674 72061.67795815 +4 1 3 3 5 3067.69879499 95.29383505 -887.95943820 +4 1 3 3 6 -2.87081248 -3077.38243110 -1558.18703163 +4 1 3 3 7 -534.67811179 3079.12848496 0.28922365 +4 1 3 3 8 -1.41398226 -3079.39628463 536.61698141 +4 2 3 1 1 0.44990345 -538.82365070 3074.52233062 +4 2 3 1 2 537.61319618 -0.99621478 -3073.61181173 +4 2 3 1 3 -67120.24913480 -72104.89011311 -80914.06389354 +4 2 3 1 4 72093.68537486 67135.27805235 80912.26427975 +4 2 3 1 5 2.02456552 1559.72955773 3080.16754769 +4 2 3 1 6 -3065.11720616 889.43769239 -91.65175952 +4 2 3 1 7 -889.90901981 3060.92881930 89.74502586 +4 2 3 1 8 -1558.44411931 -0.73912709 -3077.48955097 +4 2 3 2 1 538.83436268 -0.52488736 1558.35842341 +4 2 3 2 2 -539.51992984 -1.10333465 -1558.17631964 +4 2 3 2 3 -72110.97452164 -74174.93872452 -72077.06037127 +4 2 3 2 4 72107.21461426 74175.66713963 72073.84677521 +4 2 3 2 5 1560.61865264 -1.07119869 538.29876334 +4 2 3 2 6 -1559.64386184 -0.85695895 -539.69132163 +4 2 3 2 7 -3062.98552077 -9470.47828881 -3059.66480485 +4 2 3 2 8 3066.37050862 9473.19913347 3063.87461568 +4 2 3 3 1 3074.61873850 1560.09376528 0.57844729 +4 2 3 3 2 -83.10359401 893.41183951 -3055.90489746 +4 2 3 3 3 -80911.79295233 -72070.01188392 -67095.21522152 +4 2 3 3 4 80901.47730899 67093.20136800 72061.07808688 +4 2 3 3 5 3081.31373028 -535.96355021 0.29993563 +4 2 3 3 6 -3079.41770861 -1.41398226 536.58484545 +4 2 3 3 7 94.20121239 3063.58539204 -889.24487662 +4 2 3 3 8 -3077.36100713 -2.88152446 -1558.19774361 +4 3 3 1 1 -893.35827957 82.96433818 3055.88347349 +4 3 3 1 2 -1559.57958992 -3074.39378677 -0.48203941 +4 3 3 1 3 -67084.21401103 -80901.08096548 -72060.94954304 +4 3 3 1 4 72063.67038770 80909.58628304 67096.45781200 +4 3 3 1 5 2.21738128 3079.48198053 1557.20152883 +4 3 3 1 6 -3066.55261240 -94.17978841 889.22345265 +4 3 3 1 7 2.67799671 3077.90731846 -536.87406909 +4 3 3 1 8 535.10659126 -3080.32822749 -0.23566371 +4 3 3 2 1 83.51064951 -893.69035117 3055.93703342 +4 3 3 2 2 -3074.40449876 -1559.57958992 -0.48203941 +4 3 3 2 3 -80901.88436449 -67087.65255881 -72061.63511020 +4 3 3 2 4 80909.41489125 72070.16185173 67094.65819821 +4 3 3 2 5 3081.80648168 -0.59987126 -536.92762902 +4 3 3 2 6 -3080.32822749 535.17086318 -0.27851166 +4 3 3 2 7 3076.03272076 2.72084466 1559.70813376 +4 3 3 2 8 -94.15836444 -3066.55261240 889.20202868 +4 3 3 3 1 -3055.52997792 -3055.10149845 -9478.78007862 +4 3 3 3 2 3055.93703342 3055.92632144 9477.76243987 +4 3 3 3 3 -72064.25954698 -72063.75608360 -74111.05243493 +4 3 3 3 4 72065.14864189 72062.25640544 74111.86654593 +4 3 3 3 5 1555.38049107 539.07002640 -1.69249392 +4 3 3 3 6 -1556.44097777 -538.29876334 2.63514877 +4 3 3 3 7 538.12737155 1556.36599386 -3.14932413 +4 3 3 3 8 -538.29876334 -1556.44097777 2.61372479 +4 1 4 1 1 -74167.86881320 -67132.10730425 67088.54165371 +4 1 4 1 2 2.12097340 -5.62379310 7.29486305 +4 1 4 1 3 74174.06034160 67119.38146386 67080.43267967 +4 1 4 1 4 -115.00389085 213.51132196 -123.83056802 +4 1 4 1 5 74170.60036985 -67112.39724844 -67088.53094173 +4 1 4 1 6 -1.14618259 3.74919540 -8.50531756 +4 1 4 1 7 -74062.48428654 66921.46679477 -66963.46849522 +4 1 4 1 8 -0.36420755 -7.75547848 8.25894186 +4 1 4 2 1 -72109.04636401 -72098.14156139 80899.57057533 +4 1 4 2 2 -1.04977471 2.06741346 11786.03492691 +4 1 4 2 3 72098.14156139 72106.94681459 80899.83837500 +4 1 4 2 4 224.35185265 -222.12375939 -329275.61390950 +4 1 4 2 5 -72115.45213215 72109.00351606 80901.80938058 +4 1 4 2 6 1.77818982 2.80654056 -2957.25821053 +4 1 4 2 7 71902.15504993 -71902.15504993 80705.06231805 +4 1 4 2 8 -0.74983908 1.71391790 -2959.42203188 +4 1 4 3 1 72071.85434566 80911.31091292 -72063.58469181 +4 1 4 3 2 -5.01320985 -2970.33754648 -6.90923152 +4 1 4 3 3 72067.01252760 80914.34240520 72060.00688820 +4 1 4 3 4 -122.05237820 -329280.77708716 -108.19106722 +4 1 4 3 5 -72081.31303005 80900.65248600 72062.59918902 +4 1 4 3 6 6.70570377 -2956.65833927 -0.27851166 +4 1 4 3 7 -71944.31743018 80700.02768423 -71944.98157337 +4 1 4 3 8 7.02706338 11781.39663660 1.52110213 +4 2 4 1 1 -72109.41057156 -72098.72000868 80899.81695103 +4 2 4 1 2 -0.42847947 1.36042233 11785.11369604 +4 2 4 1 3 72098.07728947 72106.58260703 80899.66698321 +4 2 4 1 4 223.35563787 -219.03870717 -329277.49921918 +4 2 4 1 5 -72115.58067599 72108.76785235 80901.98077237 +4 2 4 1 6 1.69249392 2.72084466 -2957.42960232 +4 2 4 1 7 71903.05485683 -71903.27980855 80708.00811444 +4 2 4 1 8 -0.79268703 1.81032578 -2959.59342367 +4 2 4 2 1 -67118.22456928 -74175.37791599 67079.97206423 +4 2 4 2 2 5.48453727 -1.55323809 7.11275927 +4 2 4 2 3 67135.19235646 74168.57580433 67091.05897063 +4 2 4 2 4 -220.20631374 114.48971549 -124.04480776 +4 2 4 2 5 67118.71732068 -74169.04713176 -67089.64498836 +4 2 4 2 6 6.95207947 0.57844729 6.55573595 +4 2 4 2 7 -66924.08051956 74057.52463663 -66964.67894973 +4 2 4 2 8 -3.83489129 4.91680197 -6.14868045 +4 2 4 3 1 80912.67133525 72070.05473187 -72065.10579394 +4 2 4 3 2 -2970.15544271 -4.95964991 10.48703513 +4 2 4 3 3 80912.01790406 72068.21227013 72057.73594698 +4 2 4 3 4 -329277.20999554 -122.99503305 112.11165440 +4 2 4 3 5 80896.86044266 -72079.95260772 -72061.65653417 +4 2 4 3 6 11782.30715548 7.66978259 1.11404663 +4 2 4 3 7 80700.12409211 -71944.87445350 71945.33506893 +4 2 4 3 8 -2956.48694748 6.60929589 -0.02142397 +4 3 4 1 1 72071.68295387 80911.37518484 -72063.56326783 +4 3 4 1 2 -4.97036190 -2970.33754648 -6.88780755 +4 3 4 1 3 72066.86255978 80914.12816547 72059.62125667 +4 3 4 1 4 -122.02024224 -329280.15579192 -108.46957887 +4 3 4 1 5 -72081.28089409 80900.58821408 72062.81342875 +4 3 4 1 6 6.69499178 -2956.65833927 -0.21423974 +4 3 4 1 7 -71943.97464660 80699.85629244 -71944.61736582 +4 3 4 1 8 7.09133530 11781.30022872 1.48896617 +4 3 4 2 1 80912.49994346 72069.87262809 -72065.06294599 +4 3 4 2 2 -2970.11259476 -4.95964991 10.51917109 +4 3 4 2 3 80912.02861604 72068.21227013 72057.77879493 +4 3 4 2 4 -329277.27426746 -122.84506523 111.29754340 +4 3 4 2 5 80896.81759471 -72079.84548785 -72061.42087046 +4 3 4 2 6 11782.24288356 7.77690246 0.96407882 +4 3 4 2 7 80700.35975583 -71944.96014939 71945.57073265 +4 3 4 2 8 -2956.50837145 6.59858390 -0.09640788 +4 3 4 3 1 -67096.30784418 -67097.92535420 74105.35365793 +4 3 4 3 2 4.34906666 -1.46754220 -7.12347126 +4 3 4 3 3 67094.73318212 67093.13709607 74109.12427730 +4 3 4 3 4 -107.88041960 110.91191188 4.58473037 +4 3 4 3 5 67086.95627966 -67087.33119920 -74078.23090722 +4 3 4 3 6 -0.88909491 -1.11404663 -5.99871264 +4 3 4 3 7 -66981.47534512 66981.07900160 -74121.55018205 +4 3 4 3 8 0.64271921 2.61372479 -5.98800065 +4 1 5 1 1 1.30686240 -1559.55816594 -536.92762902 +4 1 5 1 2 -0.21423974 540.80536827 1560.30800502 +4 1 5 1 3 -9477.32324841 3068.19154638 3067.05607578 +4 1 5 1 4 74173.47118233 -72113.84533412 -72079.65267209 +4 1 5 1 5 -74162.65207560 72101.22661361 72062.02074173 +4 1 5 1 6 9463.84756895 -3060.07186035 -3055.14434640 +4 1 5 1 7 0.55702332 -537.76316400 -1559.04399057 +4 1 5 1 8 1.04977471 1561.01499615 541.65161523 +4 1 5 2 1 -1560.00806939 0.37491954 3080.60673915 +4 1 5 2 2 0.23566371 539.92698534 -3074.61873850 +4 1 5 2 3 -3068.90924950 -888.08798204 94.95105147 +4 1 5 2 4 -67118.25670525 72109.47484348 80903.18051490 +4 1 5 2 5 72102.62988389 -67157.19477746 -80923.70468171 +4 1 5 2 6 0.73912709 -1552.98100601 -3070.56960747 +4 1 5 2 7 533.88542476 3.67421149 3077.27531124 +4 1 5 2 8 -890.38034723 -3055.08007448 -86.33861404 +4 1 5 3 1 537.95597976 3080.69243504 0.36420755 +4 1 5 3 2 -890.89452260 -81.12187644 -3057.53311947 +4 1 5 3 3 -3066.99180386 94.69396378 -888.06655807 +4 1 5 3 4 -67091.70168984 80902.47352377 72061.63511020 +4 1 5 3 5 72057.84306685 -80921.94791587 -67086.28142449 +4 1 5 3 6 7.01635139 -3071.96216576 -1561.50774755 +4 1 5 3 7 -1556.53738565 3074.92938612 -3.53495566 +4 1 5 3 8 3.23502003 -3077.67165475 534.88163954 +4 2 5 1 1 888.06655807 3068.93067348 94.88677954 +4 2 5 1 2 -540.16264905 -0.47132742 -3074.66158644 +4 2 5 1 3 -0.39634351 1559.98664542 3080.46748332 +4 2 5 1 4 -72109.92474693 67118.39596107 80902.75203543 +4 2 5 1 5 67159.65853443 -72100.92667798 -80924.24028106 +4 2 5 1 6 3054.27667546 889.54481225 -86.89563735 +4 2 5 1 7 -3.66349950 -533.89613675 3077.30744720 +4 2 5 1 8 1552.14547104 -1.60679803 -3069.96973620 +4 2 5 2 1 -3069.32701699 9475.36295481 3068.47005804 +4 2 5 2 2 -540.71967237 0.14996782 1560.14732522 +4 2 5 2 3 1560.64007661 -1.00692676 -536.15636597 +4 2 5 2 4 72113.71679028 -74171.01813734 -72081.98788522 +4 2 5 2 5 -72101.65509308 74162.74848349 72060.64960741 +4 2 5 2 6 -1560.04020535 -0.57844729 542.36931835 +4 2 5 2 7 537.74174003 -0.78197504 -1559.24751832 +4 2 5 2 8 3059.64338088 -9464.82235975 -3054.46949123 +4 2 5 3 1 94.67253981 -3066.99180386 888.12011800 +4 2 5 3 2 -81.13258843 -891.18374624 3057.27603178 +4 2 5 3 3 3080.62816312 537.97740374 -0.47132742 +4 2 5 3 4 80904.42310538 -67093.73696734 -72063.28475617 +4 2 5 3 5 -80923.98319337 72062.10643762 67085.91721694 +4 2 5 3 6 -3076.60045606 3.51353169 -534.09966450 +4 2 5 3 7 3074.96152208 -1556.52667366 3.55637964 +4 2 5 3 8 -3072.99051650 5.07748177 1562.87888187 +4 3 5 1 1 -1.58537405 3078.94638119 -537.81672393 +4 3 5 1 2 1560.58651668 -3074.75799433 -0.68556716 +4 3 5 1 3 -0.21423974 3080.31751550 1555.20909928 +4 3 5 1 4 -72075.29289344 80900.22400653 67090.52337128 +4 3 5 1 5 67095.81509279 -80906.99398222 -72056.42908459 +4 3 5 1 6 3062.98552077 -92.48729449 891.40869797 +4 3 5 1 7 889.60908418 93.36567741 3056.70829648 +4 3 5 1 8 -531.95726712 -3078.65715754 0.74983908 +4 3 5 2 1 3080.63887511 -0.43919146 -1554.99485954 +4 3 5 2 2 -3074.68301042 1560.53295675 0.50346338 +4 3 5 2 3 3080.78884292 -0.27851166 539.11287434 +4 3 5 2 4 80897.57814578 -72076.97467537 -67092.08732136 +4 3 5 2 5 -80907.37961375 67096.80059558 72055.31503796 +4 3 5 2 6 -3077.67165475 -531.48593970 -0.04284795 +4 3 5 2 7 93.68703702 889.83403590 -3056.89040025 +4 3 5 2 8 -92.91577396 3062.02144196 -890.78740273 +4 3 5 3 1 536.94905300 -1557.46932851 -2.79582857 +4 3 5 3 2 3057.07250403 -3056.72972045 -9482.87205760 +4 3 5 3 3 1557.45861652 -536.92762902 -2.78511658 +4 3 5 3 4 72065.11650593 -72064.76301036 -74082.62282182 +4 3 5 3 5 -72059.20348918 72057.02895585 74119.92196005 +4 3 5 3 6 -1553.81654099 540.29119290 -7.06991132 +4 3 5 3 7 -3064.09956741 3064.05671946 9465.71145466 +4 3 5 3 8 -539.43423395 1554.64136398 -7.60551067 +4 1 6 1 1 -9471.68874332 0.42847947 -1.88530969 +4 1 6 1 2 0.53559934 -0.61058325 -0.10711987 +4 1 6 1 3 9471.73159127 -0.44990345 -2.05670148 +4 1 6 1 4 -1.21045451 -1.39255829 6.94136748 +4 1 6 1 5 9461.21242018 1.22116650 5.87016880 +4 1 6 1 6 4.89537799 1.32828637 -6.87709556 +4 1 6 1 7 -9465.60433479 0.40705550 -1.94958161 +4 1 6 1 8 0.19281576 -0.89980690 0.14996782 +4 1 6 2 1 -3065.44927775 1558.55123918 -3077.98230237 +4 1 6 2 2 -0.66414318 -0.73912709 573.18770452 +4 1 6 2 3 3067.67737102 -1558.48696726 -3078.06799826 +4 1 6 2 4 1.92815763 2.44233300 -2958.47937704 +4 1 6 2 5 -3060.86454738 -1552.70249436 -3072.54061305 +4 1 6 2 6 -1.88530969 -6.91994351 11774.93730853 +4 1 6 2 7 3059.62195690 1557.82282407 -3075.45427347 +4 1 6 2 8 -0.44990345 0.17139179 2914.44239908 +4 1 6 3 1 3061.65723440 -3078.00372634 1559.04399057 +4 1 6 3 2 -1.11404663 2913.81039186 0.54631133 +4 1 6 3 3 3065.94202915 -3078.08942224 -1558.97971865 +4 1 6 3 4 -6.56644794 -2960.02190314 -1.64964598 +4 1 6 3 5 -3056.66544853 -3070.33394376 -1562.62179418 +4 1 6 3 6 -6.72712774 11773.54475024 4.77754614 +4 1 6 3 7 -3056.96538416 -3075.53996937 1557.26580076 +4 1 6 3 8 0.51417537 574.76236659 1.45683021 +4 2 6 1 1 3065.89918120 1561.14354000 -3079.48198053 +4 2 6 1 2 -0.02142397 -0.17139179 2915.20295015 +4 2 6 1 3 -3065.87775722 -1561.07926808 -3079.48198053 +4 2 6 1 4 -0.07498391 7.00563940 11783.82825762 +4 2 6 1 5 3053.62324426 -1560.28658105 -3077.03964753 +4 2 6 1 6 3.81346732 -2.39948506 -2963.36404304 +4 2 6 1 7 -3057.15819993 1555.16625133 -3074.08313915 +4 2 6 1 8 -0.23566371 0.70699113 574.67667069 +4 2 6 2 1 -890.70170683 -0.17139179 -1.15689458 +4 2 6 2 2 0.57844729 0.02142397 -0.55702332 +4 2 6 2 3 886.26694428 0.08569589 -1.15689458 +4 2 6 2 4 5.06676978 0.83553497 6.96279145 +4 2 6 2 5 889.07348483 -0.40705550 3.29929195 +4 2 6 2 6 0.43919146 -0.44990345 -6.87709556 +4 2 6 2 7 -891.34442605 -0.17139179 -1.07119869 +4 2 6 2 8 0.59987126 0.20352775 0.62129524 +4 2 6 3 1 -90.70910467 -539.02717845 -536.64911737 +4 2 6 3 2 3371.64070996 -0.82482299 -0.77126305 +4 2 6 3 3 -90.77337659 -539.15572229 536.62769339 +4 2 6 3 4 -2961.93934879 6.98421543 -0.96407882 +4 2 6 3 5 -87.04560517 542.28362245 -534.31390423 +4 2 6 3 6 -2965.24935273 -5.74162495 -0.53559934 +4 2 6 3 7 -89.98068957 535.36367894 537.80601195 +4 2 6 3 8 2914.02463160 0.11783186 -1.01763875 +4 3 6 1 1 -3065.06364622 -3080.70314703 1556.38741783 +4 3 6 1 2 -0.72841511 573.31624836 -0.78197504 +4 3 6 1 3 -3067.16319565 -3080.68172306 -1556.40884181 +4 3 6 1 4 5.81660886 11784.47097683 -0.34278358 +4 3 6 1 5 3064.78513457 -3078.00372634 -1554.78061981 +4 3 6 1 6 5.73091297 -2961.15737375 -2.91366042 +4 3 6 1 7 3055.67994574 -3072.94766855 1559.92237350 +4 3 6 1 8 0.81411100 2915.69570154 -1.17831855 +4 3 6 2 1 -96.57927347 535.49222279 538.19164347 +4 3 6 2 2 2915.50288578 -0.24637570 -1.30686240 +4 3 6 2 3 -94.41545212 535.55649471 -538.21306745 +4 3 6 2 4 -2955.74782039 6.42719211 -2.48518095 +4 3 6 2 5 -95.87228234 -531.74302739 539.49850587 +4 3 6 2 6 -2958.95070446 -7.62693464 0.89980690 +4 3 6 2 7 -88.56670730 -538.77009076 -536.00639816 +4 3 6 2 8 3374.57579436 0.98550279 -0.43919146 +4 3 6 3 1 -885.38856136 -0.10711987 2.42090903 +4 3 6 3 2 -0.89980690 0.91051888 -1.99242955 +4 3 6 3 3 887.57380667 0.19281576 2.61372479 +4 3 6 3 4 -0.18210378 -1.24259047 -3.96343514 +4 3 6 3 5 892.20138499 -0.59987126 -7.41269490 +4 3 6 3 6 -1.61751001 0.10711987 3.87773924 +4 3 6 3 7 -892.13711307 -0.08569589 2.44233300 +4 3 6 3 8 0.55702332 0.74983908 1.96029359 +4 1 7 1 1 9469.50349801 -3060.32894803 3063.82105575 +4 1 7 1 2 0.64271921 -536.16707796 1555.77683458 +4 1 7 1 3 0.87838292 1556.77304936 -534.87092755 +4 1 7 1 4 -74060.30975321 71902.24074582 -71939.98978750 +4 1 7 1 5 1.09262266 534.61383986 -1556.60165757 +4 1 7 1 6 -9463.10844185 3057.22247185 -3060.00758843 +4 1 7 1 7 74050.93676471 -71899.38064533 71936.81903939 +4 1 7 1 8 0.34278358 -1555.12340339 535.12801523 +4 1 7 2 1 3064.20668728 890.15539551 93.68703702 +4 1 7 2 2 -0.38563153 -535.46008683 -3078.36793390 +4 1 7 2 3 1561.08998006 -0.51417537 3079.05350105 +4 1 7 2 4 66920.29918820 -71901.25524303 80698.90292561 +4 1 7 2 5 -537.74174003 2.07812545 3074.42592273 +4 1 7 2 6 -0.11783186 1557.43719255 -3075.00437002 +4 1 7 2 7 -71897.54889558 66928.76165781 -80701.76302610 +4 1 7 2 8 890.23037941 3058.80784590 -90.81622454 +4 1 7 3 1 -3059.57910895 90.83764851 889.48054033 +4 1 7 3 2 -884.51017843 -101.45322749 3065.36358186 +4 1 7 3 3 540.19478501 3075.30430566 0.47132742 +4 1 7 3 4 -66970.30274283 80708.32947404 -71949.58772772 +4 1 7 3 5 -1559.75098171 3079.71764424 -1.64964598 +4 1 7 3 6 -2.21738128 -3075.60424129 1556.98728910 +4 1 7 3 7 71936.66907157 -80703.77687963 66976.95488667 +4 1 7 3 8 -0.47132742 -3073.19404425 -537.62390817 +4 2 7 1 1 -0.44990345 -1561.74341126 3079.73906821 +4 2 7 1 2 535.81358239 0.53559934 -3078.19654211 +4 2 7 1 3 -890.35892326 -3064.14241535 93.70846099 +4 2 7 1 4 71905.44362989 -66921.68103450 80700.27405993 +4 2 7 1 5 -2.24951724 537.65604413 3074.40449876 +4 2 7 1 6 -3056.98680814 -889.00921291 -92.10166296 +4 2 7 1 7 -66934.21405912 71898.48083844 -80702.48072922 +4 2 7 1 8 -1557.05156102 -0.05355993 -3075.19718579 +4 2 7 2 1 -1555.93751439 -0.06427192 -535.36367894 +4 2 7 2 2 536.02782213 -0.58915928 1555.58401882 +4 2 7 2 3 3061.16448301 -9468.73223495 3064.35665509 +4 2 7 2 4 -71906.13990904 74059.80628983 -71941.46804168 +4 2 7 2 5 -534.33532821 -0.81411100 -1556.58023360 +4 2 7 2 6 1554.09505265 -0.74983908 535.89927829 +4 2 7 2 7 71901.76941840 -74052.84349837 71936.95829522 +4 2 7 2 8 -3056.81541635 9464.09394464 -3059.30059730 +4 2 7 3 1 3076.31123242 540.66611244 -1.14618259 +4 2 7 3 2 -101.95669087 -884.86367400 -3065.44927775 +4 2 7 3 3 90.40916904 -3060.60745969 -890.20895544 +4 2 7 3 4 80704.86950229 -66967.82827387 71949.52345579 +4 2 7 3 5 3079.81405212 -1559.81525363 1.90673366 +4 2 7 3 6 -3074.95081009 -1.90673366 538.83436268 +4 2 7 3 7 -80698.02454269 71937.30107879 -66975.86226401 +4 2 7 3 8 -3076.54689613 -2.86010049 -1557.45861652 +4 3 7 1 1 5.48453727 3079.31058874 -1557.96207990 +4 3 7 1 2 1556.96586512 -3078.74285344 -0.55702332 +4 3 7 1 3 2.77440459 3075.30430566 537.95597976 +4 3 7 1 4 -71947.45604233 80700.16694006 -66984.34615759 +4 3 7 1 5 891.07662637 93.36567741 -3062.70700912 +4 3 7 1 6 3057.27603178 -88.43816346 -890.61601094 +4 3 7 1 7 66971.77028503 -80709.42209670 71957.31107024 +4 3 7 1 8 -537.80601195 -3071.57653423 0.99621478 +4 3 7 2 1 3075.56139334 2.24951724 -538.30947533 +4 3 7 2 2 -3078.64644555 1557.10512095 0.46061543 +4 3 7 2 3 3077.35029514 2.72084466 1556.10890618 +4 3 7 2 4 80699.50279688 -71939.83981968 66983.63916646 +4 3 7 2 5 93.09787774 890.53031505 3062.98552077 +4 3 7 2 6 -3071.65151814 -537.67746810 -0.87838292 +4 3 7 2 7 -80707.36539523 66966.68209127 -71955.26508075 +4 3 7 2 8 -87.73117233 3058.17583868 891.34442605 +4 3 7 3 1 -1559.30107826 537.32397254 -2.94579638 +4 3 7 3 2 -3067.63452307 3067.61309909 -9457.99882413 +4 3 7 3 3 -534.90306351 1561.78625921 -1.28543842 +4 3 7 3 4 -71944.41383807 71937.89023807 -74124.67808221 +4 3 7 3 5 3058.44363835 -3057.56525543 9466.09708619 +4 3 7 3 6 1560.44726085 -535.77073444 2.18524532 +4 3 7 3 7 71951.70870111 -71950.78747024 74116.21561260 +4 3 7 3 8 535.79215842 -1560.43654886 2.24951724 +4 1 8 1 1 -0.19281576 -886.43833607 -1.15689458 +4 1 8 1 2 -0.00000000 0.23566371 -0.35349557 +4 1 8 1 3 0.10711987 886.37406415 -1.37113432 +4 1 8 1 4 -0.81411100 -1.41398226 8.20538193 +4 1 8 1 5 0.42847947 -891.19445823 3.34213990 +4 1 8 1 6 -0.20352775 0.19281576 0.34278358 +4 1 8 1 7 0.23566371 888.98778894 -1.09262266 +4 1 8 1 8 0.38563153 3.27786798 -8.23751789 +4 1 8 2 1 1561.14354000 3065.96345312 -3079.41770861 +4 1 8 2 2 0.06427192 -0.09640788 2915.23508611 +4 1 8 2 3 -1561.14354000 -3065.96345312 -3079.39628463 +4 1 8 2 4 -6.39505615 -0.72841511 11784.34243299 +4 1 8 2 5 1560.30800502 -3053.68751619 -3076.99679958 +4 1 8 2 6 -0.68556716 0.06427192 574.69809467 +4 1 8 2 7 -1555.14482736 3059.10778153 -3074.08313915 +4 1 8 2 8 1.84246174 -4.65971428 -2964.22100199 +4 1 8 3 1 -538.98433050 -90.73052865 -536.60626942 +4 1 8 3 2 -0.81411100 3371.73711784 0.61058325 +4 1 8 3 3 -539.09145037 -90.75195262 536.62769339 +4 1 8 3 4 6.39505615 -2961.07167785 0.34278358 +4 1 8 3 5 542.24077450 -87.06702914 534.14251244 +4 1 8 3 6 0.10711987 2914.21744736 1.17831855 +4 1 8 3 7 535.29940702 -92.12308694 -537.76316400 +4 1 8 3 8 -5.14175369 -2964.29598590 1.31757438 +4 2 8 1 1 1558.50839123 -3065.49212570 -3078.08942224 +4 2 8 1 2 1.00692676 0.31064762 573.34838433 +4 2 8 1 3 -1558.55123918 3067.63452307 -3077.93945442 +4 2 8 1 4 -3.79204335 -3.79204335 -2957.10824272 +4 2 8 1 5 1552.70249436 3058.59360616 -3072.54061305 +4 2 8 1 6 -0.40705550 -0.02142397 2914.30314325 +4 2 8 1 7 -1557.73712818 -3057.43671158 -3075.58281731 +4 2 8 1 8 8.29107782 0.14996782 11773.71614203 +4 2 8 2 1 0.42847947 -9471.62447140 -1.92815763 +4 2 8 2 2 0.89980690 -0.31064762 -0.23566371 +4 2 8 2 3 -0.42847947 9473.93826056 -1.97100558 +4 2 8 2 4 -0.57844729 2.14239737 6.25580032 +4 2 8 2 5 -1.17831855 -9463.44051345 5.65592906 +4 2 8 2 6 0.69627915 -0.14996782 0.36420755 +4 2 8 2 7 -0.32135961 9463.56905729 -1.97100558 +4 2 8 2 8 0.72841511 -4.01699507 -6.23437635 +4 2 8 3 1 -3078.11084621 3061.63581043 1558.97971865 +4 2 8 3 2 2913.91751173 -0.94265484 -1.18903054 +4 2 8 3 3 -3078.02515032 3065.98487709 -1558.80832686 +4 2 8 3 4 -2960.77174222 -5.76304893 -2.87081248 +4 2 8 3 5 -3070.37679170 -3054.45877924 1562.49325034 +4 2 8 3 6 574.69809467 0.70699113 -0.79268703 +4 2 8 3 7 -3075.45427347 -3061.29302685 -1557.33007268 +4 2 8 3 8 11774.25174137 -5.83803283 -0.42847947 +4 3 8 1 1 535.47079881 -96.60069744 538.38445924 +4 3 8 1 2 -0.44990345 2915.17081419 0.94265484 +4 3 8 1 3 535.53507073 -94.47972404 -538.25591539 +4 3 8 1 4 7.70191855 -2957.60099411 -0.02142397 +4 3 8 1 5 -531.87157123 -91.58748759 -539.45565792 +4 3 8 1 6 1.18903054 3374.34013065 0.92123087 +4 3 8 1 7 -538.70581884 -88.48101141 536.02782213 +4 3 8 1 8 -8.86952511 -2960.78245421 1.60679803 +4 3 8 2 1 -3080.68172306 -3064.99937430 1556.28029797 +4 3 8 2 2 573.32696035 -0.81411100 1.18903054 +4 3 8 2 3 -3080.63887511 -3067.18461962 -1556.40884181 +4 3 8 2 4 11784.55667272 5.76304893 2.93508440 +4 3 8 2 5 -3078.04657429 3062.59988925 1554.60922802 +4 3 8 2 6 2915.72783750 0.92123087 0.79268703 +4 3 8 2 7 -3072.92624457 3057.97231093 -1559.92237350 +4 3 8 2 8 -2961.24306964 5.69877701 0.25708768 +4 3 8 3 1 -0.10711987 -885.36713738 2.48518095 +4 3 8 3 2 -0.85695895 0.19281576 -2.08883744 +4 3 8 3 3 0.12854384 887.61665462 2.52802890 +4 3 8 3 4 0.54631133 -2.54945287 -4.62757832 +4 3 8 3 5 0.38563153 -890.08041160 -7.36984695 +4 3 8 3 6 -0.84624696 -1.09262266 2.01385353 +4 3 8 3 7 0.23566371 892.22280897 2.52802890 +4 3 8 3 8 0.57844729 -1.04977471 4.59544236 +5 1 1 1 1 -0.02142397 -0.03213596 -9.10518883 +5 1 1 1 2 -0.83553497 -890.29465133 -0.14996782 +5 1 1 1 3 0.03213596 -0.04284795 0.87838292 +5 1 1 1 4 0.88909491 890.14468352 -0.29993563 +5 1 1 1 5 -0.11783186 -0.06427192 13.28286370 +5 1 1 1 6 -0.62129524 -889.56623623 -2.35663711 +5 1 1 1 7 0.06427192 0.04284795 0.43919146 +5 1 1 1 8 0.53559934 889.50196431 -2.49589294 +5 1 1 2 1 1.24259047 -1.84246174 2959.80766341 +5 1 1 2 2 1560.54366873 -3071.70507807 3080.36036345 +5 1 1 2 3 -0.16067980 -0.34278358 -573.00560075 +5 1 1 2 4 -1560.55438072 3071.70507807 3080.42463537 +5 1 1 2 5 -1.24259047 -1.82103777 -11776.28701887 +5 1 1 2 6 1553.15239780 3059.42914114 3071.76934999 +5 1 1 2 7 0.14996782 -0.32135961 -2914.66735081 +5 1 1 2 8 -1553.10954986 -3055.03722653 3071.87646986 +5 1 1 3 1 -13.11147191 2961.20022170 0.61058325 +5 1 1 3 2 -536.04924610 94.73681173 538.23449142 +5 1 1 3 3 -0.22495172 -2914.47453504 0.17139179 +5 1 1 3 4 -536.15636597 94.75823570 -538.17021950 +5 1 1 3 5 17.32128274 2964.45666570 -0.68556716 +5 1 1 3 6 534.67811179 87.36696477 -537.69889208 +5 1 1 3 7 -1.24259047 -3373.61171554 -0.07498391 +5 1 1 3 8 534.72095973 85.31026330 537.84885989 +5 2 1 1 1 -1.30686240 1.78890180 -11786.34557453 +5 2 1 1 2 1560.86502834 3071.46941436 3081.45298611 +5 2 1 1 3 0.17139179 0.34278358 -2915.31007002 +5 2 1 1 4 -1560.79004443 -3071.38371847 3081.45298611 +5 2 1 1 5 1.31757438 1.73534187 2966.06346373 +5 2 1 1 6 1558.07991176 -3056.30124098 3073.65465968 +5 2 1 1 7 -0.19281576 0.36420755 -574.32317513 +5 2 1 1 8 -1558.05848778 3051.86647842 3073.59038776 +5 2 1 2 1 -0.00000000 -0.04284795 -8.81596518 +5 2 1 2 2 0.79268703 -9474.68809964 0.85695895 +5 2 1 2 3 -0.04284795 -0.04284795 -0.17139179 +5 2 1 2 4 -0.80339901 9474.62382772 1.11404663 +5 2 1 2 5 -0.00000000 -0.00000000 13.36855959 +5 2 1 2 6 -0.12854384 -9456.11351444 -2.91366042 +5 2 1 2 7 -0.06427192 0.02142397 -0.20352775 +5 2 1 2 8 0.06427192 9456.19921033 -2.96722036 +5 2 1 3 1 -11784.51382478 -4.48832249 -0.02142397 +5 2 1 3 2 3081.75292174 3064.99937430 1556.30172194 +5 2 1 3 3 -573.29482439 1.69249392 0.02142397 +5 2 1 3 4 3081.80648168 3065.04222225 -1556.32314591 +5 2 1 3 5 2961.16808574 -4.32764269 -0.04284795 +5 2 1 3 6 3074.46877068 -3061.35729877 1557.35149665 +5 2 1 3 7 -2915.73854949 -0.08569589 0.01071199 +5 2 1 3 8 3074.53304260 -3061.34658679 -1557.33007268 +5 3 1 1 1 -12.21166501 2959.22921612 -0.58915928 +5 3 1 1 2 538.27733937 94.05124457 -536.52057352 +5 3 1 1 3 1.39255829 -3372.17630930 -0.10711987 +5 3 1 1 4 538.19164347 94.00839662 536.45630160 +5 3 1 1 5 13.76490311 2962.50708409 0.64271921 +5 3 1 1 6 -539.45565792 87.28126888 536.07067008 +5 3 1 1 7 -0.29993563 -2914.66735081 0.07498391 +5 3 1 1 8 -539.54135382 89.50936214 -536.02782213 +5 3 1 2 1 2958.07232153 10.61557897 -0.03213596 +5 3 1 2 2 3081.15305048 -3064.33523112 1558.27272752 +5 3 1 2 3 -2913.56401616 1.26401445 0.02142397 +5 3 1 2 4 3081.17447445 -3064.24953522 -1558.29415149 +5 3 1 2 5 -11771.71300049 13.11147191 0.02142397 +5 3 1 2 6 3069.81976839 3052.95910108 1560.60794065 +5 3 1 2 7 -574.99803030 -2.23880525 0.03213596 +5 3 1 2 8 3069.84119236 3052.93767711 -1560.51153277 +5 3 1 3 1 0.04284795 0.02142397 8.22680590 +5 3 1 3 2 -0.10711987 -886.33121620 -1.94958161 +5 3 1 3 3 0.02142397 0.06427192 2.63514877 +5 3 1 3 4 0.12854384 886.43833607 -2.05670148 +5 3 1 3 5 0.04284795 0.04284795 -10.32635533 +5 3 1 3 6 0.14996782 -891.30157810 2.91366042 +5 3 1 3 7 0.02142397 -0.03213596 -2.23880525 +5 3 1 3 8 -0.21423974 891.24801816 2.94579638 +5 1 2 1 1 -1.30686240 1559.55816594 -536.94905300 +5 1 2 1 2 -74173.54616623 72114.10242181 -72080.03830361 +5 1 2 1 3 9477.33396039 -3068.19154638 3067.09892373 +5 1 2 1 4 0.21423974 -540.82679224 1560.32942900 +5 1 2 1 5 74162.80204342 -72101.41942937 72062.32067736 +5 1 2 1 6 -1.03906272 -1561.01499615 541.68375119 +5 1 2 1 7 -0.49275140 537.69889208 -1559.06541455 +5 1 2 1 8 -9463.82614497 3060.06114836 -3055.20861832 +5 1 2 2 1 -888.13082999 -3068.93067348 94.91891551 +5 1 2 2 2 72109.71050720 -67118.04246551 80902.60206761 +5 1 2 2 3 0.37491954 -1560.07234131 3080.55317921 +5 1 2 2 4 540.15193707 0.51417537 -3074.64016247 +5 1 2 2 5 -67159.40144675 72100.60531837 -80923.96176940 +5 1 2 2 6 -1552.13475905 1.52110213 -3069.96973620 +5 1 2 2 7 3.68492348 533.86400078 3077.29673521 +5 1 2 2 8 -3054.28738745 -889.59837219 -86.90634934 +5 1 2 3 1 -0.96407882 3079.87832404 538.44873116 +5 1 2 3 2 -72076.78185961 80900.02047878 -67092.25871315 +5 1 2 3 3 -0.25708768 3080.53175524 -1555.10197941 +5 1 2 3 4 1560.81146840 -3074.42592273 0.47132742 +5 1 2 3 5 67095.39732530 -80910.50751391 72055.91490922 +5 1 2 3 6 -530.69325268 -3076.84683176 0.42847947 +5 1 2 3 7 889.67335610 93.55849317 -3056.79399237 +5 1 2 3 8 3062.79270501 -92.16593488 -891.29086611 +5 2 2 1 1 1560.02949336 -0.34278358 3080.55317921 +5 2 2 1 2 67116.25356370 -72107.95374135 80901.40232508 +5 2 2 1 3 3068.87711354 888.06655807 94.95105147 +5 2 2 1 4 -0.61058325 -540.11980111 -3074.89725015 +5 2 2 1 5 -72098.23796928 67157.04480964 -80923.70468171 +5 2 2 1 6 889.99471570 3055.25146627 -86.12437430 +5 2 2 1 7 -533.88542476 -3.66349950 3077.27531124 +5 2 2 1 8 -2.57087684 1551.70627958 -3069.28416904 +5 2 2 2 1 3068.21297036 -9477.30182443 3067.09892373 +5 2 2 2 2 -72113.95245399 74173.65328610 -72080.02759163 +5 2 2 2 3 -1559.56887793 1.30686240 -536.92762902 +5 2 2 2 4 540.81608025 -0.23566371 1560.30800502 +5 2 2 2 5 72101.40871738 -74162.81275541 72062.36352530 +5 2 2 2 6 -3060.07186035 9463.84756895 -3055.18719435 +5 2 2 2 7 -537.67746810 0.50346338 -1559.04399057 +5 2 2 2 8 1560.97214821 1.01763875 541.68375119 +5 2 2 3 1 3080.48890729 -0.29993563 1555.09126742 +5 2 2 3 2 80900.03119077 -72076.84613153 67092.29084911 +5 2 2 3 3 3079.86761205 -0.96407882 -538.42730718 +5 2 2 3 4 -3074.40449876 1560.80075642 -0.40705550 +5 2 2 3 5 -80910.51822590 67095.42946126 -72055.91490922 +5 2 2 3 6 -92.09095098 3062.81412898 891.23730618 +5 2 2 3 7 93.55849317 889.69478007 3056.82612833 +5 2 2 3 8 -3076.91110368 -530.67182870 -0.46061543 +5 3 2 1 1 537.91313182 3080.69243504 -0.37491954 +5 3 2 1 2 -67092.62292071 80902.98769914 -72062.15999755 +5 3 2 1 3 -3066.97037988 94.71538776 888.08798204 +5 3 2 1 4 -891.09805035 -81.21828432 3057.39386364 +5 3 2 1 5 72060.04973614 -80922.01218779 67086.06718475 +5 3 2 1 6 3.08505221 -3077.55382289 -534.82807960 +5 3 2 1 7 -1556.55880962 3074.97223406 3.57780361 +5 3 2 1 8 6.06298456 -3072.57274901 1562.17189073 +5 3 2 2 1 94.73681173 -3066.95966790 -888.13082999 +5 3 2 2 2 80903.00912311 -67092.44081693 72062.20284550 +5 3 2 2 3 3080.67101107 537.89170784 0.40705550 +5 3 2 2 4 -81.22899631 -891.04449041 -3057.41528761 +5 3 2 2 5 -80922.00147580 72060.00688820 -67086.04576078 +5 3 2 2 6 -3072.59417298 6.06298456 -1562.15046676 +5 3 2 2 7 3075.00437002 -1556.56952161 -3.54566765 +5 3 2 2 8 -3077.53239892 3.07434023 534.81736761 +5 3 2 3 1 -536.86335710 1557.44790453 -2.81725254 +5 3 2 3 2 -72066.28411249 72066.61618409 -74083.90826025 +5 3 2 3 3 -1557.44790453 536.94905300 -2.82796453 +5 3 2 3 4 -3056.81541635 3057.09392801 -9483.02202541 +5 3 2 3 5 72059.08565733 -72061.33517457 74120.22189568 +5 3 2 3 6 540.68753641 -1552.85246217 -6.34149622 +5 3 2 3 7 3064.03529549 -3064.05671946 9465.72216665 +5 3 2 3 8 1553.68799715 -539.86271342 -6.89851953 +5 1 3 1 1 -0.06427192 0.02142397 -0.26779967 +5 1 3 1 2 9474.66667567 -0.81411100 0.81411100 +5 1 3 1 3 -0.04284795 -0.02142397 -8.76240525 +5 1 3 1 4 -9474.62382772 0.70699113 0.47132742 +5 1 3 1 5 0.05355993 -0.02142397 13.47567946 +5 1 3 1 6 -9456.19921033 -0.02142397 -2.82796453 +5 1 3 1 7 0.04284795 0.05355993 -0.14996782 +5 1 3 1 8 9456.13493841 -0.00000000 -3.07434023 +5 1 3 2 1 -0.00000000 -0.01071199 -2915.58858168 +5 1 3 2 2 -3069.28416904 -1560.73648450 3081.34586624 +5 1 3 2 3 -0.02142397 -0.00000000 -11786.27059062 +5 1 3 2 4 3069.24132110 1560.77933244 3081.23874637 +5 1 3 2 5 -0.04284795 -0.00000000 2965.97776783 +5 1 3 2 6 -3056.27981700 1558.10133573 3073.61181173 +5 1 3 2 7 0.02142397 0.06427192 -574.32317513 +5 1 3 2 8 3056.32266495 -1558.04777580 3073.62252372 +5 1 3 3 1 0.77126305 -573.03773671 0.02142397 +5 1 3 3 2 3069.30559302 3081.73149777 -1556.32314591 +5 1 3 3 3 -9.03020492 -11786.35628651 0.55702332 +5 1 3 3 4 3069.30559302 3081.79576969 1556.28029797 +5 1 3 3 5 -8.85881313 2963.14980330 -0.62129524 +5 1 3 3 6 -3059.15062948 3074.46877068 1557.26580076 +5 1 3 3 7 -0.85695895 -2916.01706115 -0.02142397 +5 1 3 3 8 -3061.44299467 3074.31880286 -1557.37292062 +5 2 3 1 1 -0.00000000 -0.01071199 -573.01631273 +5 2 3 1 2 3069.39128891 -1560.56509271 3080.57460319 +5 2 3 1 3 0.05355993 -0.06427192 2959.63627162 +5 2 3 1 4 -3069.53054474 1560.45797284 3080.51033127 +5 2 3 1 5 0.04284795 -0.04284795 -11776.37271477 +5 2 3 1 6 3059.40771717 1553.10954986 3071.94074178 +5 2 3 1 7 0.04284795 -0.00000000 -2914.74233471 +5 2 3 1 8 -3059.38629319 -1553.09883787 3071.76934999 +5 2 3 2 1 0.08569589 -0.05355993 1.00692676 +5 2 3 2 2 890.20895544 0.85695895 -0.19281576 +5 2 3 2 3 -0.00000000 -0.14996782 -7.88402232 +5 2 3 2 4 -890.19824345 -0.92123087 0.17139179 +5 2 3 2 5 -0.06427192 -0.04284795 12.08312117 +5 2 3 2 6 -887.48811078 -0.40705550 -2.52802890 +5 2 3 2 7 0.08569589 0.02142397 0.21423974 +5 2 3 2 8 887.38099091 0.57844729 -2.46375698 +5 2 3 3 1 -2915.01013439 -0.34278358 -0.03213596 +5 2 3 3 2 94.77965968 -536.09209405 -538.29876334 +5 2 3 3 3 2958.49008902 -11.20473825 0.12854384 +5 2 3 3 4 94.80108365 -536.11351802 538.29876334 +5 2 3 3 5 2961.76795700 15.44668504 -0.04284795 +5 2 3 3 6 89.61648201 534.74238371 -537.78458797 +5 2 3 3 7 -3374.10446694 -0.95336683 -0.00000000 +5 2 3 3 8 89.70217791 534.71024775 537.74174003 +5 3 3 1 1 1.92815763 -2913.87466378 0.02142397 +5 3 3 1 2 -3068.74856970 3081.11020253 -1558.22987957 +5 3 3 1 3 14.19338258 2960.87886209 -0.06427192 +5 3 3 1 4 -3068.67358579 3081.21732240 1558.16560765 +5 3 3 1 5 16.67856353 -11774.20889342 -0.00000000 +5 3 3 1 6 3053.08764492 3069.84119236 1560.65078860 +5 3 3 1 7 -1.47825419 -574.68738268 -0.05355993 +5 3 3 1 8 3052.98052505 3069.83048037 -1560.55438072 +5 3 3 2 1 -3372.13346135 1.29615041 -0.00000000 +5 3 3 2 2 94.05124457 538.27733937 536.60626942 +5 3 3 2 3 2959.32562400 -12.16881707 0.72841511 +5 3 3 2 4 94.01910861 538.25591539 -536.54199750 +5 3 3 2 5 2962.52850807 13.71134317 -0.57844729 +5 3 3 2 6 89.53078612 -539.47708190 536.02782213 +5 3 3 2 7 -2914.64592683 -0.31064762 -0.10711987 +5 3 3 2 8 87.38838875 -539.54135382 -536.04924610 +5 3 3 3 1 0.14996782 -0.11783186 2.69942069 +5 3 3 3 2 886.39548812 0.10711987 -2.03527750 +5 3 3 3 3 0.97479080 0.66414318 8.84810114 +5 3 3 3 4 -888.46290158 -0.02142397 -1.84246174 +5 3 3 3 5 0.92123087 -0.59987126 -10.92622659 +5 3 3 3 6 -891.32300207 0.08569589 2.95650837 +5 3 3 3 7 0.14996782 0.07498391 -2.28165320 +5 3 3 3 8 891.28015412 -0.08569589 2.81725254 +5 1 4 1 1 1.28543842 -1559.56887793 -536.91691704 +5 1 4 1 2 -0.34278358 540.64468846 1560.22230913 +5 1 4 1 3 -9477.33396039 3068.19154638 3067.09892373 +5 1 4 1 4 74173.97464571 -72114.61659717 -72080.20969540 +5 1 4 1 5 -74162.52353176 72103.32616303 72061.87077391 +5 1 4 1 6 9463.94397683 -3060.22182817 -3055.10149845 +5 1 4 1 7 0.53559934 -537.76316400 -1559.02256660 +5 1 4 1 8 0.36420755 1560.10447727 542.32647040 +5 1 4 2 1 888.04513410 3068.93067348 94.89749153 +5 1 4 2 2 -540.16264905 -0.53559934 -3074.64016247 +5 1 4 2 3 -0.35349557 1560.05091734 3080.46748332 +5 1 4 2 4 -72109.66765925 67117.96748160 80902.68776351 +5 1 4 2 5 67159.33717483 -72100.41250261 -80923.76895363 +5 1 4 2 6 3054.26596348 889.56623623 -86.89563735 +5 1 4 2 7 -3.64207553 -533.89613675 3077.28602322 +5 1 4 2 8 1552.14547104 -1.56395008 -3070.03400812 +5 1 4 3 1 -0.89980690 3079.84618808 -538.47015513 +5 1 4 3 2 1560.86502834 -3074.46877068 -0.46061543 +5 1 4 3 3 -0.28922365 3080.53175524 1555.08055544 +5 1 4 3 4 -72076.52477192 80899.60271129 67091.98020149 +5 1 4 3 5 67095.01169377 -80910.10045841 -72055.57212564 +5 1 4 3 6 3062.79270501 -92.12308694 891.23730618 +5 1 4 3 7 889.73762802 93.55849317 3056.79399237 +5 1 4 3 8 -530.71467665 -3076.86825574 -0.49275140 +5 2 4 1 1 -1560.00806939 0.36420755 3080.55317921 +5 2 4 1 2 0.64271921 540.07695316 -3074.81155426 +5 2 4 1 3 -3068.90924950 -888.04513410 94.86535557 +5 2 4 1 4 -67116.39281953 72107.97516533 80901.33805316 +5 2 4 1 5 72098.30224120 -67157.10908156 -80923.87607350 +5 2 4 1 6 2.58158883 -1551.67414362 -3069.24132110 +5 2 4 1 7 533.94969668 3.65278752 3077.29673521 +5 2 4 1 8 -890.01613968 -3055.26217825 -86.18864622 +5 2 4 2 1 -3068.25581831 9477.33396039 3067.09892373 +5 2 4 2 2 -540.65540045 0.28922365 1560.21159714 +5 2 4 2 3 1559.59030190 -1.30686240 -536.97047697 +5 2 4 2 4 72115.03436466 -74174.42454916 -72080.83099064 +5 2 4 2 5 -72103.56182674 74162.87702733 72062.02074173 +5 2 4 2 6 -1560.14732522 -0.40705550 542.28362245 +5 2 4 2 7 537.76316400 -0.54631133 -1559.03327859 +5 2 4 2 8 3060.22182817 -9463.93326484 -3055.06936249 +5 2 4 3 1 3080.48890729 -0.29993563 -1555.11269140 +5 2 4 3 2 -3074.68301042 1560.55438072 0.46061543 +5 2 4 3 3 3079.88903603 -0.92123087 538.47015513 +5 2 4 3 4 80899.31348765 -72076.63189179 -67091.89450560 +5 2 4 3 5 -80907.86165316 67097.03625929 72055.50785372 +5 2 4 3 6 -3077.70379071 -531.46451573 -0.00000000 +5 2 4 3 7 93.62276510 889.69478007 -3056.79399237 +5 2 4 3 8 -92.91577396 3062.00001798 -890.76597876 +5 3 4 1 1 537.91313182 3080.66029908 0.43919146 +5 3 4 1 2 -891.15161028 -81.20757233 -3057.43671158 +5 3 4 1 3 -3066.95966790 94.71538776 -888.10940602 +5 3 4 1 4 -67092.34440905 80902.83773132 72062.17070954 +5 3 4 1 5 72059.95332826 -80921.90506792 -67086.06718475 +5 3 4 1 6 6.06298456 -3072.60488497 -1562.19331471 +5 3 4 1 7 -1556.51596168 3074.95081009 -3.55637964 +5 3 4 1 8 3.10647619 -3077.56453488 534.79594364 +5 3 4 2 1 94.73681173 -3066.94895591 888.10940602 +5 3 4 2 2 -81.19686035 -891.10876234 3057.44742357 +5 3 4 2 3 3080.68172306 537.95597976 -0.38563153 +5 3 4 2 4 80902.84844331 -67092.36583302 -72062.02074173 +5 3 4 2 5 -80921.91577991 72059.92119230 67085.89579296 +5 3 4 2 6 -3077.54311091 3.10647619 -534.74238371 +5 3 4 2 7 3074.96152208 -1556.56952161 3.53495566 +5 3 4 2 8 -3072.60488497 6.08440853 1562.17189073 +5 3 4 3 1 536.88478108 -1557.44790453 -2.76369261 +5 3 4 3 2 3057.02965608 -3056.72972045 -9482.85063362 +5 3 4 3 3 1557.44790453 -536.88478108 -2.82796453 +5 3 4 3 4 72064.98796208 -72064.74158639 -74082.62282182 +5 3 4 3 5 -72059.06423335 72056.85756406 74120.05050389 +5 3 4 3 6 -1553.84867695 540.24834495 -7.11275927 +5 3 4 3 7 -3064.05671946 3064.03529549 9465.70074267 +5 3 4 3 8 -539.39138600 1554.68421192 -7.66978259 +5 1 5 1 1 0.77126305 -1.06048670 16.05726829 +5 1 5 1 2 74158.14232914 -67155.81293115 67095.98648458 +5 1 5 1 3 -0.26779967 0.04284795 -8.09826206 +5 1 5 1 4 -74157.97093735 67155.84506711 67095.77224484 +5 1 5 1 5 -2.11026141 -1.92815763 -387.68822819 +5 1 5 1 6 -73990.13552734 -66819.74576761 -66907.41266802 +5 1 5 1 7 1.37113432 1.03906272 8.13039802 +5 1 5 1 8 73990.15695131 66821.92030094 -66912.20092614 +5 1 5 2 1 -0.00000000 0.08569589 2959.14352022 +5 1 5 2 2 -72101.71936500 72101.71936500 -80905.50501605 +5 1 5 2 3 0.01071199 -0.06427192 2959.10067227 +5 1 5 2 4 72101.88004481 -72101.89075679 -80905.79423969 +5 1 5 2 5 -0.06427192 0.29993563 328882.97674338 +5 1 5 2 6 -71808.43587695 -71808.42516497 -80608.60087644 +5 1 5 2 7 0.06427192 -0.08569589 -11773.06271083 +5 1 5 2 8 71808.40374099 71808.26448516 -80608.27951684 +5 1 5 3 1 14.41833430 -11771.85225631 -1.25330246 +5 1 5 3 2 72062.59918902 -80922.22642753 72055.34717392 +5 1 5 3 3 12.57587257 2960.87886209 -0.19281576 +5 1 5 3 4 72062.17070954 -80921.94791587 -72054.97225438 +5 1 5 3 5 -387.76321210 328883.51234273 1.00692676 +5 1 5 3 6 -71879.94910118 -80593.49697498 -71890.75749592 +5 1 5 3 7 -4.11340295 2953.94820660 0.07498391 +5 1 5 3 8 -71879.85269330 -80588.96580454 71890.48969625 +5 2 5 1 1 -0.00000000 0.02142397 2959.18636817 +5 2 5 1 2 -72101.74078898 72101.63366911 -80905.55857598 +5 2 5 1 3 -0.01071199 -0.04284795 2959.16494419 +5 2 5 1 4 72101.86933282 -72101.91218077 -80905.62284790 +5 2 5 1 5 -0.09640788 0.25708768 328883.16955915 +5 2 5 1 6 -71808.35018106 -71808.53228483 -80608.51518055 +5 2 5 1 7 0.02142397 -0.08569589 -11773.00915089 +5 2 5 1 8 71808.42516497 71808.39302900 -80608.39734869 +5 2 5 2 1 0.12854384 -0.09640788 -7.85188636 +5 2 5 2 2 67156.12357877 -74158.05663324 67095.99719656 +5 2 5 2 3 -0.22495172 0.10711987 18.08183381 +5 2 5 2 4 -67155.74865923 74157.99236132 67095.85794074 +5 2 5 2 5 -1.47825419 -1.02835074 -389.61638582 +5 2 5 2 6 -66817.62479421 -73990.13552734 -66907.71260365 +5 2 5 2 7 1.37113432 1.30686240 7.93758226 +5 2 5 2 8 66817.64621819 73990.07125541 -66912.26519806 +5 2 5 3 1 2965.52786438 18.09254579 0.05355993 +5 2 5 3 2 -80923.68325774 72056.15057293 -72055.21863007 +5 2 5 3 3 -11768.79934006 15.44668504 -0.00000000 +5 2 5 3 4 -80923.01911455 72055.52927769 72054.52235093 +5 2 5 3 5 328878.97046030 -384.32466432 0.29993563 +5 2 5 3 6 -80591.86875298 -71878.63152680 -71889.60060134 +5 2 5 3 7 2955.18008508 -3.02078029 -0.01071199 +5 2 5 3 8 -80592.25438450 -71879.03858230 71889.96480889 +5 3 5 1 1 14.50403020 -11771.85225631 -1.28543842 +5 3 5 1 2 72062.38494928 -80922.01218779 72055.16507014 +5 3 5 1 3 12.51160064 2960.90028606 -0.19281576 +5 3 5 1 4 72062.24569345 -80921.92649189 -72055.10079822 +5 3 5 1 5 -387.61324428 328883.38379888 1.52110213 +5 3 5 1 6 -71880.03479708 -80593.66836677 -71890.67180002 +5 3 5 1 7 -4.09197898 2954.00176653 0.22495172 +5 3 5 1 8 -71879.80984535 -80588.98722851 71890.51112022 +5 3 5 2 1 2965.48501644 18.11396977 0.02142397 +5 3 5 2 2 -80923.81180158 72056.08630101 -72055.24005405 +5 3 5 2 3 -11768.74578013 15.55380491 0.06427192 +5 3 5 2 4 -80922.76202687 72055.05795027 72054.09387145 +5 3 5 2 5 328878.61696473 -384.17469650 0.59987126 +5 3 5 2 6 -80591.80448106 -71878.58867885 -71889.34351365 +5 3 5 2 7 2955.26578098 -3.03149228 -0.00000000 +5 3 5 2 8 -80592.34008040 -71879.08143025 71889.85768902 +5 3 5 3 1 0.85695895 -1.04977471 -9.97285976 +5 3 5 3 2 67081.95378180 -67081.96449379 74113.44120800 +5 3 5 3 3 -0.27851166 -0.04284795 -9.23373267 +5 3 5 3 4 -67081.82523796 67081.99662975 74113.32337615 +5 3 5 3 5 -2.04598949 -1.90673366 28.47246106 +5 3 5 3 6 -66906.80208477 -66906.72710086 -74110.49541162 +5 3 5 3 7 1.39255829 1.07119869 -10.62629096 +5 3 5 3 8 66906.83422073 66909.01946604 -74114.80163033 +5 1 6 1 1 -0.96407882 1553.77369304 534.26034430 +5 1 6 1 2 -0.62129524 -1552.55252654 -531.60377156 +5 1 6 1 3 -9459.56277421 -3053.08764492 -3057.90803901 +5 1 6 1 4 9463.10844185 3055.52997792 3062.21425772 +5 1 6 1 5 -73991.82802126 -71805.44723262 -71878.37443912 +5 1 6 1 6 73991.34598185 71801.89085298 71869.24782632 +5 1 6 1 7 -0.92123087 533.96040867 1555.38049107 +5 1 6 1 8 -0.70699113 -533.93898469 -1553.50589337 +5 1 6 2 1 -890.89452260 3056.08700124 90.58056083 +5 1 6 2 2 -1559.83667760 0.82482299 -3077.51097495 +5 1 6 2 3 0.64271921 1557.43719255 3074.04029121 +5 1 6 2 4 -3059.60053293 889.52338828 -93.55849317 +5 1 6 2 5 -66822.94865168 -71804.35460996 -80591.07606595 +5 1 6 2 6 71802.79065988 66839.32727958 80599.21717596 +5 1 6 2 7 -2.67799671 -537.82743592 3077.45741501 +5 1 6 2 8 532.68568223 -1.10333465 -3079.13919695 +5 1 6 3 1 -3.89916321 3073.27974014 -538.95219454 +5 1 6 3 2 542.86206974 -3070.77313522 -0.07498391 +5 1 6 3 3 -4.30621871 3075.06864194 1558.01563984 +5 1 6 3 4 -3054.25525149 -87.21699696 890.10183557 +5 1 6 3 5 -66913.49707655 -80606.32993523 -71895.12798655 +5 1 6 3 6 71873.00773370 80595.38228466 66916.28219313 +5 1 6 3 7 -885.60280109 101.50678742 3068.98423341 +5 1 6 3 8 -1554.43783623 -3080.94952273 0.49275140 +5 2 6 1 1 1558.31557547 -0.20352775 3074.65087446 +5 2 6 1 2 889.73762802 -3059.54697299 -93.65490106 +5 2 6 1 3 3057.00823211 -891.79432949 90.02353751 +5 2 6 1 4 1.69249392 -1560.52224476 -3078.06799826 +5 2 6 1 5 -71806.19707170 -66823.21645135 -80591.16176184 +5 2 6 1 6 66838.00970519 71805.74716825 80599.73135133 +5 2 6 1 7 -537.52750029 -2.93508440 3077.40385508 +5 2 6 1 8 -0.85695895 532.57856236 -3079.06421304 +5 2 6 2 1 -3053.13049287 -9459.53063825 -3057.89732702 +5 2 6 2 2 3055.44428203 9463.12986583 3062.19283375 +5 2 6 2 3 1553.78440503 -0.87838292 534.27105629 +5 2 6 2 4 -1552.57395051 -0.66414318 -531.59305957 +5 2 6 2 5 -71806.10066382 -73992.47074047 -71878.76007064 +5 2 6 2 6 71802.52286021 73992.02083702 71869.80484963 +5 2 6 2 7 534.01396860 -0.86767094 1555.41262703 +5 2 6 2 8 -533.92827271 -0.72841511 -1553.47375741 +5 2 6 3 1 3074.68301042 -4.55259441 1558.21916759 +5 2 6 3 2 -87.23842093 -3054.21240354 890.11254756 +5 2 6 3 3 3071.41585443 -2.61372479 -537.65604413 +5 2 6 3 4 -3070.77313522 542.81922179 -0.06427192 +5 2 6 3 5 -80608.76155624 -66915.48950610 -71896.92760035 +5 2 6 3 6 80600.23481471 71873.74686080 66916.92491234 +5 2 6 3 7 101.05688397 -885.42069732 3068.80212964 +5 2 6 3 8 -3080.91738677 -1554.39498828 0.50346338 +5 3 6 1 1 -539.32711408 3069.44484885 0.35349557 +5 3 6 1 2 3.77061937 -3073.14048431 539.64847369 +5 3 6 1 3 3053.62324426 86.55285377 -891.32300207 +5 3 6 1 4 5.84874482 -3077.12534342 -1554.86631570 +5 3 6 1 5 -71877.87097573 -80588.71942884 -66910.19778460 +5 3 6 1 6 66912.12594223 80611.81447250 71886.60124502 +5 3 6 1 7 1558.22987957 3080.91738677 2.52802890 +5 3 6 1 8 883.63179551 -109.74430531 -3072.56203702 +5 3 6 2 1 86.55285377 3053.75178811 -891.32300207 +5 3 6 2 2 -3076.48262421 4.88466601 -1554.29858040 +5 3 6 2 3 3069.41271289 -539.32711408 0.34278358 +5 3 6 2 4 -3073.23689219 3.59922758 539.73416958 +5 3 6 2 5 -80588.69800487 -71875.71786638 -66910.32632844 +5 3 6 2 6 80611.33243309 66911.16186341 71885.95852581 +5 3 6 2 7 3080.85311485 1558.15489566 2.54945287 +5 3 6 2 8 -109.64789743 883.39613180 -3072.64773292 +5 3 6 3 1 536.17778994 1560.17946118 3.10647619 +5 3 6 3 2 -533.47836926 -1563.91794459 -6.05227257 +5 3 6 3 3 1560.20088515 536.24206187 3.04220427 +5 3 6 3 4 -1563.11454558 -534.27105629 -6.64143185 +5 3 6 3 5 -71893.03914912 -71890.90746373 -74117.05114757 +5 3 6 3 6 71886.49412515 71886.21561349 74133.84754296 +5 3 6 3 7 -3064.48519893 -3064.43163900 -9458.98432692 +5 3 6 3 8 3071.12663078 3070.84811912 9448.22949211 +5 1 7 1 1 -0.12854384 0.06427192 -0.77126305 +5 1 7 1 2 -0.77126305 2.42090903 890.08041160 +5 1 7 1 3 0.10711987 -0.12854384 -0.98550279 +5 1 7 1 4 0.76055107 -2.37806108 889.82332391 +5 1 7 1 5 0.62129524 0.59987126 -4.90608998 +5 1 7 1 6 -0.83553497 -2.22809327 -886.52403196 +5 1 7 1 7 -0.64271921 -0.68556716 -2.32450115 +5 1 7 1 8 0.81411100 2.39948506 -884.39234658 +5 1 7 2 1 -0.08569589 -0.05355993 -3374.52223442 +5 1 7 2 2 537.95597976 534.74238371 91.58748759 +5 1 7 2 3 0.07498391 0.06427192 -2915.86709333 +5 1 7 2 4 -537.92384380 -534.74238371 93.70846099 +5 1 7 2 5 0.65343120 -0.55702332 2950.74532253 +5 1 7 2 6 533.99254463 -537.27041260 101.93526689 +5 1 7 2 7 -0.59987126 0.64271921 2950.69176259 +5 1 7 2 8 -534.05681655 537.23827664 102.05309875 +5 1 7 3 1 0.38563153 -2914.59236690 0.18210378 +5 1 7 3 2 -1558.95829468 3078.60359761 -3060.97166725 +5 1 7 3 3 0.32135961 -574.37673506 0.17139179 +5 1 7 3 4 -1558.94758269 3078.60359761 3060.92881930 +5 1 7 3 5 11.74033759 -11775.06585237 0.77126305 +5 1 7 3 6 1555.18767531 3076.61116805 3068.55575394 +5 1 7 3 7 -4.79897011 2953.48759116 0.85695895 +5 1 7 3 8 1555.12340339 3076.76113587 -3070.80527118 +5 2 7 1 1 -0.06427192 -0.09640788 -2915.96350122 +5 2 7 1 2 -534.69953576 -537.97740374 91.35182388 +5 2 7 1 3 0.05355993 0.08569589 -3374.53294641 +5 2 7 1 4 534.78523165 537.99882771 93.40852536 +5 2 7 1 5 0.56773530 -0.62129524 2950.78817047 +5 2 7 1 6 -537.29183658 534.03539257 101.89241895 +5 2 7 1 7 -0.62129524 0.67485517 2950.67033862 +5 2 7 1 8 537.33468452 -533.96040867 102.01025080 +5 2 7 2 1 -0.08569589 0.16067980 -0.97479080 +5 2 7 2 2 -2.39948506 0.77126305 890.27322736 +5 2 7 2 3 0.11783186 -0.04284795 -0.77126305 +5 2 7 2 4 2.37806108 -0.66414318 890.16610749 +5 2 7 2 5 0.66414318 0.64271921 -4.92751395 +5 2 7 2 6 -2.39948506 -0.77126305 -886.43833607 +5 2 7 2 7 -0.53559934 -0.68556716 -2.41019704 +5 2 7 2 8 2.39948506 0.74983908 -884.39234658 +5 2 7 3 1 -574.50527891 0.34278358 0.17139179 +5 2 7 3 2 3078.51790171 -1558.95829468 3060.99309122 +5 2 7 3 3 -2914.61379087 0.42847947 0.08569589 +5 2 7 3 4 3078.57146165 -1558.87259878 -3060.97166725 +5 2 7 3 5 -11775.08727634 11.74033759 0.85695895 +5 2 7 3 6 3076.71828792 1555.14482736 3068.59860189 +5 2 7 3 7 2953.40189527 -4.77754614 0.87838292 +5 2 7 3 8 3076.80398381 1555.13411537 -3070.77313522 +5 3 7 1 1 -0.66414318 -574.54812685 0.23566371 +5 3 7 1 2 -1556.28029797 3074.74728234 3062.49276938 +5 3 7 1 3 -1.67106995 -2914.36741517 0.21423974 +5 3 7 1 4 -1556.21602604 3074.83297823 -3062.68558514 +5 3 7 1 5 -4.23123481 2952.11645684 0.83553497 +5 3 7 1 6 1557.90851997 3080.51033127 -3066.84183604 +5 3 7 1 7 3.27786798 -11773.74827799 0.84624696 +5 3 7 1 8 1557.88709599 3080.63887511 3064.72086264 +5 3 7 2 1 -2914.41026312 -1.83174975 0.23566371 +5 3 7 2 2 3074.68301042 -1556.25887399 -3062.62131322 +5 3 7 2 3 -574.67667069 -0.70699113 0.12854384 +5 3 7 2 4 3074.69372240 -1556.21602604 3062.34280156 +5 3 7 2 5 2952.10574486 -4.13482693 0.89980690 +5 3 7 2 6 3080.57460319 1557.92994394 -3066.92753194 +5 3 7 2 7 -11773.71614203 3.32071592 0.94265484 +5 3 7 2 8 3080.55317921 1557.96207990 3064.77442258 +5 3 7 3 1 -0.21423974 0.16067980 -3.01006831 +5 3 7 3 2 3.10647619 -3.14932413 9467.72530819 +5 3 7 3 3 0.16067980 -0.23566371 -2.84938850 +5 3 7 3 4 -3.13861215 3.12790016 9467.55391640 +5 3 7 3 5 1.24259047 1.28543842 -13.28286370 +5 3 7 3 6 3.08505221 3.08505221 -9459.36995844 +5 3 7 3 7 -1.19974253 -1.19974253 -1.88530969 +5 3 7 3 8 -3.10647619 -3.01006831 -9455.16014761 +5 1 8 1 1 0.29993563 -1552.85246217 534.90306351 +5 1 8 1 2 -9463.14057781 -3055.46570600 3062.19283375 +5 1 8 1 3 9459.61633414 3053.30188466 -3057.77949516 +5 1 8 1 4 0.66414318 1552.59537449 -531.55021162 +5 1 8 1 5 73992.54572438 71806.34703952 -71878.82434256 +5 1 8 1 6 0.74983908 533.94969668 -1553.49518138 +5 1 8 1 7 0.77126305 -533.75688092 1555.30550716 +5 1 8 1 8 -73991.44238973 -71804.18321817 71869.36565817 +5 1 8 2 1 891.73005757 -3056.94396019 90.00211354 +5 1 8 2 2 3059.64338088 -889.53410027 -93.55849317 +5 1 8 2 3 0.16067980 -1558.27272752 3074.66158644 +5 1 8 2 4 1559.89023753 -0.83553497 -3077.46812700 +5 1 8 2 5 66823.24858731 71804.11894625 -80591.20460979 +5 1 8 2 6 -532.71781819 1.04977471 -3079.09634900 +5 1 8 2 7 2.97793235 537.58106022 3077.42527905 +5 1 8 2 8 -71804.91163328 -66837.13132227 80599.13148006 +5 1 8 3 1 -2.54945287 3071.42656641 537.67746810 +5 1 8 3 2 -3054.22311553 -87.21699696 -890.12325954 +5 1 8 3 3 -4.50974647 3074.70443439 -1558.20845560 +5 1 8 3 4 542.84064577 -3070.80527118 0.08569589 +5 1 8 3 5 -66915.05031464 -80608.23666889 71896.43484895 +5 1 8 3 6 -1554.41641225 -3080.96023471 -0.47132742 +5 1 8 3 7 -885.38856136 101.15329185 -3068.78070566 +5 1 8 3 8 71873.33980530 80600.00986299 -66916.57141678 +5 2 8 1 1 -1557.48004049 -0.55702332 3074.13669909 +5 2 8 1 2 -1.60679803 1560.71506052 -3078.04657429 +5 2 8 1 3 -3056.10842521 890.85167465 90.53771288 +5 2 8 1 4 -890.38034723 3060.41464393 -93.06574178 +5 2 8 1 5 71806.51843131 66820.70984643 -80591.14033787 +5 2 8 1 6 0.78197504 -532.42859455 -3079.13919695 +5 2 8 1 7 537.78458797 2.71013267 3077.41456707 +5 2 8 1 8 -66839.56294329 -71802.41574034 80599.13148006 +5 2 8 2 1 3052.48777366 9460.41973315 -3057.34030370 +5 2 8 2 2 1552.57395051 0.66414318 -531.61448355 +5 2 8 2 3 -1553.69870913 1.13547061 534.35675218 +5 2 8 2 4 -3055.44428203 -9463.16200179 3062.19283375 +5 2 8 2 5 71806.12208779 73992.68498021 -71878.86719051 +5 2 8 2 6 533.92827271 0.72841511 -1553.49518138 +5 2 8 2 7 -534.01396860 1.06048670 1555.32693114 +5 2 8 2 8 -71801.91227696 -73993.55265114 71869.18355440 +5 2 8 3 1 3073.37614802 -2.74226863 -1556.89088122 +5 2 8 3 2 -3070.76242323 542.81922179 0.07498391 +5 2 8 3 3 3071.64080615 -2.22809327 537.84885989 +5 2 8 3 4 -87.23842093 -3054.24453950 -890.08041160 +5 2 8 3 5 -80607.18689418 -66913.32568476 71895.51361808 +5 2 8 3 6 -3080.93881074 -1554.39498828 -0.47132742 +5 2 8 3 7 100.94976410 -885.04577778 -3068.96280944 +5 2 8 3 8 80600.09555888 71869.11928247 -66916.71067260 +5 3 8 1 1 -539.28426613 3069.38057693 -0.37491954 +5 3 8 1 2 5.84874482 -3077.11463143 1554.90916365 +5 3 8 1 3 3053.63395625 86.57427775 891.30157810 +5 3 8 1 4 3.77061937 -3073.14048431 -539.66989766 +5 3 8 1 5 -71877.63531202 -80588.44091718 66910.15493665 +5 3 8 1 6 883.57823558 -109.71216935 3072.58346099 +5 3 8 1 7 1558.20845560 3080.87453882 -2.54945287 +5 3 8 1 8 66911.91170249 80611.54667283 -71886.24774945 +5 3 8 2 1 86.57427775 3053.65538023 891.34442605 +5 3 8 2 2 -3073.16190828 3.58851560 -539.77701753 +5 3 8 2 3 3069.42342487 -539.28426613 -0.29993563 +5 3 8 2 4 -3076.52547216 4.92751395 1554.28786841 +5 3 8 2 5 -80588.40878122 -71875.54647459 66910.24063255 +5 3 8 2 6 -109.64789743 883.37470783 3072.66915689 +5 3 8 2 7 3080.89596279 1558.16560765 -2.57087684 +5 3 8 2 8 80610.91466560 66911.06545553 -71885.70143812 +5 3 8 3 1 -536.75623723 -1559.35463819 3.94201116 +5 3 8 3 2 1563.15739352 534.28176827 -6.59858390 +5 3 8 3 3 -1560.15803721 -535.98497418 3.40641182 +5 3 8 3 4 533.47836926 1563.90723260 -6.17010443 +5 3 8 3 5 71893.06057309 71891.14312744 -74116.75121194 +5 3 8 3 6 -3071.10520681 -3070.80527118 9448.22949211 +5 3 8 3 7 3064.97795033 3065.21361404 -9458.15950393 +5 3 8 3 8 -71886.55839707 -71888.36872285 74131.80155347 +6 1 1 1 1 74113.83755151 -72001.92649548 72006.23271419 +6 1 1 1 2 0.49275140 -1558.28343951 535.74931047 +6 1 1 1 3 -0.62129524 537.95597976 -1559.68670978 +6 1 1 1 4 -9472.03152690 3065.23503801 -3066.41335657 +6 1 1 1 5 -0.95336683 1557.77997612 -539.79844150 +6 1 1 1 6 -74107.15327172 71997.17037332 -71995.04939992 +6 1 1 1 7 9466.41844579 -3061.80720222 3061.16448301 +6 1 1 1 8 -0.02142397 -536.08138206 1557.85496003 +6 1 1 2 1 -72004.34740451 67024.50539631 -80796.18919021 +6 1 1 2 2 889.35199649 3066.01701305 -95.09030729 +6 1 1 2 3 -537.75245201 0.34278358 3077.44670303 +6 1 1 2 4 1.77818982 1561.95765100 -3081.64580187 +6 1 1 2 5 1553.42019748 0.21423974 3070.14112799 +6 1 1 2 6 67035.67799859 -72006.46837791 80811.55017936 +6 1 1 2 7 3061.33587480 889.93044378 90.86978447 +6 1 1 2 8 0.57844729 -536.67054134 -3076.99679958 +6 1 1 3 1 72007.83951222 -80795.30009530 67033.78197692 +6 1 1 3 2 -1.39255829 -3078.06799826 -538.18093149 +6 1 1 3 3 -1558.04777580 3077.53239892 0.27851166 +6 1 1 3 4 -2.86010049 -3080.14612371 1557.13725691 +6 1 1 3 5 536.22063789 3076.67543997 1.88530969 +6 1 1 3 6 -67028.31886363 80799.95980959 -72006.42552996 +6 1 1 3 7 -3061.97859401 91.88742323 890.48746710 +6 1 1 3 8 -891.51581784 -92.55156641 3061.18590698 +6 2 1 1 1 -67017.46762094 72015.89492634 -80796.97116525 +6 2 1 1 2 -1561.78625921 -1.85317373 -3081.82790565 +6 2 1 1 3 -0.57844729 538.57727500 3077.33958316 +6 2 1 1 4 -3065.10649417 -888.70927728 -95.70089055 +6 2 1 1 5 -891.71934559 -3053.55897234 86.16722225 +6 2 1 1 6 71999.35561863 -67052.19588232 80811.67872320 +6 2 1 1 7 0.44990345 -1557.58716036 3076.32194441 +6 2 1 1 8 536.88478108 -0.51417537 -3076.93252766 +6 2 1 2 1 72011.80294736 -74112.61638501 72011.03168430 +6 2 1 2 2 -3064.61374278 9472.93133380 -3065.78134934 +6 2 1 2 3 -537.46322837 -0.70699113 -1558.44411931 +6 2 1 2 4 1558.21916759 -0.34278358 535.87785431 +6 2 1 2 5 3056.94396019 -9458.51299949 3054.97295461 +6 2 1 2 6 -72002.16215919 74100.51183987 -71998.43438777 +6 2 1 2 7 -1558.82975084 -1.47825419 -537.10973280 +6 2 1 2 8 536.13494200 0.16067980 1557.81211209 +6 2 1 3 1 -80798.84576295 72015.87350236 -67033.67485705 +6 2 1 3 2 -3080.18897166 -2.88152446 -1557.11583294 +6 2 1 3 3 3077.13605541 -1559.92237350 -0.25708768 +6 2 1 3 4 -3078.10013422 -1.41398226 538.17021950 +6 2 1 3 5 89.61648201 -3058.44363835 -892.09426513 +6 2 1 3 6 80806.74049726 -67036.98486099 72006.25413817 +6 2 1 3 7 3076.16126460 535.37439093 -0.02142397 +6 2 1 3 8 -92.57299038 -891.53724181 -3061.19661897 +6 3 1 1 1 67029.91494967 -80801.69515146 72004.17601272 +6 3 1 1 2 -540.07695316 -3079.37486066 -0.85695895 +6 3 1 1 3 888.90209304 90.36632109 -3062.66416117 +6 3 1 1 4 3063.45684820 -93.02289383 -888.81639715 +6 3 1 1 5 -2.19595730 3073.89032339 536.15636597 +6 3 1 1 6 -71997.19179729 80810.32901286 -67028.00821601 +6 3 1 1 7 -0.51417537 3076.69686395 -1559.55816594 +6 3 1 1 8 1557.71570420 -3077.29673521 -0.34278358 +6 3 1 2 1 -80804.71593175 67032.88217003 -72004.62591617 +6 3 1 2 2 -92.80865410 3063.38186429 888.76283721 +6 3 1 2 3 90.61269679 889.00921291 3062.72843309 +6 3 1 2 4 -3078.46434178 -539.45565792 0.19281576 +6 3 1 2 5 3072.49776510 -1.86388571 1561.55059550 +6 3 1 2 6 80813.09270547 -72002.07646330 67026.70135361 +6 3 1 2 7 3076.97537560 0.19281576 -535.59934265 +6 3 1 2 8 -3077.12534342 1557.80140010 0.42847947 +6 3 1 3 1 71999.93406592 -71999.81623407 74099.97624053 +6 3 1 3 2 536.34918173 -1559.29036627 2.34592512 +6 3 1 3 3 3062.88911289 -3062.70700912 9469.33210622 +6 3 1 3 4 1559.34392621 -536.30633379 2.33521313 +6 3 1 3 5 -537.06688485 1558.74405494 3.72777142 +6 3 1 3 6 -72001.54086395 72000.79102487 -74115.23010981 +6 3 1 3 7 -1558.61551110 537.17400472 2.88152446 +6 3 1 3 8 -3061.33587480 3061.33587480 -9465.43294300 +6 1 2 1 1 0.14996782 886.35264017 -1.09262266 +6 1 2 1 2 0.17139179 2.39948506 8.77311723 +6 1 2 1 3 -0.25708768 -886.41691209 -1.02835074 +6 1 2 1 4 0.13925583 -0.00000000 -0.36420755 +6 1 2 1 5 -0.40705550 891.28015412 3.25644400 +6 1 2 1 6 0.13925583 -2.29236519 -8.82667717 +6 1 2 1 7 -0.12854384 -891.36585002 -1.09262266 +6 1 2 1 8 0.12854384 0.08569589 0.29993563 +6 1 2 2 1 -1558.50839123 3063.32830435 -3078.06799826 +6 1 2 2 2 1.82103777 4.73469819 -2955.21222105 +6 1 2 2 3 1558.67978302 -3063.28545641 -3078.11084621 +6 1 2 2 4 -0.66414318 -0.06427192 573.69116790 +6 1 2 2 5 -1552.65964641 -3060.80027546 -3072.41206920 +6 1 2 2 6 -6.35220820 0.70699113 11771.70228850 +6 1 2 2 7 1557.65143228 3055.29431421 -3075.62566526 +6 1 2 2 8 0.06427192 0.11783186 2914.09961550 +6 1 2 3 1 535.49222279 -92.25163078 -538.25591539 +6 1 2 3 2 6.34149622 -2959.42203188 -1.27472644 +6 1 2 3 3 535.57791868 -94.50114802 538.08452360 +6 1 2 3 4 -0.18210378 2914.83874260 -1.07119869 +6 1 2 3 5 -531.85014726 -91.52321567 539.58420176 +6 1 2 3 6 -7.61622265 -2962.63562793 -0.38563153 +6 1 2 3 7 -538.77009076 -88.52385935 -536.00639816 +6 1 2 3 8 0.92123087 3373.89022720 -0.63200722 +6 2 2 1 1 -1561.14354000 -3065.92060517 -3079.61052437 +6 2 2 1 2 6.34149622 0.83553497 11784.49240080 +6 2 2 1 3 1561.16496397 3065.96345312 -3079.56767642 +6 2 2 1 4 -0.13925583 0.08569589 2915.24579810 +6 2 2 1 5 -1560.30800502 3053.53754837 -3077.08249547 +6 2 2 1 6 -1.69249392 4.64900229 -2964.13530609 +6 2 2 1 7 1555.20909928 -3059.30059730 -3074.14741108 +6 2 2 1 8 0.70699113 -0.11783186 574.59097480 +6 2 2 2 1 -0.36420755 9473.85256467 -1.99242955 +6 2 2 2 2 -0.68556716 -4.01699507 6.33078423 +6 2 2 2 3 0.44990345 -9471.66731935 -1.88530969 +6 2 2 2 4 -0.66414318 -0.02142397 -0.23566371 +6 2 2 2 5 1.15689458 9463.50478537 5.74162495 +6 2 2 2 6 0.51417537 2.16382134 -6.27722430 +6 2 2 2 7 0.51417537 -9463.48336139 -1.99242955 +6 2 2 2 8 -0.81411100 -0.31064762 0.29993563 +6 2 2 3 1 -3080.68172306 -3067.16319565 -1556.43026578 +6 2 2 3 2 11785.79926320 7.56266272 -2.91366042 +6 2 2 3 3 -3080.70314703 -3069.36986494 1556.28029797 +6 2 2 3 4 573.11272061 -0.32135961 -1.13547061 +6 2 2 3 5 -3078.08942224 3062.57846527 -1554.60922802 +6 2 2 3 6 -2962.35711628 7.47696682 -0.19281576 +6 2 2 3 7 -3072.96909252 3057.82234311 1559.83667760 +6 2 2 3 8 2915.93136525 1.29615041 -0.76055107 +6 3 2 1 1 -539.07002640 -90.75195262 536.56342147 +6 3 2 1 2 6.47004006 -2961.05025388 -0.42847947 +6 3 2 1 3 -538.98433050 -90.88049646 -536.54199750 +6 3 2 1 4 -0.78197504 3371.83352572 -0.62129524 +6 3 2 1 5 542.24077450 -87.02418119 -534.18536039 +6 3 2 1 6 -5.08819376 -2964.28527391 -1.26401445 +6 3 2 1 7 535.19228715 -92.16593488 537.72031605 +6 3 2 1 8 0.04284795 2914.21744736 -1.08191067 +6 3 2 2 1 -3078.13227018 3061.57153851 -1558.97971865 +6 3 2 2 2 -2959.55057572 -3.88845123 1.52110213 +6 3 2 2 3 -3078.11084621 3061.48584261 1558.93687070 +6 3 2 2 4 2913.72469596 -0.53559934 0.96407882 +6 3 2 2 5 -3070.33394376 -3054.39450732 -1562.53609829 +6 3 2 2 6 11772.94487897 -3.98485911 1.60679803 +6 3 2 2 7 -3075.47569744 -3061.44299467 1557.33007268 +6 3 2 2 8 574.69809467 1.08191067 1.01763875 +6 3 2 3 1 0.10711987 885.32428943 2.57087684 +6 3 2 3 2 -1.22116650 1.61751001 -3.87773924 +6 3 2 3 3 -0.12854384 -885.40998533 2.48518095 +6 3 2 3 4 0.97479080 -0.47132742 -1.90673366 +6 3 2 3 5 -0.47132742 890.10183557 -7.32699901 +6 3 2 3 6 0.07498391 0.19281576 3.94201116 +6 3 2 3 7 -0.21423974 -892.26565692 2.42090903 +6 3 2 3 8 0.74983908 0.86767094 1.98171757 +6 1 3 1 1 -0.87838292 -537.30254856 -1558.04777580 +6 1 3 1 2 -0.14996782 1558.30486348 536.01711014 +6 1 3 1 3 -74115.85140504 72014.97369547 72011.54585967 +6 1 3 1 4 9472.87777386 -3064.69943867 -3065.55639762 +6 1 3 1 5 -9460.51614104 3056.00130535 3053.43042850 +6 1 3 1 6 74104.26103527 -72005.99705048 -71997.49173292 +6 1 3 1 7 -0.49275140 -1556.81589731 -538.58798699 +6 1 3 1 8 0.85695895 535.47079881 1558.76547892 +6 1 3 2 1 538.57727500 -0.53559934 3077.28602322 +6 1 3 2 2 -889.24487662 -3065.89918120 -94.94033948 +6 1 3 2 3 72016.10916607 -67015.60373523 -80799.33851435 +6 1 3 2 4 -1.82103777 -1562.04334689 -3081.53868200 +6 1 3 2 5 -3053.55897234 -891.70863360 86.21007019 +6 1 3 2 6 -67052.36727411 71999.33419466 80812.21432255 +6 1 3 2 7 -1557.60858433 0.46061543 3076.39692831 +6 1 3 2 8 0.02142397 536.01711014 -3076.11841666 +6 1 3 3 1 -1559.77240568 3077.32887117 -0.17139179 +6 1 3 3 2 -1.39255829 -3078.07871025 538.40588321 +6 1 3 3 3 72015.19864719 -80797.75314029 -67035.14239925 +6 1 3 3 4 -2.93508440 -3080.21039563 -1556.92301718 +6 1 3 3 5 -3058.52933424 89.85214572 -892.13711307 +6 1 3 3 6 -67037.62758020 80805.05871533 72006.91828135 +6 1 3 3 7 536.04924610 3077.13605541 -0.62129524 +6 1 3 3 8 -890.83025068 -93.24784556 -3060.23254015 +6 2 3 1 1 0.19281576 -537.87028387 3077.59667084 +6 2 3 1 2 1561.91480305 1.73534187 -3081.77434571 +6 2 3 1 3 67023.36992570 -72003.36190172 -80795.28938332 +6 2 3 1 4 3066.00630107 889.37342047 -95.07959531 +6 2 3 1 5 -0.65343120 1552.78819025 3069.58410468 +6 2 3 1 6 -72004.07960484 67035.39948694 80811.31451565 +6 2 3 1 7 889.78047597 3061.44299467 90.73052865 +6 2 3 1 8 -536.64911737 0.59987126 -3077.00751156 +6 2 3 2 1 538.02025168 -0.68556716 -1559.64386184 +6 2 3 2 2 3064.65659072 -9472.86706188 -3065.59924557 +6 2 3 2 3 -72001.80866362 74115.74428517 72003.72610927 +6 2 3 2 4 -1558.27272752 0.19281576 536.02782213 +6 2 3 2 5 1557.71570420 -0.98550279 -539.84128945 +6 2 3 2 6 71996.88114967 -74107.15327172 -71994.57807250 +6 2 3 2 7 -3061.87147414 9466.45058175 3061.14305904 +6 2 3 2 8 -535.47079881 -0.83553497 1558.78690289 +6 2 3 3 1 3076.99679958 -1558.28343951 0.49275140 +6 2 3 3 2 -3080.36036345 -2.81725254 1556.80518532 +6 2 3 3 3 -80795.66430286 72009.53200615 67037.97036378 +6 2 3 3 4 -3078.92495721 -1.99242955 -539.02717845 +6 2 3 3 5 3073.98673127 534.33532821 -0.00000000 +6 2 3 3 6 80806.00137017 -67027.96536806 -72006.76831354 +6 2 3 3 7 91.39467183 -3061.70008235 890.16610749 +6 2 3 3 8 -93.42994933 -890.94808253 3060.32894803 +6 3 3 1 1 888.40934165 91.44823176 3061.93574606 +6 3 3 1 2 -539.88413740 -3079.44984457 0.89980690 +6 3 3 1 3 67030.78262060 -80802.25217477 -72004.92585180 +6 3 3 1 4 3064.35665509 -92.35875065 889.48054033 +6 3 3 1 5 -1.83174975 3072.77627676 1561.29350781 +6 3 3 1 6 -72000.46966527 80809.45062994 67027.53688859 +6 3 3 1 7 0.74983908 3077.80019859 -536.42416564 +6 3 3 1 8 1557.86567202 -3077.22175130 0.24637570 +6 3 3 2 1 91.00904030 888.22723787 -3061.72150633 +6 3 3 2 2 -92.80865410 3063.37115230 -888.78426119 +6 3 3 2 3 -80804.21246837 67030.08634146 72004.66876411 +6 3 3 2 4 -3078.46434178 -539.41280997 -0.17139179 +6 3 3 2 5 3073.79391551 -2.31378916 536.32775776 +6 3 3 2 6 80810.86461220 -71997.42746100 -67030.32200517 +6 3 3 2 7 3076.78255984 -0.37491954 -1559.40819813 +6 3 3 2 8 -3077.08249547 1557.77997612 -0.41776749 +6 3 3 3 1 -3062.42849746 3063.36044031 9469.44993807 +6 3 3 3 2 -536.30633379 1559.32250223 2.37806108 +6 3 3 3 3 -72000.33040944 72001.32662422 74100.83319948 +6 3 3 3 4 -1559.31179024 536.30633379 2.31378916 +6 3 3 3 5 1559.47247005 -536.04924610 4.15625090 +6 3 3 3 6 71998.75574737 -72005.97562651 -74115.16583788 +6 3 3 3 7 538.66297089 -1556.82660929 1.63893399 +6 3 3 3 8 3061.33587480 -3061.34658679 -9465.37938307 +6 1 4 1 1 -9471.60304743 0.40705550 -2.03527750 +6 1 4 1 2 0.14996782 -0.62129524 -0.07498391 +6 1 4 1 3 9473.91683659 -0.40705550 -1.88530969 +6 1 4 1 4 -3.07434023 -1.43540624 6.87709556 +6 1 4 1 5 9463.41908947 1.26401445 5.82732085 +6 1 4 1 6 3.12790016 1.30686240 -6.85567159 +6 1 4 1 7 -9465.73287863 0.42847947 -2.03527750 +6 1 4 1 8 -0.10711987 -0.95336683 0.19281576 +6 1 4 2 1 3066.00630107 1561.10069205 -3079.50340450 +6 1 4 2 2 -0.08569589 -0.05355993 2915.09583028 +6 1 4 2 3 -3063.82105575 -1561.12211602 -3079.52482848 +6 1 4 2 4 -0.03213596 5.76304893 11783.78540967 +6 1 4 2 5 3053.64466824 -1560.37227694 -3077.03964753 +6 1 4 2 6 3.79204335 -1.11404663 -2963.51401086 +6 1 4 2 7 -3059.21490140 1555.18767531 -3074.08313915 +6 1 4 2 8 -0.21423974 0.61058325 574.69809467 +6 1 4 3 1 -3065.02079828 -3080.63887511 1556.40884181 +6 1 4 3 2 -0.49275140 573.36980830 -0.94265484 +6 1 4 3 3 -3067.18461962 -3080.70314703 -1556.36599386 +6 1 4 3 4 6.69499178 11783.80683364 -0.98550279 +6 1 4 3 5 3062.64273719 -3078.04657429 -1554.69492391 +6 1 4 3 6 6.63071986 -2960.45038262 -2.07812545 +6 1 4 3 7 3055.57282587 -3072.92624457 1559.90094952 +6 1 4 3 8 1.15689458 2915.63142962 -1.06048670 +6 2 4 1 1 -3065.47070172 1558.52981520 -3078.11084621 +6 2 4 1 2 -0.36420755 -0.83553497 573.34838433 +6 2 4 1 3 3065.38500583 -1558.46554328 -3078.02515032 +6 2 4 1 4 2.83867652 3.06362824 -2957.81523385 +6 2 4 1 5 -3060.86454738 -1552.59537449 -3072.75485278 +6 2 4 1 6 -0.93194286 -7.69120656 11774.29458932 +6 2 4 1 7 3059.60053293 1557.73712818 -3075.58281731 +6 2 4 1 8 -0.21423974 0.27851166 2914.35670319 +6 2 4 2 1 -886.37406415 -0.14996782 -1.22116650 +6 2 4 2 2 -0.08569589 0.09640788 -0.26779967 +6 2 4 2 3 886.35264017 0.10711987 -1.11404663 +6 2 4 2 4 2.36734909 0.21423974 8.76240525 +6 2 4 2 5 891.21588220 -0.47132742 3.29929195 +6 2 4 2 6 -2.32450115 0.23566371 -8.80525319 +6 2 4 2 7 -891.25873015 -0.17139179 -1.00692676 +6 2 4 2 8 0.08569589 0.07498391 0.27851166 +6 2 4 3 1 -96.62212141 535.49222279 538.29876334 +6 2 4 3 2 2915.35291796 -0.07498391 -1.41398226 +6 2 4 3 3 -92.25163078 535.49222279 -538.34161129 +6 2 4 3 4 -2956.61549132 5.80589687 -3.23502003 +6 2 4 3 5 -95.85085836 -531.78587534 539.45565792 +6 2 4 3 6 -2959.88264731 -7.04848735 1.47825419 +6 2 4 3 7 -88.45958743 -538.77009076 -536.02782213 +6 2 4 3 8 3374.40440257 0.86767094 -0.29993563 +6 3 4 1 1 3061.50726659 -3078.17511813 1558.95829468 +6 3 4 1 2 -0.96407882 2913.74611994 0.69627915 +6 3 4 1 3 3063.73535985 -3078.06799826 -1558.89402276 +6 3 4 1 4 -5.72020098 -2959.44345585 -1.00692676 +6 3 4 1 5 -3056.57975264 -3070.26967183 -1562.62179418 +6 3 4 1 6 -5.83803283 11772.90203103 4.11340295 +6 3 4 1 7 -3056.92253622 -3075.51854539 1557.35149665 +6 3 4 1 8 0.70699113 574.76236659 1.43540624 +6 3 4 2 1 -90.75195262 -539.04860242 -536.49914955 +6 3 4 2 2 3371.42647022 -0.93194286 -0.61058325 +6 3 4 2 3 -90.75195262 -539.02717845 536.71338929 +6 3 4 2 4 -2962.88200363 7.66978259 -0.53559934 +6 3 4 2 5 -84.83893588 542.26219848 -534.18536039 +6 3 4 2 6 -2966.17058360 -6.32007224 -1.28543842 +6 3 4 2 7 -90.00211354 535.23513510 537.82743592 +6 3 4 2 8 2913.85323981 0.23566371 -1.19974253 +6 3 4 3 1 -885.30286546 -0.10711987 2.42090903 +6 3 4 3 2 -0.77126305 0.97479080 -2.08883744 +6 3 4 3 3 887.53095873 0.17139179 2.48518095 +6 3 4 3 4 -0.21423974 -1.13547061 -3.81346732 +6 3 4 3 5 892.30850486 -0.47132742 -7.45554285 +6 3 4 3 6 -1.61751001 0.12854384 3.92058719 +6 3 4 3 7 -892.28708089 -0.17139179 2.44233300 +6 3 4 3 8 0.42847947 0.79268703 1.96029359 +6 1 5 1 1 -0.87838292 1553.68799715 534.31390423 +6 1 5 1 2 -0.64271921 -1552.60608647 -531.60377156 +6 1 5 1 3 -9459.57348619 -3053.10906890 -3057.90803901 +6 1 5 1 4 9463.14057781 3055.44428203 3062.17140977 +6 1 5 1 5 -73991.75303735 -71805.36153673 -71877.94595964 +6 1 5 1 6 73991.22814999 71801.93370093 71869.20497837 +6 1 5 1 7 -0.89980690 533.93898469 1555.42333902 +6 1 5 1 8 -0.70699113 -533.93898469 -1553.49518138 +6 1 5 2 1 1558.37984739 -0.21423974 3074.67229843 +6 1 5 2 2 889.58766020 -3059.58982094 -93.55849317 +6 1 5 2 3 3056.93324820 -891.81575347 90.04496149 +6 1 5 2 4 0.81411100 -1559.85810157 -3077.48955097 +6 1 5 2 5 -71803.86185857 -66823.04505956 -80590.94752211 +6 1 5 2 6 66836.87423459 71804.78308944 80598.87439238 +6 1 5 2 7 -537.57034824 -2.94579638 3077.39314309 +6 1 5 2 8 -1.04977471 532.70710620 -3079.16062092 +6 1 5 3 1 -539.11287434 3069.48769679 0.32135961 +6 1 5 3 2 3.79204335 -3073.15119630 539.62704971 +6 1 5 3 3 3054.56589911 85.93155854 -892.00856923 +6 1 5 3 4 5.83803283 -3077.14676739 -1554.97343557 +6 1 5 3 5 -71877.08900069 -80588.14098155 -66909.68360923 +6 1 5 3 6 66910.07995274 80611.85732045 71886.68694091 +6 1 5 3 7 1558.37984739 3080.79955491 2.63514877 +6 1 5 3 8 883.56752359 -109.74430531 -3072.59417298 +6 2 5 1 1 -890.91594657 3056.14056118 90.54842487 +6 2 5 1 2 -1560.11518926 0.74983908 -3077.40385508 +6 2 5 1 3 0.61058325 1557.50146447 3074.06171518 +6 2 5 1 4 -3060.48962784 890.18753147 -92.89434999 +6 2 5 1 5 -66820.81696630 -71804.46172983 -80591.11891390 +6 2 5 1 6 71801.78373312 66838.74883229 80598.74584854 +6 2 5 1 7 -2.72084466 -537.81672393 3077.43599104 +6 2 5 1 8 532.53571441 -0.95336683 -3079.24631682 +6 2 5 2 1 -3053.30188466 -9459.64847010 -3057.79020715 +6 2 5 2 2 3055.46570600 9463.12986583 3062.20354573 +6 2 5 2 3 1552.85246217 -0.25708768 534.91377550 +6 2 5 2 4 -1552.61679846 -0.64271921 -531.63590752 +6 2 5 2 5 -71806.62555117 -73992.68498021 -71879.01715833 +6 2 5 2 6 71804.30105003 73991.54950960 71869.63345784 +6 2 5 2 7 533.75688092 -0.81411100 1555.32693114 +6 2 5 2 8 -533.94969668 -0.70699113 -1553.49518138 +6 2 5 3 1 86.42430993 3053.54826036 -891.22659419 +6 2 5 3 2 -3076.28980845 4.97036190 -1554.36285232 +6 2 5 3 3 3068.44863407 -538.68439487 0.94265484 +6 2 5 3 4 -3072.30494934 2.95650837 539.17714626 +6 2 5 3 5 -80591.60095331 -71876.12492188 -66910.66911202 +6 2 5 3 6 80614.12826166 66911.76173468 71886.42985323 +6 2 5 3 7 3080.70314703 1558.29415149 2.47446896 +6 2 5 3 8 -109.49792961 883.28901193 -3072.56203702 +6 3 5 1 1 -3.87773924 3073.26902815 -538.97361851 +6 3 5 1 2 542.84064577 -3070.80527118 -0.04284795 +6 3 5 1 3 -4.34906666 3075.02579400 1558.05848778 +6 3 5 1 4 -3054.26596348 -87.23842093 890.16610749 +6 3 5 1 5 -66913.88270808 -80606.67271881 -71895.51361808 +6 3 5 1 6 71873.55404503 80595.83218811 66916.83921645 +6 3 5 1 7 -885.58137712 101.47465146 3069.01636937 +6 3 5 1 8 -1554.41641225 -3080.92809875 0.49275140 +6 3 5 2 1 3073.91174736 -3.68492348 1557.70499222 +6 3 5 2 2 -87.21699696 -3054.24453950 890.14468352 +6 3 5 2 3 3070.64459137 -1.75676584 -537.09902081 +6 3 5 2 4 -3070.79455919 542.81922179 -0.04284795 +6 3 5 2 5 -80608.42948465 -66914.67539510 -71896.45627292 +6 3 5 2 6 80602.07727645 71871.11171203 66916.53928081 +6 3 5 2 7 100.88549218 -885.18503361 3068.82355361 +6 3 5 2 8 -3080.93881074 -1554.38427629 0.47132742 +6 3 5 3 1 535.34225497 1561.00428417 2.81725254 +6 3 5 3 2 -533.45694528 -1563.89652062 -6.07369655 +6 3 5 3 3 1559.45104607 536.92762902 3.81346732 +6 3 5 3 4 -1563.13596955 -534.27105629 -6.53431198 +6 3 5 3 5 -71892.86775733 -71890.20047260 -74116.23703657 +6 3 5 3 6 71888.96859411 71884.39457573 74132.30501685 +6 3 5 3 7 -3065.29930993 -3064.78513457 -9458.09523201 +6 3 5 3 8 3071.21232668 3070.83740714 9448.26162808 +6 1 6 1 1 -74108.86718962 67033.99621666 -67027.94394409 +6 1 6 1 2 0.94265484 -7.85188636 -8.58030147 +6 1 6 1 3 74100.05122443 -67048.70377461 -67036.38498973 +6 1 6 1 4 3.67421149 3.17074811 5.16317766 +6 1 6 1 5 73986.62199565 66835.49238828 66912.55442171 +6 1 6 1 6 120.60625998 218.71734757 126.29432500 +6 1 6 1 7 -74102.76135711 -67030.26844523 67035.78511846 +6 1 6 1 8 -0.29993563 -4.61686633 -6.82353563 +6 1 6 2 1 71997.72739663 -72005.91135459 80806.21560991 +6 1 6 2 2 -3.70634745 1.02835074 -2960.10759904 +6 1 6 2 3 -72005.90064260 71997.66312471 80804.07321254 +6 1 6 2 4 -2.50660492 -0.59987126 -2960.06475109 +6 1 6 2 5 71805.62933640 71801.24813377 80611.08605739 +6 1 6 2 6 219.38149075 221.69527991 -328882.41972007 +6 1 6 2 7 -72008.63219925 -72012.83129810 80808.80791073 +6 1 6 2 8 -2.24951724 -2.37806108 11772.36643168 +6 1 6 3 1 -71994.25671289 80814.11034422 -72003.69397331 +6 1 6 3 2 -9.12661280 11771.12384121 -0.88909491 +6 1 6 3 3 -71997.77024458 80814.46383978 72003.19050993 +6 1 6 3 4 -7.32699901 -2964.62805749 -1.41398226 +6 1 6 3 5 71865.99138231 80595.68222030 71885.44435044 +6 1 6 3 6 126.64782056 -328878.02780546 115.13243470 +6 1 6 3 7 72010.58178086 80799.48848216 -72005.41860319 +6 1 6 3 8 5.09890574 -2952.14859281 7.96971822 +6 2 6 1 1 71997.98448432 -72006.48980188 80806.76192124 +6 2 6 1 2 -3.64207553 0.99621478 -2960.13973500 +6 2 6 1 3 -72005.86850664 71997.29891716 80803.90182075 +6 2 6 1 4 -2.47446896 -0.57844729 -2960.08617506 +6 2 6 1 5 71805.05088911 71800.43402277 80610.40049023 +6 2 6 1 6 219.60644248 223.98764510 -328882.22690430 +6 2 6 1 7 -72008.73931912 -72013.22764161 80809.01143848 +6 2 6 1 8 -2.29236519 -2.41019704 11772.27002380 +6 2 6 2 1 -67051.63885901 74101.29381491 -67037.45618841 +6 2 6 2 2 3.59922758 3.70634745 5.31314548 +6 2 6 2 3 67035.00314342 -74109.18854922 -67028.58666330 +6 2 6 2 4 -6.14868045 1.09262266 -7.28415106 +6 2 6 2 5 66839.43439945 73988.12167381 66914.09694781 +6 2 6 2 6 218.62093968 117.68188757 125.30882221 +6 2 6 2 7 -67034.73534375 -74102.69708519 67035.95651025 +6 2 6 2 8 -4.11340295 -0.34278358 -7.03777536 +6 2 6 3 1 80810.80034028 -71998.15587611 72003.28691781 +6 2 6 3 2 -2964.13530609 -7.68049457 -1.53181412 +6 2 6 3 3 80812.82490580 -71994.81373621 -72004.45452438 +6 2 6 3 4 11774.00536567 -7.19845517 -1.58537405 +6 2 6 3 5 80596.59273918 71866.76264537 71886.21561349 +6 2 6 3 6 -328878.56340480 124.62325505 115.75372993 +6 2 6 3 7 80800.32401714 72011.14951616 -72006.03989843 +6 2 6 3 8 -2951.62370545 5.37741740 8.05541411 +6 3 6 1 1 -71993.80680944 80814.76377542 -72003.28691781 +6 3 6 1 2 -8.95522101 11771.27380902 -0.73912709 +6 3 6 1 3 -71996.84901371 80814.72092747 72001.17665640 +6 3 6 1 4 -7.53052676 -2964.67090544 -1.24259047 +6 3 6 1 5 71869.04429857 80598.61730469 71888.22946702 +6 3 6 1 6 121.34538707 -328881.92696867 111.68317493 +6 3 6 1 7 72011.16022815 80800.04550548 -72004.90442782 +6 3 6 1 8 5.76304893 -2952.74846407 8.92308505 +6 3 6 2 1 80810.54325260 -71997.84522849 72003.58685344 +6 3 6 2 2 -2964.26384994 -7.83046239 -1.66035796 +6 3 6 2 3 80812.81419381 -71994.98512800 -72001.81937561 +6 3 6 2 4 11774.05892561 -7.06991132 -1.73534187 +6 3 6 2 5 80597.86746561 71868.09093174 71888.01522728 +6 3 6 2 6 -328877.37437426 124.04480776 110.18349677 +6 3 6 2 7 80798.52440335 72009.45702224 -72003.74753324 +6 3 6 2 8 -2952.30927261 6.09512052 7.20916715 +6 3 6 3 1 -67028.88659893 67027.62258448 -74118.59367368 +6 3 6 3 2 -1.15689458 3.41712381 3.37427586 +6 3 6 3 3 67026.88345739 -67030.23630927 -74119.04357713 +6 3 6 3 4 5.25958554 -1.58537405 4.49903448 +6 3 6 3 5 66910.30490447 66909.74788115 74140.36043096 +6 3 6 3 6 108.66239464 110.80479201 -4.97036190 +6 3 6 3 7 -67020.57409713 -67018.93516314 74089.93910885 +6 3 6 3 8 -0.53559934 -0.84624696 4.67042627 +6 1 7 1 1 9466.54698963 3061.53940255 -3062.02144196 +6 1 7 1 2 -0.32135961 1557.50146447 -538.84507467 +6 1 7 1 3 -1.54252611 -1556.58023360 536.17778994 +6 1 7 1 4 -9464.88663167 -3057.84376708 3056.60117661 +6 1 7 1 5 -1.51039015 -537.67746810 1557.05156102 +6 1 7 1 6 -74103.55404414 -72014.41667215 72011.99576312 +6 1 7 1 7 74104.92517845 72008.84643899 -72003.20122192 +6 1 7 1 8 0.19281576 538.52371507 -1557.84424805 +6 1 7 2 1 -3060.65030764 889.20202868 91.95169515 +6 1 7 2 2 -890.29465133 3057.07250403 -88.71667512 +6 1 7 2 3 -1557.69428023 1.24259047 3076.82540779 +6 1 7 2 4 0.97479080 1554.78061981 -3072.62630894 +6 1 7 2 5 533.77830489 -2.69942069 3080.03900384 +6 1 7 2 6 -67034.12476050 -72011.84579531 80799.93838561 +6 1 7 2 7 72008.20371978 67050.69620416 -80809.91124537 +6 1 7 2 8 -0.21423974 -538.32018732 -3077.42527905 +6 1 7 3 1 3060.37179598 91.28755196 889.26630060 +6 1 7 3 2 -1.13547061 -3075.53996937 -535.94212623 +6 1 7 3 3 -538.63083493 3076.54689613 -0.17139179 +6 1 7 3 4 -2.08883744 -3073.89032339 1559.83667760 +6 1 7 3 5 1553.95579682 3075.92560089 1.67106995 +6 1 7 3 6 67039.09512240 80805.25153109 -71999.59128235 +6 1 7 3 7 -72000.44824129 -80809.11855834 67022.12733523 +6 1 7 3 8 888.70927728 -90.38774507 3062.77128104 +6 2 7 1 1 1.24259047 -1557.94065593 3076.79327183 +6 2 7 1 2 1554.67349994 0.87838292 -3072.77627676 +6 2 7 1 3 889.84474789 -3061.44299467 91.33039991 +6 2 7 1 4 3056.18340912 -889.60908418 -89.33797035 +6 2 7 1 5 -2.62443678 533.54264118 3080.12469974 +6 2 7 1 6 -72012.83129810 -67032.50725049 80800.36686509 +6 2 7 1 7 67052.02449053 72007.28248891 -80809.11855834 +6 2 7 1 8 -538.51300308 -0.13925583 -3077.35029514 +6 2 7 2 1 -1558.42269534 -0.23566371 534.83879159 +6 2 7 2 2 -3057.97231093 -9464.96161558 3056.54761668 +6 2 7 2 3 3061.10021109 9466.39702182 -3062.10713785 +6 2 7 2 4 1556.60165757 0.32135961 -539.45565792 +6 2 7 2 5 -538.03096367 -1.37113432 1557.26580076 +6 2 7 2 6 -72011.13880417 -74104.51812295 72013.10980975 +6 2 7 2 7 72009.48915820 74104.06821950 -72002.17287118 +6 2 7 2 8 538.34161129 0.26779967 -1557.80140010 +6 2 7 3 1 3075.79705705 -537.82743592 -0.69627915 +6 2 7 3 2 -3074.14741108 -2.16382134 1559.78311767 +6 2 7 3 3 90.50557692 3061.27160288 889.86617186 +6 2 7 3 4 -3076.40764030 -0.57844729 -536.54199750 +6 2 7 3 5 3075.63637725 1554.20217252 1.67106995 +6 2 7 3 6 80806.34415375 67036.08505410 -71998.84144327 +6 2 7 3 7 -80807.22253667 -71999.84837003 67021.89167151 +6 2 7 3 8 -90.53771288 888.81639715 3062.85697693 +6 3 7 1 1 -1.24259047 3077.84304654 -1557.54431241 +6 3 7 1 2 534.95662344 -3075.06864194 0.04284795 +6 3 7 1 3 -0.22495172 3076.84683176 538.12737155 +6 3 7 1 4 -3059.61124492 -90.79480057 -890.89452260 +6 3 7 1 5 -885.96700865 100.47843668 -3064.52804688 +6 3 7 1 6 72010.33540516 80798.86718693 -67021.60244787 +6 3 7 1 7 -67039.12725836 -80811.10027591 71996.83830172 +6 3 7 1 8 -1559.02256660 -3077.14676739 -0.44990345 +6 3 7 2 1 3075.94702487 0.40705550 537.43109241 +6 3 7 2 2 -90.98761633 -3059.70765280 -890.93737055 +6 3 7 2 3 3077.62880680 -1.28543842 -1557.65143228 +6 3 7 2 4 -3075.94702487 535.59934265 -0.59987126 +6 3 7 2 5 100.25348496 -885.90273672 -3064.48519893 +6 3 7 2 6 80800.01336952 72009.38203833 -67020.80976084 +6 3 7 2 7 -80809.60059775 -67039.59858578 71997.30962915 +6 3 7 2 8 -3077.29673521 -1558.91544673 -0.33207159 +6 3 7 3 1 -1560.54366873 -534.96733543 1.55323809 +6 3 7 3 2 536.39202968 1559.38677415 3.96343514 +6 3 7 3 3 -536.60626942 -1558.85117481 2.69942069 +6 3 7 3 4 1557.76926414 538.02025168 2.91366042 +6 3 7 3 5 3070.62316740 3071.12663078 -9457.27040902 +6 3 7 3 6 -71998.86286724 -72002.82630238 74085.98638570 +6 3 7 3 7 71993.69968958 71989.92907020 -74110.13120406 +6 3 7 3 8 -3062.42849746 -3061.86076215 9470.25333708 +6 1 8 1 1 0.02142397 0.08569589 -890.03756365 +6 1 8 1 2 0.34278358 0.38563153 1.22116650 +6 1 8 1 3 -0.06427192 -0.06427192 -894.32235839 +6 1 8 1 4 -0.29993563 -0.27851166 1.17831855 +6 1 8 1 5 -0.08569589 -0.04284795 883.56752359 +6 1 8 1 6 -3.35285189 -0.42847947 5.50596124 +6 1 8 1 7 0.06427192 -0.04284795 887.53095873 +6 1 8 1 8 3.40641182 0.47132742 5.53809720 +6 1 8 2 1 -536.49914955 -536.39202968 -91.28755196 +6 1 8 2 2 -0.02142397 0.19281576 3374.16873886 +6 1 8 2 3 536.52057352 536.37060571 -93.32282946 +6 1 8 2 4 -0.77126305 0.66414318 2915.58858168 +6 1 8 2 5 -533.30697747 533.28555349 -110.29061664 +6 1 8 2 6 -5.42026535 -0.29993563 -2952.50208837 +6 1 8 2 7 537.87028387 -537.97740374 -89.42366625 +6 1 8 2 8 1.54252611 4.15625090 -2952.57707228 +6 1 8 3 1 1557.56573639 -3076.71828792 3060.67173161 +6 1 8 3 2 0.40705550 2914.32456723 -1.03906272 +6 1 8 3 3 1557.63000831 -3076.76113587 -3058.65787809 +6 1 8 3 4 0.47132742 574.74094262 -1.26401445 +6 1 8 3 5 -1554.39498828 -3080.38178742 -3071.16947873 +6 1 8 3 6 -6.22366436 11773.20196666 6.08440853 +6 1 8 3 7 -1558.63693507 -3077.03964753 3064.37807907 +6 1 8 3 8 3.08505221 -2951.43088969 0.69627915 +6 2 8 1 1 536.37060571 536.39202968 -91.37324786 +6 2 8 1 2 0.85695895 -0.58915928 2915.58858168 +6 2 8 1 3 -536.43487763 -536.30633379 -93.53706920 +6 2 8 1 4 -0.06427192 -0.06427192 3374.14731488 +6 2 8 1 5 533.24270555 -533.30697747 -110.29061664 +6 2 8 1 6 -1.49967816 -4.24194679 -2952.58778427 +6 2 8 1 7 -537.91313182 537.91313182 -89.40224228 +6 2 8 1 8 5.42026535 0.28922365 -2952.45924042 +6 2 8 2 1 0.02142397 0.02142397 -889.97329173 +6 2 8 2 2 -0.17139179 0.05355993 1.19974253 +6 2 8 2 3 0.08569589 0.02142397 -894.49375018 +6 2 8 2 4 0.01071199 0.10711987 1.30686240 +6 2 8 2 5 0.02142397 -0.02142397 883.48182770 +6 2 8 2 6 -3.05291625 -0.68556716 5.42026535 +6 2 8 2 7 -0.02142397 -0.06427192 887.48811078 +6 2 8 2 8 3.06362824 0.74983908 5.54880919 +6 2 8 3 1 -3076.76113587 1557.60858433 -3060.80027546 +6 2 8 3 2 574.71951864 0.39634351 -0.87838292 +6 2 8 3 3 -3076.67543997 1557.65143228 3058.61503014 +6 2 8 3 4 2914.34599120 0.42847947 -0.70699113 +6 2 8 3 5 -3080.42463537 -1554.35214033 -3070.91239105 +6 2 8 3 6 11773.14840672 -6.34149622 8.05541411 +6 2 8 3 7 -3076.88967971 -1558.72263097 3064.44235099 +6 2 8 3 8 -2951.45231366 3.14932413 2.53874088 +6 3 8 1 1 1557.63000831 -3076.67543997 -3060.69315559 +6 3 8 1 2 0.32135961 574.65524672 1.09262266 +6 3 8 1 3 1557.71570420 -3076.69686395 3060.62888367 +6 3 8 1 4 0.55702332 2914.36741517 0.89980690 +6 3 8 1 5 -1554.43783623 -3080.42463537 3071.08378284 +6 3 8 1 6 3.80275533 -2952.05218492 -1.49967816 +6 3 8 1 7 -1558.72263097 -3076.99679958 -3064.42092701 +6 3 8 1 8 -6.89851953 11773.72685401 -7.03777536 +6 3 8 2 1 -3076.71828792 1557.60858433 3060.75742751 +6 3 8 2 2 2914.45311107 0.51417537 0.73912709 +6 3 8 2 3 -3076.80398381 1557.56573639 -3060.58603572 +6 3 8 2 4 574.58026281 0.34278358 1.09262266 +6 3 8 2 5 -3080.36036345 -1554.39498828 3071.21232668 +6 3 8 2 6 -2952.08432088 3.83489129 -1.56395008 +6 3 8 2 7 -3076.91110368 -1558.55123918 -3064.39950304 +6 3 8 2 8 11773.75898997 -6.91994351 -6.98421543 +6 3 8 3 1 -0.02142397 -0.06427192 -9469.88912953 +6 3 8 3 2 -1.69249392 0.93194286 2.36734909 +6 3 8 3 3 -0.02142397 -0.04284795 -9461.16957223 +6 3 8 3 4 1.69249392 -0.96407882 2.39948506 +6 3 8 3 5 0.04284795 0.08569589 9444.71596043 +6 3 8 3 6 11.97600130 6.87709556 4.90608998 +6 3 8 3 7 -0.00000000 -0.14996782 9471.79586319 +6 3 8 3 8 -11.99742528 -6.80211165 4.92751395 +7 1 1 1 1 -0.02142397 -0.03213596 -5.18460164 +7 1 1 1 2 -9468.73223495 0.06427192 3.06362824 +7 1 1 1 3 0.02142397 0.02142397 0.51417537 +7 1 1 1 4 9468.76437091 -0.02142397 2.93508440 +7 1 1 1 5 -0.02142397 0.02142397 -0.14996782 +7 1 1 1 6 9470.91748027 0.66414318 -0.85695895 +7 1 1 1 7 0.08569589 -0.03213596 0.38563153 +7 1 1 1 8 -9470.85320835 -0.77126305 -0.83553497 +7 1 1 2 1 0.04284795 0.07498391 -11783.73184973 +7 1 1 2 2 3060.43606790 1561.33635576 3077.53239892 +7 1 1 2 3 -0.02142397 0.08569589 -2915.16010220 +7 1 1 2 4 -3060.43606790 -1561.29350781 3077.61809482 +7 1 1 2 5 -0.02142397 -0.04284795 -574.71951864 +7 1 1 2 6 3060.80027546 -1557.43719255 3077.51097495 +7 1 1 2 7 -0.00000000 0.05355993 2963.54614682 +7 1 1 2 8 -3060.82169943 1557.50146447 3077.36100713 +7 1 1 3 1 -1.77818982 -11783.18553841 0.04284795 +7 1 1 3 2 3062.94267283 3079.61052437 1556.34456989 +7 1 1 3 3 0.73912709 -573.58404804 0.02142397 +7 1 1 3 4 3062.94267283 3079.63194834 -1556.21602604 +7 1 1 3 5 -0.80339901 -2915.61000565 -0.00000000 +7 1 1 3 6 -3061.18590698 3076.58974408 -1557.39434460 +7 1 1 3 7 -1.67106995 2959.93620725 0.02142397 +7 1 1 3 8 -3061.20733096 3076.62188004 1557.31936069 +7 2 1 1 1 -0.06427192 -0.05355993 2957.22607457 +7 2 1 1 2 -3063.52112012 1556.38741783 3075.68993718 +7 2 1 1 3 -0.00000000 0.02142397 -573.36980830 +7 2 1 1 4 3063.47827217 -1556.38741783 3075.45427347 +7 2 1 1 5 0.10711987 -0.00000000 -2914.26029531 +7 2 1 1 6 -3061.07878711 -1557.15868089 3076.43977626 +7 2 1 1 7 -0.04284795 -0.01071199 -11773.64115812 +7 2 1 1 8 3061.05736314 1557.21224082 3076.40764030 +7 2 1 2 1 -0.04284795 0.02142397 -2.08883744 +7 2 1 2 2 -888.96636496 0.53559934 2.46375698 +7 2 1 2 3 0.04284795 0.02142397 0.72841511 +7 2 1 2 4 889.03063689 -0.55702332 2.31378916 +7 2 1 2 5 -0.04284795 -0.00000000 -1.97100558 +7 2 1 2 6 888.62358139 -0.92123087 -0.00000000 +7 2 1 2 7 -0.02142397 0.03213596 -1.86388571 +7 2 1 2 8 -888.60215741 0.92123087 0.29993563 +7 2 1 3 1 2960.34326275 -1.68178194 -0.06427192 +7 2 1 3 2 92.01596707 -534.87092755 538.25591539 +7 2 1 3 3 -2914.67806279 0.70699113 -0.02142397 +7 2 1 3 4 92.02667905 -534.93519947 -538.12737155 +7 2 1 3 5 -3373.81524329 -1.07119869 0.19281576 +7 2 1 3 6 90.40916904 535.83500637 537.78458797 +7 2 1 3 7 2963.47116291 -0.05355993 0.03213596 +7 2 1 3 8 90.30204917 535.93141425 -537.81672393 +7 3 1 1 1 -1.02835074 2959.38989592 -0.02142397 +7 3 1 1 2 -3058.87211782 3075.02579400 1559.60101389 +7 3 1 1 3 0.26779967 -2913.70327199 -0.10711987 +7 3 1 1 4 -3058.88282981 3074.94009810 -1559.53674197 +7 3 1 1 5 0.40705550 -574.91233441 0.02142397 +7 3 1 1 6 3060.65030764 3076.03272076 -1559.23680634 +7 3 1 1 7 -3.19217208 -11772.98772692 -0.04284795 +7 3 1 1 8 3060.67173161 3076.07556871 1559.22609435 +7 3 1 2 1 2962.05718064 -2.52802890 0.03213596 +7 3 1 2 2 89.53078612 539.75559355 -536.47772558 +7 3 1 2 3 -3371.54430208 0.55702332 -0.02142397 +7 3 1 2 4 89.61648201 539.75559355 536.62769339 +7 3 1 2 5 -2914.04605557 0.10711987 0.04284795 +7 3 1 2 6 89.59505804 -538.04167566 -536.13494200 +7 3 1 2 7 2965.18508081 -1.56395008 -0.03213596 +7 3 1 2 8 89.61648201 -537.96669175 536.02782213 +7 3 1 3 1 -0.17139179 -0.06427192 4.86324203 +7 3 1 3 2 -890.85167465 -0.14996782 -2.89223645 +7 3 1 3 3 0.04284795 0.02142397 2.16382134 +7 3 1 3 4 890.84096266 0.27851166 -2.74226863 +7 3 1 3 5 -0.05355993 -0.02142397 -2.46375698 +7 3 1 3 6 888.94494099 -0.12854384 1.92815763 +7 3 1 3 7 0.04284795 -0.04284795 -2.71013267 +7 3 1 3 8 -889.00921291 0.11783186 2.02456552 +7 1 2 1 1 -9469.63204185 3060.52176380 3063.70322389 +7 1 2 1 2 74061.56305567 -71906.32201282 -71941.36092181 +7 1 2 1 3 -0.23566371 -1555.85181849 -535.47079881 +7 1 2 1 4 -0.86767094 535.79215842 1555.63757875 +7 1 2 1 5 -0.97479080 -534.48529602 -1556.49453770 +7 1 2 1 6 -1.63893399 1553.28094165 536.41345366 +7 1 2 1 7 -74051.57948392 71904.77948671 71937.50460655 +7 1 2 1 8 9463.26912166 -3057.64023933 -3059.86833260 +7 1 2 2 1 0.32135961 1561.90409106 3079.65337232 +7 1 2 2 2 -71903.50476027 66918.12465487 80698.69939786 +7 1 2 2 3 890.95879452 3065.06364622 93.13001370 +7 1 2 2 4 -535.43866285 -0.36420755 -3078.30366197 +7 1 2 2 5 2.35663711 -537.50607631 3074.53304260 +7 1 2 2 6 1557.34078466 -0.10711987 -3075.02579400 +7 1 2 2 7 66929.13657735 -71897.27038392 -80701.79516206 +7 1 2 2 8 3058.78642193 890.25180339 -90.83764851 +7 1 2 3 1 3.68492348 3078.04657429 1556.69806545 +7 1 2 3 2 -71942.56066434 80699.36354105 66983.76771030 +7 1 2 3 3 2.42090903 3075.49712142 -538.23449142 +7 1 2 3 4 1556.83732128 -3078.92495721 0.47132742 +7 1 2 3 5 890.72313081 93.15143767 3062.87840091 +7 1 2 3 6 -538.50229109 -3072.51918907 -0.27851166 +7 1 2 3 7 66969.97067124 -80706.03710886 -71956.21844758 +7 1 2 3 8 3057.35101569 -88.59884326 890.78740273 +7 2 2 1 1 -3064.22811125 -890.16610749 93.64418907 +7 2 2 1 2 -66921.18828311 71901.97294615 80699.45994893 +7 2 2 1 3 -1561.08998006 0.51417537 3079.07492503 +7 2 2 1 4 0.19281576 535.29940702 -3078.23939005 +7 2 2 1 5 537.73102804 -2.05670148 3074.49019465 +7 2 2 1 6 -890.45533114 -3058.76499795 -90.85907249 +7 2 2 1 7 71899.94838064 -66928.81521775 -80701.81658604 +7 2 2 1 8 -0.79268703 -1558.05848778 -3075.65780122 +7 2 2 2 1 1555.76612260 0.38563153 -535.53507073 +7 2 2 2 2 71905.39006996 -74063.19127767 -71940.86817042 +7 2 2 2 3 -3059.85762061 9470.53184874 3063.07121667 +7 2 2 2 4 -535.97426219 0.70699113 1555.65900273 +7 2 2 2 5 534.53885596 1.19974253 -1556.40884181 +7 2 2 2 6 3057.52240748 -9463.20484974 -3059.96474048 +7 2 2 2 7 -71903.18340067 74052.50071479 71938.10447781 +7 2 2 2 8 -1554.22359649 0.98550279 535.76002246 +7 2 2 3 1 3075.47569744 2.39948506 538.19164347 +7 2 2 3 2 80699.20286125 -71942.28215268 -66983.64987845 +7 2 2 3 3 3077.99301436 3.59922758 -1556.68735347 +7 2 2 3 4 -3078.87139728 1556.77304936 -0.40705550 +7 2 2 3 5 93.18357364 890.76597876 -3062.89982488 +7 2 2 3 6 -88.57741929 3057.37243966 -890.74455478 +7 2 2 3 7 -80705.80144515 66969.91711130 71955.92922393 +7 2 2 3 8 -3072.49776510 -538.48086712 0.32135961 +7 3 2 1 1 -3059.60053293 90.86978447 -889.53410027 +7 3 2 1 2 -66971.23468569 80709.01504120 71950.68035037 +7 3 2 1 3 540.17336104 3075.26145771 -0.38563153 +7 3 2 1 4 -884.69228221 -101.54963537 -3065.25646199 +7 3 2 1 5 -1559.77240568 3079.73906821 1.69249392 +7 3 2 1 6 -0.59987126 -3073.16190828 537.57034824 +7 3 2 1 7 71938.87574086 -80703.88399950 -66977.13699044 +7 3 2 1 8 -3.10647619 -3076.24696050 -1557.69428023 +7 3 2 2 1 3075.43284950 540.00196925 0.51417537 +7 3 2 2 2 80709.48636862 -66969.98138322 -71951.36591753 +7 3 2 2 3 90.28062520 -3060.50033982 890.10183557 +7 3 2 2 4 -101.67817921 -884.85296201 3065.21361404 +7 3 2 2 5 3079.64266033 -1559.92237350 -1.77818982 +7 3 2 2 6 -3076.85754375 -4.00628308 1558.33699944 +7 3 2 2 7 -80703.46623201 71940.03263544 66976.52640719 +7 3 2 2 8 -3072.99051650 -0.78197504 -537.44180439 +7 3 2 3 1 1559.00114263 -536.80979717 -3.22430804 +7 3 2 3 2 71946.00992411 -71945.95636417 -74125.82426480 +7 3 2 3 3 536.80979717 -1559.06541455 -3.19217208 +7 3 2 3 4 3067.75235492 -3067.67737102 -9458.21306386 +7 3 2 3 5 -3058.12227874 3058.14370272 9466.35417387 +7 3 2 3 6 -536.25277385 1559.38677415 2.97793235 +7 3 2 3 7 -71955.67213625 71955.71498420 74118.09021030 +7 3 2 3 8 -1559.40819813 536.26348584 3.02078029 +7 1 3 1 1 -0.12854384 -0.02142397 0.63200722 +7 1 3 1 2 -0.55702332 889.00921291 2.37806108 +7 1 3 1 3 -0.03213596 -0.00000000 -2.22809327 +7 1 3 1 4 0.50346338 -889.00921291 2.52802890 +7 1 3 1 5 0.01071199 0.08569589 -1.97100558 +7 1 3 1 6 -0.87838292 888.70927728 0.29993563 +7 1 3 1 7 -0.00000000 0.04284795 -1.91744565 +7 1 3 1 8 0.85695895 -888.58073344 0.26779967 +7 1 3 2 1 -0.00000000 -0.06427192 -573.47692817 +7 1 3 2 2 -1556.45168975 3063.47827217 3075.73278513 +7 1 3 2 3 -0.00000000 -0.02142397 2957.12966669 +7 1 3 2 4 1556.44097777 -3063.58539204 3075.75420910 +7 1 3 2 5 -0.03213596 -0.04284795 -2914.34599120 +7 1 3 2 6 -1557.22295281 -3061.05736314 3076.31123242 +7 1 3 2 7 -0.12854384 0.02142397 -11773.73756600 +7 1 3 2 8 1557.26580076 3061.05736314 3076.41835229 +7 1 3 3 1 0.62129524 -2914.64592683 -0.01071199 +7 1 3 3 2 -534.89235152 91.97311912 -538.21306745 +7 1 3 3 3 -1.74605386 2960.32183877 -0.06427192 +7 1 3 3 4 -534.96733543 91.86599925 538.38445924 +7 1 3 3 5 -1.04977471 -3373.76168336 0.04284795 +7 1 3 3 6 535.89927829 90.36632109 537.61319618 +7 1 3 3 7 -0.10711987 2963.59970675 -0.00000000 +7 1 3 3 8 536.00639816 90.23777725 -537.87028387 +7 2 3 1 1 -0.00000000 0.03213596 -2914.98871041 +7 2 3 1 2 -1561.29350781 -3058.29367053 3077.46812700 +7 2 3 1 3 0.03213596 -0.08569589 -11782.43569933 +7 2 3 1 4 1561.28279583 3058.35794245 3077.63951879 +7 2 3 1 5 0.05355993 -0.06427192 -574.97660633 +7 2 3 1 6 -1557.45861652 3060.80027546 3077.33958316 +7 2 3 1 7 0.04284795 0.06427192 2962.26070839 +7 2 3 1 8 1557.39434460 -3060.82169943 3077.31815918 +7 2 3 2 1 -0.04284795 0.05355993 0.65343120 +7 2 3 2 2 -0.08569589 9468.66796303 3.06362824 +7 2 3 2 3 -0.00000000 0.02142397 -3.92058719 +7 2 3 2 4 0.05355993 -9468.77508290 2.87081248 +7 2 3 2 5 0.02142397 0.02142397 -0.29993563 +7 2 3 2 6 0.81411100 9468.58226714 -1.02835074 +7 2 3 2 7 0.08569589 -0.02142397 -0.85695895 +7 2 3 2 8 -0.77126305 -9468.67867502 -0.89980690 +7 2 3 3 1 -573.51977611 0.71770312 -0.04284795 +7 2 3 3 2 3079.65337232 3062.89982488 -1556.32314591 +7 2 3 3 3 -11783.20696238 -1.82103777 -0.10711987 +7 2 3 3 4 3079.66408430 3062.87840091 1556.40884181 +7 2 3 3 5 -2915.64214161 -0.77126305 -0.00000000 +7 2 3 3 6 3076.58974408 -3061.14305904 -1557.22295281 +7 2 3 3 7 2959.89335930 -1.59608604 0.05355993 +7 2 3 3 8 3076.54689613 -3061.28231486 1557.22295281 +7 3 3 1 1 0.59987126 -3372.01562950 0.05355993 +7 3 3 1 2 539.75559355 91.84457528 536.45630160 +7 3 3 1 3 -3.70634745 2960.27899083 0.08569589 +7 3 3 1 4 539.74488157 91.78030336 -536.58484545 +7 3 3 1 5 -0.18210378 -2914.51738299 0.02142397 +7 3 3 1 6 -537.95597976 89.53078612 -535.94212623 +7 3 3 1 7 -0.21423974 2963.36404304 0.05355993 +7 3 3 1 8 -538.02025168 89.56292208 536.15636597 +7 3 3 2 1 -2913.72469596 0.19281576 -0.04284795 +7 3 3 2 2 3075.02579400 -3058.89354180 -1559.70813376 +7 3 3 2 3 2959.58271168 -1.04977471 0.08569589 +7 3 3 2 4 3075.01508201 -3058.82926988 1559.62243786 +7 3 3 2 5 -574.90162242 0.53559934 0.04284795 +7 3 3 2 6 3076.07556871 3060.62888367 -1559.19395839 +7 3 3 2 7 -11772.92345500 -3.19217208 0.02142397 +7 3 3 2 8 3075.98987281 3060.59674771 1559.15111044 +7 3 3 3 1 -0.06427192 0.02142397 2.28165320 +7 3 3 3 2 0.17139179 890.78740273 -2.97793235 +7 3 3 3 3 0.01071199 -0.02142397 4.73469819 +7 3 3 3 4 -0.11783186 -890.74455478 -2.78511658 +7 3 3 3 5 -0.03213596 0.10711987 -2.46375698 +7 3 3 3 6 -0.14996782 888.90209304 2.14239737 +7 3 3 3 7 0.04284795 -0.06427192 -2.74226863 +7 3 3 3 8 0.10711987 -889.04134887 2.03527750 +7 1 4 1 1 9469.61061787 -3060.53247578 3063.70322389 +7 1 4 1 2 0.83553497 -535.79215842 1555.59473081 +7 1 4 1 3 0.23566371 1555.85181849 -535.38510292 +7 1 4 1 4 -74061.54163170 71906.24702891 -71941.29664989 +7 1 4 1 5 0.98550279 534.44244807 -1556.49453770 +7 1 4 1 6 -9463.22627371 3057.65095132 -3059.94331651 +7 1 4 1 7 74051.42951611 -71904.56524697 71937.45104661 +7 1 4 1 8 1.62822200 -1553.29165363 536.41345366 +7 1 4 2 1 -0.19281576 -1561.79697119 3079.83547609 +7 1 4 2 2 535.40652689 0.37491954 -3078.38935787 +7 1 4 2 3 -891.06591439 -3065.14934212 93.32282946 +7 1 4 2 4 71903.59045617 -66918.33889461 80696.65340837 +7 1 4 2 5 -2.97793235 538.14879553 3075.36857758 +7 1 4 2 6 -3058.87211782 -890.29465133 -90.75195262 +7 1 4 2 7 -66928.62240198 71896.98116028 -80701.09888292 +7 1 4 2 8 -1557.43719255 0.14996782 -3075.02579400 +7 1 4 3 1 3.57780361 3077.92874243 -1556.90159320 +7 1 4 3 2 1556.81589731 -3078.90353324 -0.46061543 +7 1 4 3 3 2.48518095 3075.53996937 537.99882771 +7 1 4 3 4 -71942.22859275 80699.11716535 -66981.23968141 +7 1 4 3 5 891.35513803 92.55156641 -3063.82105575 +7 1 4 3 6 3057.34030370 -88.56670730 -890.85167465 +7 1 4 3 7 66969.11371229 -80705.05160607 71954.96514512 +7 1 4 3 8 -538.49157911 -3072.49776510 0.32135961 +7 2 4 1 1 3064.33523112 890.27322736 93.85842881 +7 2 4 1 2 -0.17139179 -535.35296696 -3078.27152601 +7 2 4 1 3 1561.03642013 -0.55702332 3079.22489284 +7 2 4 1 4 66921.22041907 -71902.04793006 80697.25327964 +7 2 4 1 5 -538.40588321 2.74226863 3075.41142552 +7 2 4 1 6 0.81411100 1558.03706381 -3075.66851321 +7 2 4 1 7 -71899.32708540 66928.17249854 -80700.88464318 +7 2 4 1 8 890.44461915 3058.66859007 -90.93405640 +7 2 4 2 1 -1555.72327465 -0.40705550 -535.54578272 +7 2 4 2 2 535.94212623 -0.77126305 1555.66971471 +7 2 4 2 3 3059.91118055 -9470.51042477 3063.11406462 +7 2 4 2 4 -71905.26152612 74062.84849409 -71940.58965876 +7 2 4 2 5 -534.53885596 -1.15689458 -1556.40884181 +7 2 4 2 6 1554.25573245 -0.94265484 535.74931047 +7 2 4 2 7 71902.90488901 -74052.17935519 71937.87952608 +7 2 4 2 8 -3057.43671158 9463.18342576 -3059.95402849 +7 2 4 3 1 3075.49712142 2.47446896 -537.96669175 +7 2 4 3 2 -3078.90353324 1556.82660929 0.47132742 +7 2 4 3 3 3077.96087839 3.55637964 1556.88016923 +7 2 4 3 4 80699.42781297 -71942.41069652 66981.71100883 +7 2 4 3 5 92.54085442 891.32300207 3063.75678383 +7 2 4 3 6 -3072.45491715 -538.47015513 -0.29993563 +7 2 4 3 7 -80705.37296567 66969.40293593 -71955.20080883 +7 2 4 3 8 -88.60955525 3057.35101569 890.78740273 +7 3 4 1 1 -3059.60053293 90.88049646 889.51267629 +7 3 4 1 2 -884.66014625 -101.53892338 3065.24575000 +7 3 4 1 3 540.16264905 3075.32572963 0.29993563 +7 3 4 1 4 -66971.19183774 80708.95076928 -71950.53038256 +7 3 4 1 5 -1559.74026972 3079.69622027 -1.75676584 +7 3 4 1 6 -3.09576420 -3076.22553652 1557.65143228 +7 3 4 1 7 71938.79004497 -80704.01254334 66977.15841442 +7 3 4 1 8 -0.62129524 -3073.09763636 -537.49536433 +7 3 4 2 1 3075.34715360 540.05552919 -0.50346338 +7 3 4 2 2 -101.54963537 -884.67085824 -3065.24575000 +7 3 4 2 3 90.23777725 -3060.47891585 -890.20895544 +7 3 4 2 4 80709.01504120 -66968.96374447 71950.61607845 +7 3 4 2 5 3079.61052437 -1559.90094952 1.82103777 +7 3 4 2 6 -3073.14048431 -0.62129524 537.48465234 +7 3 4 2 7 -80703.29484022 71937.99735794 -66976.47284726 +7 3 4 2 8 -3076.24696050 -3.10647619 -1557.70499222 +7 3 4 3 1 -1559.06541455 536.82050916 -3.22430804 +7 3 4 3 2 -3067.69879499 3067.69879499 -9458.20235188 +7 3 4 3 3 -536.78837320 1559.04399057 -3.21359606 +7 3 4 3 4 -71945.75283642 71945.79568437 -74125.70643295 +7 3 4 3 5 3058.11156676 -3058.16512669 9466.39702182 +7 3 4 3 6 1559.46175806 -536.19921392 2.99935632 +7 3 4 3 7 71955.58644035 -71955.57572837 74117.97237844 +7 3 4 3 8 536.19921392 -1559.44033409 2.95650837 +7 1 5 1 1 0.04284795 -0.00000000 -0.63200722 +7 1 5 1 2 -0.77126305 2.33521313 890.12325954 +7 1 5 1 3 0.03213596 -0.08569589 -0.83553497 +7 1 5 1 4 0.81411100 -2.33521313 890.03756365 +7 1 5 1 5 -0.03213596 -0.02142397 -4.00628308 +7 1 5 1 6 -0.74983908 -2.35663711 -886.69542375 +7 1 5 1 7 -0.02142397 0.03213596 -1.41398226 +7 1 5 1 8 0.72841511 2.42090903 -886.62043984 +7 1 5 2 1 -0.02142397 -0.10711987 -2915.89922929 +7 1 5 2 2 -534.76380768 -537.93455579 91.37324786 +7 1 5 2 3 0.12854384 0.14996782 -3374.53294641 +7 1 5 2 4 534.72095973 537.99882771 93.49422125 +7 1 5 2 5 0.62129524 -0.64271921 2950.72389855 +7 1 5 2 6 -537.24898863 533.90684873 101.89241895 +7 1 5 2 7 -0.59987126 0.61058325 2950.72389855 +7 1 5 2 8 537.14186876 -534.06752853 101.95669087 +7 1 5 3 1 -0.83553497 -574.62311076 0.02142397 +7 1 5 3 2 -1556.13033015 3074.79013029 3062.57846527 +7 1 5 3 3 -1.64964598 -2914.51738299 -0.00000000 +7 1 5 3 4 -1556.22673803 3074.81155426 -3062.68558514 +7 1 5 3 5 -3.57780361 2952.82344798 -0.04284795 +7 1 5 3 6 1557.90851997 3080.63887511 -3066.84183604 +7 1 5 3 7 2.72084466 -11774.38028521 -0.01071199 +7 1 5 3 8 1557.88709599 3080.61745113 3066.88468399 +7 2 5 1 1 -0.08569589 -0.16067980 -3374.50081045 +7 2 5 1 2 537.95597976 534.78523165 91.56606362 +7 2 5 1 3 0.05355993 0.08569589 -2915.93136525 +7 2 5 1 4 -537.99882771 -534.76380768 93.57991715 +7 2 5 1 5 0.66414318 -0.70699113 2950.72389855 +7 2 5 1 6 533.94969668 -537.37753247 101.97811484 +7 2 5 1 7 -0.57844729 0.59987126 2950.61677869 +7 2 5 1 8 -533.97112065 537.25970062 102.01025080 +7 2 5 2 1 -0.00000000 0.09640788 -0.80339901 +7 2 5 2 2 -2.39948506 0.83553497 890.16610749 +7 2 5 2 3 -0.06427192 0.02142397 -0.62129524 +7 2 5 2 4 2.37806108 -0.77126305 890.03756365 +7 2 5 2 5 -0.01071199 -0.08569589 -3.98485911 +7 2 5 2 6 -2.42090903 -0.81411100 -886.65257580 +7 2 5 2 7 -0.00000000 -0.03213596 -1.43540624 +7 2 5 2 8 2.44233300 0.74983908 -886.55616792 +7 2 5 3 1 -2914.58165491 -1.71391790 0.03213596 +7 2 5 3 2 3074.68301042 -1556.19460207 -3062.55704130 +7 2 5 3 3 -574.54812685 -0.79268703 0.02142397 +7 2 5 3 4 3074.75799433 -1556.32314591 3062.51419335 +7 2 5 3 5 2952.75917606 -3.51353169 -0.04284795 +7 2 5 3 6 3080.63887511 1557.95136791 -3066.84183604 +7 2 5 3 7 -11774.33743726 2.71013267 0.01071199 +7 2 5 3 8 3080.63887511 1557.91923195 3066.88468399 +7 3 5 1 1 0.38563153 -2914.49595902 -0.10711987 +7 3 5 1 2 -1559.02256660 3078.58217363 -3060.92881930 +7 3 5 1 3 0.37491954 -574.59097480 -0.04284795 +7 3 5 1 4 -1558.92615872 3078.56074966 3061.05736314 +7 3 5 1 5 12.29736091 -11774.44455713 0.06427192 +7 3 5 1 6 1555.10197941 3076.71828792 3068.59860189 +7 3 5 1 7 -5.42026535 2952.75917606 -0.04284795 +7 3 5 1 8 1555.20909928 3076.77184785 -3068.51290599 +7 3 5 2 1 -574.54812685 0.43919146 0.05355993 +7 3 5 2 2 3078.66786953 -1559.00114263 3060.84312340 +7 3 5 2 3 -2914.45311107 0.29993563 0.04284795 +7 3 5 2 4 3078.66786953 -1558.89402276 -3061.10021109 +7 3 5 2 5 -11774.39099720 12.38305680 0.04284795 +7 3 5 2 6 3076.73971189 1555.12340339 3068.64144983 +7 3 5 2 7 2952.69490413 -5.43097733 0.03213596 +7 3 5 2 8 3076.78255984 1555.15553935 -3068.51290599 +7 3 5 3 1 -0.00000000 -0.04284795 -2.49589294 +7 3 5 3 2 3.08505221 -3.04220427 9467.74673216 +7 3 5 3 3 0.01071199 -0.04284795 -2.52802890 +7 3 5 3 4 -3.09576420 3.02078029 9467.51106845 +7 3 5 3 5 -0.03213596 -0.00000000 -11.44040196 +7 3 5 3 6 3.04220427 3.08505221 -9459.49850228 +7 3 5 3 7 -0.04284795 -0.02142397 -0.16067980 +7 3 5 3 8 -3.04220427 -3.04220427 -9459.30568652 +7 1 6 1 1 9466.46129374 3061.60367447 -3061.80720222 +7 1 6 1 2 -0.32135961 1557.51217645 -538.83436268 +7 1 6 1 3 -1.45683021 -1556.70877744 536.30633379 +7 1 6 1 4 -9464.87591968 -3057.82234311 3056.51548071 +7 1 6 1 5 -0.89980690 -536.97047697 1557.95136791 +7 1 6 1 6 -74103.85397977 -72014.58806394 72010.34611715 +7 1 6 1 7 74104.53954693 72008.48223143 -72002.55850270 +7 1 6 1 8 0.23566371 538.51300308 -1557.86567202 +7 1 6 2 1 1.17831855 -1557.84424805 3076.75042388 +7 1 6 2 2 1554.37356431 0.81411100 -3072.79770073 +7 1 6 2 3 889.83403590 -3061.52869056 91.39467183 +7 1 6 2 4 3055.25146627 -889.07348483 -90.02353751 +7 1 6 2 5 -2.58158883 533.54264118 3080.08185179 +7 1 6 2 6 -72014.05246460 -67033.49275328 80801.22382403 +7 1 6 2 7 67054.63821532 72007.59313652 -80809.37564603 +7 1 6 2 8 -538.72724282 -0.11783186 -3077.32887117 +7 1 6 3 1 -1.26401445 3077.80019859 -1557.50146447 +7 1 6 3 2 534.95662344 -3075.09006592 0.02142397 +7 1 6 3 3 -0.25708768 3076.88967971 538.12737155 +7 1 6 3 4 -3059.62195690 -90.79480057 -890.89452260 +7 1 6 3 5 -885.97772063 100.47843668 -3064.57089483 +7 1 6 3 6 72010.31398119 80799.03857872 -67021.49532800 +7 1 6 3 7 -67039.25580220 -80811.22881975 71996.92399762 +7 1 6 3 8 -1559.06541455 -3077.14676739 -0.46061543 +7 2 6 1 1 -3061.55011454 889.89830782 91.34111190 +7 2 6 1 2 -890.38034723 3057.09392801 -88.71667512 +7 2 6 1 3 -1557.85496003 1.15689458 3076.73971189 +7 2 6 1 4 0.99621478 1554.73777186 -3072.64773292 +7 2 6 1 5 533.62833707 -2.57087684 3080.16754769 +7 2 6 1 6 -67031.98236313 -72012.08145902 80799.78841780 +7 2 6 1 7 72007.32533685 67050.06419694 -80809.27923815 +7 2 6 1 8 -0.21423974 -538.32018732 -3077.45741501 +7 2 6 2 1 -1557.50146447 -0.88909491 535.51364676 +7 2 6 2 2 -3057.97231093 -9464.96161558 3056.47263277 +7 2 6 2 3 3061.38943473 9466.41844579 -3062.12856183 +7 2 6 2 4 1556.56952161 0.38563153 -539.51992984 +7 2 6 2 5 -537.79529996 -1.39255829 1557.05156102 +7 2 6 2 6 -72013.51686525 -74104.45385103 72013.23835360 +7 2 6 2 7 72010.49608496 74104.67880276 -72002.91199827 +7 2 6 2 8 538.34161129 0.31064762 -1557.75855215 +7 2 6 3 1 3076.93252766 -0.22495172 538.12737155 +7 2 6 3 2 -91.00904030 -3059.71836478 -890.94808253 +7 2 6 3 3 3077.84304654 -1.24259047 -1557.52288844 +7 2 6 3 4 -3075.94702487 535.53507073 -0.59987126 +7 2 6 3 5 100.45701271 -885.96700865 -3064.57089483 +7 2 6 3 6 80798.04236394 72009.78909383 -67021.04542455 +7 2 6 3 7 -80808.89360662 -67039.12725836 71996.89186166 +7 2 6 3 8 -3077.27531124 -1558.94758269 -0.34278358 +7 3 6 1 1 3061.33587480 90.66625672 889.93044378 +7 3 6 1 2 -1.17831855 -3075.56139334 -535.97426219 +7 3 6 1 3 -538.45944314 3076.69686395 -0.04284795 +7 3 6 1 4 -2.03527750 -3073.95459531 1559.90094952 +7 3 6 1 5 1554.11647662 3075.83990500 1.58537405 +7 3 6 1 6 67036.67421337 80805.08013930 -71999.39846658 +7 3 6 1 7 -71999.18422685 -80808.28302337 67021.28108826 +7 3 6 1 8 888.70927728 -90.40916904 3062.74985706 +7 3 6 2 1 3076.69686395 -538.44873116 0.02142397 +7 3 6 2 2 -3074.14741108 -2.17453333 1559.80454164 +7 3 6 2 3 90.59127282 3061.27160288 889.97329173 +7 3 6 2 4 -3076.40764030 -0.57844729 -536.62769339 +7 3 6 2 5 3075.76492109 1554.13790059 1.58537405 +7 3 6 2 6 80804.25531631 67036.27786986 -71998.77717134 +7 3 6 2 7 -80806.15133799 -71999.23778678 67021.30251224 +7 3 6 2 8 -90.60198480 888.82710914 3062.82484097 +7 3 6 3 1 -1559.47247005 -535.66361458 2.04598949 +7 3 6 3 2 536.34918173 1559.47247005 3.84560328 +7 3 6 3 3 -536.53128551 -1558.72263097 2.54945287 +7 3 6 3 4 1557.88709599 537.97740374 2.74226863 +7 3 6 3 5 3070.17326395 3070.41963965 -9458.21306386 +7 3 6 3 6 -72000.45895328 -72002.03361535 74086.95046451 +7 3 6 3 7 71995.11367184 71991.04311684 -74109.46706088 +7 3 6 3 8 -3063.04979270 -3062.49276938 9469.33210622 +7 1 7 1 1 -0.02142397 0.01071199 -2.65657274 +7 1 7 1 2 -74052.67210658 66926.62997243 66965.96438815 +7 1 7 1 3 0.03213596 -0.02142397 0.08569589 +7 1 7 1 4 74052.53285075 -66926.73709230 66966.00723610 +7 1 7 1 5 -0.09640788 0.02142397 3.55637964 +7 1 7 1 6 74102.02223002 67046.64707313 -67035.09955130 +7 1 7 1 7 0.12854384 -0.06427192 137.28482351 +7 1 7 1 8 -74102.14006187 -67046.68992108 -67035.15311124 +7 1 7 2 1 0.17139179 0.05355993 2964.03889821 +7 1 7 2 2 71893.37122071 -71893.38193270 -80701.97726584 +7 1 7 2 3 0.08569589 -0.00000000 2964.02818623 +7 1 7 2 4 -71893.46762859 71893.45691661 -80702.13794564 +7 1 7 2 5 0.03213596 -0.00000000 -11772.30215976 +7 1 7 2 6 72009.09281468 72009.08210270 -80812.21432255 +7 1 7 2 7 0.21423974 0.03213596 328872.88605177 +7 1 7 2 8 -72009.03925475 -72009.10352667 -80812.11791466 +7 1 7 3 1 -4.94893793 2963.50329887 0.28922365 +7 1 7 3 2 71939.49703610 -80703.33768817 -71955.35077664 +7 1 7 3 3 -3.37427586 -11772.17361592 0.21423974 +7 1 7 3 4 71939.37920424 -80703.18772035 71953.01556351 +7 1 7 3 5 -2.88152446 2953.63755898 0.94265484 +7 1 7 3 6 -71999.40917857 -80812.08577870 71993.89250534 +7 1 7 3 7 131.20041498 328885.77257195 1.11404663 +7 1 7 3 8 -71999.54843440 -80812.07506672 -71993.93535329 +7 2 7 1 1 0.02142397 -0.08569589 2964.02818623 +7 2 7 1 2 71893.41406866 -71893.46762859 -80702.11652167 +7 2 7 1 3 0.06427192 0.04284795 2963.96391430 +7 2 7 1 4 -71893.42478064 71893.37122071 -80702.15936962 +7 2 7 1 5 0.04284795 -0.04284795 -11772.34500771 +7 2 7 1 6 72008.95355886 72009.12495064 -80812.04293076 +7 2 7 1 7 -0.06427192 -0.03213596 328872.57540415 +7 2 7 1 8 -72008.88928693 -72008.85715097 -80811.95723486 +7 2 7 2 1 -0.96407882 0.58915928 0.81411100 +7 2 7 2 2 -66929.43651299 74053.48621758 66966.64995531 +7 2 7 2 3 -0.17139179 -0.06427192 -2.44233300 +7 2 7 2 4 66928.85806570 -74052.35074698 66965.79299637 +7 2 7 2 5 -0.19281576 0.12854384 3.51353169 +7 2 7 2 6 67049.45361369 74102.69708519 -67035.95651025 +7 2 7 2 7 -0.74983908 -2.74226863 136.74922417 +7 2 7 2 8 -67046.88273684 -74101.88297419 -67035.29236707 +7 2 7 3 1 -11768.59581231 -0.77126305 -0.27851166 +7 2 7 3 2 -80707.08688357 71938.37227748 71954.81517730 +7 2 7 3 3 2964.18886603 -5.46311330 -0.17139179 +7 2 7 3 4 -80707.04403562 71938.38298947 -71952.47996417 +7 2 7 3 5 2954.39811004 -2.52802890 -1.00692676 +7 2 7 3 6 -80812.59995407 -72000.57678514 71994.38525674 +7 2 7 3 7 328889.12542384 132.78578903 -0.97479080 +7 2 7 3 8 -80812.51425818 -72000.38396937 -71994.21386495 +7 3 7 1 1 -4.99178587 2963.49258688 0.16067980 +7 3 7 1 2 71939.21852444 -80703.08060049 -71954.99728108 +7 3 7 1 3 -3.27786798 -11772.19503989 0.23566371 +7 3 7 1 4 71939.62557994 -80703.61619983 71953.35834709 +7 3 7 1 5 -2.84938850 2953.70183090 1.00692676 +7 3 7 1 6 -71999.86979400 -80812.27859447 71994.10674508 +7 3 7 1 7 131.39323074 328885.95467573 -0.00000000 +7 3 7 1 8 -71999.46273850 -80812.05364274 -71993.76396150 +7 3 7 2 1 -11768.46726847 -0.86767094 -0.24637570 +7 3 7 2 2 -80706.82979588 71938.14732576 71954.52595365 +7 3 7 2 3 2964.21029000 -5.29172151 -0.14996782 +7 3 7 2 4 -80707.33325927 71938.64007715 -71952.95129159 +7 3 7 2 5 2954.45166998 -2.44233300 -0.85695895 +7 3 7 2 6 -80813.00700957 -72000.94099269 71994.68519237 +7 3 7 2 7 328889.61817523 133.25711645 -0.78197504 +7 3 7 2 8 -80812.62137805 -72000.46966527 -71994.25671289 +7 3 7 3 1 -0.92123087 0.59987126 -1.52110213 +7 3 7 3 2 -66970.35630276 66970.27060687 74116.12991670 +7 3 7 3 3 -0.09640788 -0.08569589 -0.98550279 +7 3 7 3 4 66969.92782329 -66969.67073561 74117.73671473 +7 3 7 3 5 0.42847947 -0.57844729 -2.99935632 +7 3 7 3 6 67024.37685246 67022.41655887 -74107.68887106 +7 3 7 3 7 -1.09262266 -0.42847947 -12.96150409 +7 3 7 3 8 -67022.30943900 -67022.36299894 -74107.73171901 +7 1 8 1 1 -9466.52556566 -3061.57153851 -3062.05357792 +7 1 8 1 2 9464.87591968 3057.76878318 3056.61188860 +7 1 8 1 3 1.46754220 1556.64450552 536.19921392 +7 1 8 1 4 0.29993563 -1557.48004049 -538.89863461 +7 1 8 1 5 1.55323809 537.67746810 1557.09440897 +7 1 8 1 6 -0.23566371 -538.53442705 -1557.82282407 +7 1 8 1 7 -74105.52504972 -72009.39275032 -72003.72610927 +7 1 8 1 8 74103.98252361 72014.89871156 72012.72417823 +7 1 8 2 1 -1.19974253 1557.89780798 3076.75042388 +7 1 8 2 2 -3055.27289024 889.05206086 -89.99140155 +7 1 8 2 3 -889.87688385 3061.52869056 91.39467183 +7 1 8 2 4 -1554.42712424 -0.72841511 -3072.88339663 +7 1 8 2 5 2.61372479 -533.64976105 3080.16754769 +7 1 8 2 6 538.73795480 0.04284795 -3077.21103932 +7 1 8 2 7 -67054.57394340 -72007.56100056 -80809.35422206 +7 1 8 2 8 72014.05246460 67033.43919334 80801.09528019 +7 1 8 3 1 -1.17831855 3077.85375853 1557.53360043 +7 1 8 3 2 -3059.64338088 -90.81622454 890.87309862 +7 1 8 3 3 -0.25708768 3076.91110368 -538.17021950 +7 1 8 3 4 534.92448748 -3075.04721797 -0.04284795 +7 1 8 3 5 -885.96700865 100.43558873 3064.57089483 +7 1 8 3 6 -1558.99043064 -3077.08249547 0.42847947 +7 1 8 3 7 -67039.02013849 -80811.04671598 -71996.72046987 +7 1 8 3 8 72010.21757330 80798.76006706 67021.50603999 +7 2 8 1 1 3061.46441864 -889.86617186 91.37324786 +7 2 8 1 2 -0.96407882 -1554.76990782 -3072.63702093 +7 2 8 1 3 1557.86567202 -1.17831855 3076.69686395 +7 2 8 1 4 890.36963524 -3057.09392801 -88.69525114 +7 2 8 1 5 -533.60691310 2.59230082 3080.12469974 +7 2 8 1 6 0.26779967 538.34161129 -3077.53239892 +7 2 8 1 7 -72007.04682520 -67049.91422912 -80809.05428642 +7 2 8 1 8 67031.82168333 72011.88864325 80799.62773799 +7 2 8 2 1 1556.58023360 1.55323809 536.14565398 +7 2 8 2 2 -1556.60165757 -0.32135961 -539.44494594 +7 2 8 2 3 -3061.47513063 -9466.54698963 -3062.00001798 +7 2 8 2 4 3057.98302291 9464.98303955 3056.51548071 +7 2 8 2 5 537.63462016 1.49967816 1557.11583294 +7 2 8 2 6 -538.33089930 -0.36420755 -1557.75855215 +7 2 8 2 7 -72011.71725146 -74105.63216959 -72003.80109318 +7 2 8 2 8 72015.85207839 74104.74307468 72013.35618545 +7 2 8 3 1 3076.88967971 -0.26779967 -538.13808354 +7 2 8 3 2 -3075.96844884 535.57791868 0.61058325 +7 2 8 3 3 3077.86447051 -1.24259047 1557.56573639 +7 2 8 3 4 -90.99832832 -3059.79334869 890.91594657 +7 2 8 3 5 100.46772470 -885.98843262 3064.54947085 +7 2 8 3 6 -3077.27531124 -1558.93687070 0.29993563 +7 2 8 3 7 -80809.00072649 -67039.17010631 -71996.87043768 +7 2 8 3 8 80797.98880400 72009.68197396 67020.93830468 +7 3 8 1 1 3061.33587480 90.63412076 -889.89830782 +7 3 8 1 2 -2.07812545 -3073.96530730 -1559.90094952 +7 3 8 1 3 -538.43801917 3076.65401600 0.08569589 +7 3 8 1 4 -1.16760657 -3075.53996937 535.94212623 +7 3 8 1 5 1554.07362867 3075.77563308 -1.56395008 +7 3 8 1 6 888.71998927 -90.28062520 -3062.77128104 +7 3 8 1 7 -71999.24849877 -80808.37943125 -67021.17396840 +7 3 8 1 8 67036.70634933 80805.06942731 71999.41989056 +7 3 8 2 1 3076.69686395 -538.44873116 0.01071199 +7 3 8 2 2 -3076.39692831 -0.52488736 536.62769339 +7 3 8 2 3 90.66625672 3061.27160288 -889.99471570 +7 3 8 2 4 -3074.17954704 -2.18524532 -1559.77240568 +7 3 8 2 5 3075.79705705 1554.11647662 -1.56395008 +7 3 8 2 6 -90.54842487 888.88066907 -3062.83555296 +7 3 8 2 7 -80805.93709825 -71999.17351486 -67021.20610436 +7 3 8 2 8 80804.11606048 67036.09576608 71998.86286724 +7 3 8 3 1 1559.49389402 535.68503855 2.06741346 +7 3 8 3 2 -1557.84424805 -537.94526778 2.73155665 +7 3 8 3 3 536.47772558 1558.70120699 2.50660492 +7 3 8 3 4 -536.31704577 -1559.49389402 3.87773924 +7 3 8 3 5 -3070.15183998 -3070.37679170 -9458.21306386 +7 3 8 3 6 3063.03908071 3062.51419335 9469.33210622 +7 3 8 3 7 -71995.11367184 -71990.98955690 -74109.30638108 +7 3 8 3 8 72000.34112143 72001.92649548 74087.11114432 +8 1 1 1 1 -74115.87282902 72001.84079958 72005.95420254 +8 1 1 1 2 9472.97418175 -3064.58160682 -3065.79206133 +8 1 1 1 3 0.61058325 -538.02025168 -1559.70813376 +8 1 1 1 4 -0.34278358 1558.20845560 535.83500637 +8 1 1 1 5 0.95336683 -1557.71570420 -539.81986547 +8 1 1 1 6 0.17139179 536.11351802 1557.82282407 +8 1 1 1 7 -9466.39702182 3061.81791421 3061.18590698 +8 1 1 1 8 74107.92453477 -71997.60956478 -71995.41360747 +8 1 1 2 1 72004.19743669 -67024.52682028 -80796.04993438 +8 1 1 2 2 -1.73534187 -1561.91480305 -3081.73149777 +8 1 1 2 3 537.77387599 -0.36420755 3077.46812700 +8 1 1 2 4 -889.37342047 -3066.02772504 -95.12244326 +8 1 1 2 5 -1553.40948549 -0.25708768 3070.09828004 +8 1 1 2 6 -0.66414318 536.75623723 -3077.03964753 +8 1 1 2 7 -3061.31445083 -889.88759583 90.81622454 +8 1 1 2 8 -67035.52803078 72006.32912208 80811.48590744 +8 1 1 3 1 72007.81808825 -80795.24653537 -67033.79268891 +8 1 1 3 2 -2.84938850 -3080.14612371 -1557.04084903 +8 1 1 3 3 -1558.03706381 3077.63951879 -0.36420755 +8 1 1 3 4 -1.43540624 -3078.11084621 538.19164347 +8 1 1 3 5 536.18850193 3076.65401600 -1.92815763 +8 1 1 3 6 -891.54795380 -92.59441436 -3061.18590698 +8 1 1 3 7 -3061.95717004 91.85528727 -890.47675511 +8 1 1 3 8 -67028.22245575 80799.92767362 72006.51122585 +8 2 1 1 1 67015.53946331 -72016.08774210 -80797.22825294 +8 2 1 1 2 3066.00630107 889.36270848 -95.10101928 +8 2 1 1 3 0.56773530 -538.53442705 3077.36100713 +8 2 1 1 4 1561.95765100 1.71391790 -3081.75292174 +8 2 1 1 5 891.74076956 3053.51612440 86.08152635 +8 2 1 1 6 -536.68125333 0.59987126 -3076.99679958 +8 2 1 1 7 -0.47132742 1557.60858433 3076.34336838 +8 2 1 1 8 -71998.56293161 67051.78882682 80811.25024373 +8 2 1 2 1 -72012.35997067 74112.81991276 72011.38517987 +8 2 1 2 2 -1558.18703163 0.32135961 535.82429438 +8 2 1 2 3 537.31326055 0.57844729 -1558.31557547 +8 2 1 2 4 3064.61374278 -9472.95275777 -3065.77063736 +8 2 1 2 5 -3057.07250403 9458.64154334 3054.80156282 +8 2 1 2 6 -536.15636597 -0.12854384 1557.80140010 +8 2 1 2 7 1557.84424805 0.82482299 -537.75245201 +8 2 1 2 8 72004.04746888 -74100.13692033 -71998.05946823 +8 2 1 3 1 -80797.45320466 72014.82372765 67032.58223439 +8 2 1 3 2 -3078.13227018 -1.45683021 -538.22377943 +8 2 1 3 3 3077.35029514 -1559.83667760 0.17139179 +8 2 1 3 4 -3080.15683570 -2.84938850 1557.11583294 +8 2 1 3 5 89.76644983 -3058.55075822 892.24423294 +8 2 1 3 6 -92.59441436 -891.51581784 3061.20733096 +8 2 1 3 7 3077.14676739 536.03853412 0.64271921 +8 2 1 3 8 80804.09463651 -67036.59922946 -72005.72925081 +8 3 1 1 1 67029.59359006 -80803.52690121 -72004.05818086 +8 3 1 1 2 3063.39257627 -92.84079006 888.77354920 +8 3 1 1 3 888.89138106 90.30204917 3062.64273719 +8 3 1 1 4 -539.39138600 -3078.51790171 0.25708768 +8 3 1 1 5 -2.19595730 3073.89032339 -536.13494200 +8 3 1 1 6 1557.82282407 -3077.12534342 0.44990345 +8 3 1 1 7 -0.53559934 3076.69686395 1559.55816594 +8 3 1 1 8 -71997.62027676 80811.11098790 67028.44740747 +8 3 1 2 1 -80800.98816032 67031.39320385 72003.26549384 +8 3 1 2 2 -3079.37486066 -540.05552919 -0.84624696 +8 3 1 2 3 90.69839269 888.90209304 -3062.92124885 +8 3 1 2 4 -92.99075787 3063.47827217 -888.88066907 +8 3 1 2 5 3071.98358973 -2.93508440 -1560.71506052 +8 3 1 2 6 -3077.31815918 1557.71570420 -0.32135961 +8 3 1 2 7 3077.96087839 0.64271921 536.33846975 +8 3 1 2 8 80810.05050120 -71999.13066691 -67026.02649844 +8 3 1 3 1 -72000.85529679 72000.30898546 74100.67251967 +8 3 1 3 2 -1559.30107826 536.35989372 2.35663711 +8 3 1 3 3 -3063.00694475 3062.57846527 9469.46065006 +8 3 1 3 4 -536.34918173 1559.30107826 2.33521313 +8 3 1 3 5 536.88478108 -1558.65835905 3.66349950 +8 3 1 3 6 3061.34658679 -3061.33587480 -9465.43294300 +8 3 1 3 7 1557.71570420 -537.85957188 2.19595730 +8 3 1 3 8 72003.68326132 -72000.76960090 -74115.27295775 +8 1 2 1 1 9471.68874332 -0.47132742 -2.07812545 +8 1 2 1 2 3.08505221 0.09640788 6.97350344 +8 1 2 1 3 -9471.73159127 0.38563153 -1.94958161 +8 1 2 1 4 -0.10711987 0.81411100 -0.23566371 +8 1 2 1 5 -9463.46193742 -1.19974253 5.78447290 +8 1 2 1 6 0.09640788 0.79268703 0.17139179 +8 1 2 1 7 9463.48336139 -0.40705550 -1.92815763 +8 1 2 1 8 -3.14932413 0.06427192 -6.81282364 +8 1 2 2 1 -3065.94202915 -1561.07926808 -3079.54625245 +8 1 2 2 2 0.08569589 -6.93065549 11785.04942412 +8 1 2 2 3 3066.04914901 1561.10069205 -3079.43913258 +8 1 2 2 4 0.05355993 0.21423974 2915.20295015 +8 1 2 2 5 -3055.74421766 1560.37227694 -3077.10391945 +8 1 2 2 6 0.19281576 -0.79268703 574.37673506 +8 1 2 2 7 3059.08635756 -1555.20909928 -3074.10456313 +8 1 2 2 8 -3.74919540 2.42090903 -2964.73517736 +8 1 2 3 1 -3069.41271289 -3080.59602716 -1556.45168975 +8 1 2 3 2 8.52674154 11786.34557453 2.33521313 +8 1 2 3 3 -3069.39128891 -3080.68172306 1556.58023360 +8 1 2 3 4 -0.18210378 573.04844869 1.09262266 +8 1 2 3 5 3062.64273719 -3077.98230237 1554.78061981 +8 1 2 3 6 1.40327028 2915.95278923 0.81411100 +8 1 2 3 7 3057.86519106 -3072.88339663 -1559.85810157 +8 1 2 3 8 8.37677372 -2963.10695536 0.85695895 +8 2 2 1 1 3063.22118448 -1558.52981520 -3077.96087839 +8 2 2 1 2 -2.91366042 -3.08505221 -2956.56193139 +8 2 2 1 3 -3063.26403243 1558.46554328 -3077.96087839 +8 2 2 1 4 0.43919146 0.85695895 573.51977611 +8 2 2 1 5 3060.88597135 1552.57395051 -3072.51918907 +8 2 2 1 6 0.21423974 -0.36420755 2914.21744736 +8 2 2 1 7 -3059.55768498 -1557.71570420 -3075.56139334 +8 2 2 1 8 0.89980690 7.61622265 11772.99843891 +8 2 2 2 1 886.30979223 0.12854384 -1.11404663 +8 2 2 2 2 -2.39948506 -0.18210378 8.79454121 +8 2 2 2 3 -886.50260799 -0.19281576 -0.98550279 +8 2 2 2 4 0.01071199 -0.14996782 -0.36420755 +8 2 2 2 5 -891.28015412 0.49275140 3.34213990 +8 2 2 2 6 0.03213596 -0.21423974 0.32135961 +8 2 2 2 7 891.25873015 0.19281576 -1.07119869 +8 2 2 2 8 2.31378916 -0.20352775 -8.88023710 +8 2 2 3 1 -94.45830007 535.51364676 -538.23449142 +8 2 2 3 2 -2956.65833927 4.53117044 3.13861215 +8 2 2 3 3 -92.20878283 535.40652689 538.17021950 +8 2 2 3 4 2915.34220598 0.08569589 1.41398226 +8 2 2 3 5 -98.03610368 -531.78587534 -539.54135382 +8 2 2 3 6 3374.43653853 0.85695895 0.34278358 +8 2 2 3 7 -88.48101141 -538.72724282 536.11351802 +8 2 2 3 8 -2959.82908738 -5.74162495 -1.52110213 +8 3 2 1 1 3061.52869056 -3078.06799826 -1558.95829468 +8 3 2 1 2 -3.85631527 -2959.50772777 -0.19281576 +8 3 2 1 3 3061.65723440 -3078.04657429 1559.06541455 +8 3 2 1 4 -0.51417537 2913.70327199 -0.83553497 +8 3 2 1 5 -3056.62260058 -3070.33394376 1562.40755445 +8 3 2 1 6 1.06048670 574.80521454 -1.28543842 +8 3 2 1 7 -3059.12920551 -3075.51854539 -1557.24437678 +8 3 2 1 8 -3.98485911 11773.03057487 -2.94579638 +8 3 2 2 1 -90.73052865 -539.07002640 536.45630160 +8 3 2 2 2 -2962.01433270 7.06991132 -0.17139179 +8 3 2 2 3 -90.75195262 -539.04860242 -536.62769339 +8 3 2 2 4 3371.58715003 -0.87838292 0.62129524 +8 3 2 2 5 -84.79608793 542.19792656 534.24963231 +8 3 2 2 6 2914.01391961 0.04284795 1.22116650 +8 3 2 2 7 -92.20878283 535.19228715 -537.82743592 +8 3 2 2 8 -2965.24935273 -5.73091297 1.93886962 +8 3 2 3 1 885.32428943 0.17139179 2.37806108 +8 3 2 3 2 -0.70699113 0.55702332 -3.27786798 +8 3 2 3 3 -885.36713738 -0.17139179 2.42090903 +8 3 2 3 4 0.70699113 -0.85695895 -1.86388571 +8 3 2 3 5 -892.32992884 0.47132742 -7.34842298 +8 3 2 3 6 -0.66414318 -0.87838292 1.90673366 +8 3 2 3 7 892.30850486 0.12854384 2.44233300 +8 3 2 3 8 0.79268703 0.46061543 3.22430804 +8 1 3 1 1 0.55702332 537.13115677 -1558.27272752 +8 1 3 1 2 -9472.95275777 3064.60303079 -3065.70636543 +8 1 3 1 3 74113.75185562 -72013.62398512 72012.23142683 +8 1 3 1 4 0.29993563 -1558.20845560 535.81358239 +8 1 3 1 5 9458.70581526 -3057.30816774 3054.71586692 +8 1 3 1 6 -0.20352775 -536.13494200 1557.86567202 +8 1 3 1 7 0.19281576 1556.93372916 -538.43801917 +8 1 3 1 8 -74100.38329603 72006.41481797 -71998.22014803 +8 1 3 2 1 -538.53442705 0.54631133 3077.36100713 +8 1 3 2 2 1.69249392 1561.93622702 -3081.71007379 +8 1 3 2 3 -72015.61641468 67015.13240781 -80796.83190942 +8 1 3 2 4 889.36270848 3066.02772504 -95.12244326 +8 1 3 2 5 3053.54826036 891.73005757 86.12437430 +8 1 3 2 6 0.58915928 -536.64911737 -3076.99679958 +8 1 3 2 7 1557.56573639 -0.43919146 3076.37550434 +8 1 3 2 8 67051.25322748 -71998.26299598 80810.76820432 +8 1 3 3 1 -1559.83667760 3077.26459925 0.17139179 +8 1 3 3 2 -2.89223645 -3080.19968365 1557.07298499 +8 1 3 3 3 72014.64162387 -80797.36750877 67032.40013062 +8 1 3 3 4 -1.43540624 -3078.11084621 -538.17021950 +8 1 3 3 5 -3058.51862226 89.87356970 892.17996102 +8 1 3 3 6 -891.52652982 -92.57299038 3061.12163506 +8 1 3 3 7 536.00639816 3077.10391945 0.62129524 +8 1 3 3 8 -67036.44926165 80803.96609267 -72005.49358710 +8 2 3 1 1 -0.34278358 537.85957188 3077.48955097 +8 2 3 1 2 -3065.96345312 -889.34128450 -95.09030729 +8 2 3 1 3 -67024.46254836 72004.09031682 -80795.88925458 +8 2 3 1 4 -1561.93622702 -1.77818982 -3081.75292174 +8 2 3 1 5 -0.21423974 -1553.40948549 3070.05543210 +8 2 3 1 6 536.67054134 -0.51417537 -3076.97537560 +8 2 3 1 7 -889.95186776 -3061.34658679 90.85907249 +8 2 3 1 8 72006.31841009 -67035.52803078 80811.49661943 +8 2 3 2 1 -538.06309963 0.41776749 -1559.62243786 +8 2 3 2 2 1558.16560765 -0.31064762 535.81358239 +8 2 3 2 3 72002.70847052 -74116.87975578 72006.74688956 +8 2 3 2 4 -3064.59231880 9472.95275777 -3065.77063736 +8 2 3 2 5 -1557.61929632 0.77126305 -539.90556137 +8 2 3 2 6 536.15636597 0.14996782 1557.77997612 +8 2 3 2 7 3061.20733096 -9467.33967666 3060.54318777 +8 2 3 2 8 -71997.89878842 74110.20618797 -71995.68140714 +8 2 3 3 1 3077.16819137 -1558.17631964 -0.47132742 +8 2 3 3 2 -3078.00372634 -1.34971034 538.38445924 +8 2 3 3 3 -80797.09970910 72009.10352667 -67037.19910073 +8 2 3 3 4 -3080.25324358 -2.95650837 -1556.88016923 +8 2 3 3 5 3074.86511419 534.99947139 -0.66414318 +8 2 3 3 6 -93.24784556 -890.85167465 -3060.28610009 +8 2 3 3 7 91.56606362 -3061.77506626 -890.29465133 +8 2 3 3 8 80804.97301943 -67028.86517496 72007.52886460 +8 3 3 1 1 888.43076562 91.44823176 -3061.82862619 +8 3 3 1 2 3063.32830435 -93.13001370 -889.01992490 +8 3 3 1 3 67032.64650632 -80802.16647888 72006.93970533 +8 3 3 1 4 -539.95912130 -3079.31058874 -1.02835074 +8 3 3 1 5 -1.86388571 3072.69058086 -1561.14354000 +8 3 3 1 6 1558.31557547 -3077.85375853 -1.19974253 +8 3 3 1 7 0.70699113 3077.73592667 536.39202968 +8 3 3 1 8 -72001.77652766 80810.60752452 -67028.96158284 +8 3 3 2 1 91.22328004 888.34506973 3061.85005017 +8 3 3 2 2 -3079.50340450 -539.91627336 0.93194286 +8 3 3 2 3 -80801.08456820 67027.49404064 -72004.24028464 +8 3 3 2 4 -92.38017462 3064.37807907 889.48054033 +8 3 3 2 5 3074.74728234 -1.67106995 -536.88478108 +8 3 3 2 6 -3077.22175130 1557.88709599 0.27851166 +8 3 3 2 7 3076.97537560 -0.48203941 1559.30107826 +8 3 3 2 8 80807.32965654 -71996.03490271 67029.37935033 +8 3 3 3 1 3062.49276938 -3063.22118448 9469.54634595 +8 3 3 3 2 1559.30107826 -536.37060571 2.34592512 +8 3 3 3 3 72001.01597660 -72001.60513587 74101.21883100 +8 3 3 3 4 536.31704577 -1559.32250223 2.35663711 +8 3 3 3 5 -1558.56195116 536.71338929 3.49210771 +8 3 3 3 6 -3061.32516281 3061.33587480 -9465.49721492 +8 3 3 3 7 -538.47015513 1556.80518532 1.57466207 +8 3 3 3 8 -72000.74817693 72005.72925081 -74115.16583788 +8 1 4 1 1 -0.21423974 -886.43833607 -1.15689458 +8 1 4 1 2 0.06427192 0.35349557 -0.42847947 +8 1 4 1 3 0.17139179 886.35264017 -1.11404663 +8 1 4 1 4 -0.78197504 -1.49967816 8.18395796 +8 1 4 1 5 0.47132742 -891.25873015 3.42783579 +8 1 4 1 6 -0.21423974 0.10711987 0.47132742 +8 1 4 1 7 0.10711987 889.07348483 -1.15689458 +8 1 4 1 8 0.42847947 3.35285189 -8.22680590 +8 1 4 2 1 1558.44411931 -3063.32830435 -3077.96087839 +8 1 4 2 2 0.68556716 0.12854384 573.69116790 +8 1 4 2 3 -1558.48696726 3063.37115230 -3077.98230237 +8 1 4 2 4 -1.78890180 -4.64900229 -2955.24435701 +8 1 4 2 5 1552.63822244 3060.92881930 -3072.79770073 +8 1 4 2 6 -0.17139179 -0.17139179 2914.15317544 +8 1 4 2 7 -1557.71570420 -3055.25146627 -3075.56139334 +8 1 4 2 8 6.38434416 -0.83553497 11771.72371247 +8 1 4 3 1 535.55649471 -94.39402815 538.29876334 +8 1 4 3 2 -0.04284795 2914.96728644 1.04977471 +8 1 4 3 3 535.49222279 -92.27305475 -538.42730718 +8 1 4 3 4 5.79518489 -2958.47937704 0.66414318 +8 1 4 3 5 -531.87157123 -93.75130894 -539.45565792 +8 1 4 3 6 0.86767094 3374.01877104 0.72841511 +8 1 4 3 7 -538.85578666 -88.45958743 536.02782213 +8 1 4 3 8 -6.98421543 -2961.69297309 0.98550279 +8 2 4 1 1 1561.10069205 3065.96345312 -3079.41770861 +8 2 4 1 2 0.10711987 0.12854384 2915.32078200 +8 2 4 1 3 -1561.18638794 -3068.14869844 -3079.35343669 +8 2 4 1 4 -5.72020098 0.10711987 11785.07084809 +8 2 4 1 5 1560.35085297 -3053.62324426 -3076.99679958 +8 2 4 1 6 -0.61058325 0.25708768 574.61239877 +8 2 4 1 7 -1555.25194723 3059.04350961 -3074.12598710 +8 2 4 1 8 1.09262266 -3.71705944 -2964.77802531 +8 2 4 2 1 0.47132742 -9471.71016730 -1.94958161 +8 2 4 2 2 0.77126305 -0.53559934 -0.18210378 +8 2 4 2 3 -0.38563153 9473.85256467 -1.97100558 +8 2 4 2 4 -0.04284795 1.26401445 6.94136748 +8 2 4 2 5 -1.24259047 -9463.44051345 5.57023316 +8 2 4 2 6 0.70699113 -0.25708768 0.19281576 +8 2 4 2 7 -0.25708768 9465.62575876 -1.92815763 +8 2 4 2 8 -0.04284795 -4.90608998 -6.87709556 +8 2 4 3 1 -3080.63887511 -3065.02079828 1556.40884181 +8 2 4 3 2 573.30553638 -0.71770312 1.17831855 +8 2 4 3 3 -3080.70314703 -3067.27031552 -1556.49453770 +8 2 4 3 4 11784.49240080 5.87016880 2.97793235 +8 2 4 3 5 -3078.08942224 3062.59988925 1554.52353212 +8 2 4 3 6 2915.73854949 0.92123087 0.72841511 +8 2 4 3 7 -3073.03336444 3057.90803901 -1559.90094952 +8 2 4 3 8 -2961.09310183 5.68806502 0.24637570 +8 3 4 1 1 -539.07002640 -90.68768070 -536.49914955 +8 3 4 1 2 -0.81411100 3371.80138976 0.61058325 +8 3 4 1 3 -538.96290653 -90.77337659 536.54199750 +8 3 4 1 4 6.39505615 -2961.07167785 0.47132742 +8 3 4 1 5 542.26219848 -86.98133325 534.27105629 +8 3 4 1 6 0.03213596 2914.26029531 1.17831855 +8 3 4 1 7 535.19228715 -92.14451091 -537.80601195 +8 3 4 1 8 -5.07748177 -2964.37096980 1.25330246 +8 3 4 2 1 -3078.02515032 3061.59296248 1559.12968647 +8 3 4 2 2 2913.78896788 -0.72841511 -1.11404663 +8 3 4 2 3 -3078.15369416 3063.73535985 -1559.06541455 +8 3 4 2 4 -2960.10759904 -4.77754614 -2.14239737 +8 3 4 2 5 -3070.33394376 -3054.41593129 1562.49325034 +8 3 4 2 6 574.69809467 0.87838292 -0.92123087 +8 3 4 2 7 -3075.53996937 -3061.37872275 -1557.39434460 +8 3 4 2 8 11773.69471805 -5.00249786 -1.03906272 +8 3 4 3 1 -0.12854384 -885.32428943 2.46375698 +8 3 4 3 2 -0.96407882 0.49275140 -2.00314154 +8 3 4 3 3 0.12854384 885.28144149 2.44233300 +8 3 4 3 4 1.17831855 -1.60679803 -3.92058719 +8 3 4 3 5 0.42847947 -890.12325954 -7.41269490 +8 3 4 3 6 -0.76055107 -0.89980690 1.99242955 +8 3 4 3 7 0.08569589 892.20138499 2.48518095 +8 3 4 3 8 -0.08569589 -0.18210378 3.88845123 +8 1 5 1 1 0.89980690 -1553.73084509 534.31390423 +8 1 5 1 2 -9463.14057781 -3055.47641799 3062.18212176 +8 1 5 1 3 9459.57348619 3053.17334082 -3057.88661503 +8 1 5 1 4 0.58915928 1552.59537449 -531.52878765 +8 1 5 1 5 73992.05297298 71805.66147236 -71878.46013501 +8 1 5 1 6 0.73912709 533.97112065 -1553.53802933 +8 1 5 1 7 0.89980690 -533.97112065 1555.41262703 +8 1 5 1 8 -73991.61378152 -71802.12651670 71869.40850612 +8 1 5 2 1 -1558.10133573 0.33207159 3074.74728234 +8 1 5 2 2 -1.60679803 1560.40441290 -3078.28223800 +8 1 5 2 3 -3056.03344131 891.13018631 90.62340878 +8 1 5 2 4 -889.84474789 3059.66480485 -93.70846099 +8 1 5 2 5 71807.34325429 66823.92344248 -80589.70493163 +8 1 5 2 6 0.24637570 -533.22128157 -3079.95330795 +8 1 5 2 7 537.69889208 2.87081248 3077.29673521 +8 1 5 2 8 -66839.71291110 -71805.01875315 80599.04578417 +8 1 5 3 1 -539.34853805 3069.46627282 -0.25708768 +8 1 5 3 2 5.72020098 -3077.06107150 1555.13411537 +8 1 5 3 3 3053.65538023 86.57427775 891.32300207 +8 1 5 3 4 3.88845123 -3073.18333226 -539.41280997 +8 1 5 3 5 -71878.03165554 -80588.86939666 66908.24820299 +8 1 5 3 6 884.22095479 -109.09087411 3073.52611584 +8 1 5 3 7 1558.22987957 3080.91738677 -2.52802890 +8 1 5 3 8 66911.63319084 80611.27887315 -71885.91567786 +8 2 5 1 1 891.73005757 -3056.87968827 90.04496149 +8 2 5 1 2 3059.68622882 -889.63050815 -93.72988496 +8 2 5 1 3 0.14996782 -1558.27272752 3074.57589055 +8 2 5 1 4 1559.78311767 -0.74983908 -3077.72521468 +8 2 5 1 5 66823.27001128 71804.16179420 -80589.04078845 +8 2 5 1 6 -533.32840144 0.40705550 -3079.99615590 +8 2 5 1 7 2.95650837 537.54892426 3077.41456707 +8 2 5 1 8 -71804.31176201 -66836.57429896 80598.45662489 +8 2 5 2 1 3053.08764492 9459.57348619 -3057.89732702 +8 2 5 2 2 1552.59537449 0.64271921 -531.58234758 +8 2 5 2 3 -1553.75226907 0.89980690 534.27105629 +8 2 5 2 4 -3055.48712998 -9463.14057781 3062.23568169 +8 2 5 2 5 71805.51150454 73991.95656510 -71878.31016719 +8 2 5 2 6 533.93898469 0.74983908 -1553.45233344 +8 2 5 2 7 -533.97112065 0.86767094 1555.40191504 +8 2 5 2 8 -71801.89085298 -73991.48523768 71869.25853830 +8 2 5 3 1 86.53142980 3053.69822817 891.32300207 +8 2 5 3 2 -3073.26902815 3.67421149 -539.56277779 +8 2 5 3 3 3069.42342487 -539.28426613 -0.32135961 +8 2 5 3 4 -3076.40764030 4.82039408 1554.50210815 +8 2 5 3 5 -80588.73014083 -71875.71786638 66908.07681120 +8 2 5 3 6 -109.02660219 884.03885101 3073.52611584 +8 2 5 3 7 3080.91738677 1558.20845560 -2.51731691 +8 2 5 3 8 80610.55045805 66910.65840003 -71885.03729494 +8 3 5 1 1 -2.52802890 3071.37300648 537.61319618 +8 3 5 1 2 -3054.18026758 -87.31340484 -890.29465133 +8 3 5 1 3 -4.50974647 3074.68301042 -1558.12275970 +8 3 5 1 4 542.73352590 -3070.69815131 -0.12854384 +8 3 5 1 5 -66915.01817868 -80608.27951684 71898.53439837 +8 3 5 1 6 -1555.05913146 -3081.62437790 -1.45683021 +8 3 5 1 7 -885.45283328 101.12115589 -3068.78070566 +8 3 5 1 8 71873.93967656 80600.67400617 -66917.49264764 +8 3 5 2 1 3073.46184392 -2.67799671 -1556.92301718 +8 3 5 2 2 -3070.71957528 542.75494987 -0.11783186 +8 3 5 2 3 3071.61938218 -2.16382134 537.89170784 +8 3 5 2 4 -87.32411683 -3054.11599566 -890.35892326 +8 3 5 2 5 -80607.59394968 -66913.73274026 71897.91310314 +8 3 5 2 6 -3081.61366591 -1555.05913146 -1.41398226 +8 3 5 2 7 100.92834013 -885.08862572 -3068.98423341 +8 3 5 2 8 80601.08106167 71870.16905719 -66918.14607884 +8 3 5 3 1 -536.79908518 -1559.33321422 3.94201116 +8 3 5 3 2 1563.07169763 534.27105629 -6.56644794 +8 3 5 3 3 -1560.16874919 -535.94212623 3.38498785 +8 3 5 3 4 533.46765727 1563.95008055 -6.06298456 +8 3 5 3 5 71892.70707753 71890.86461579 -74116.34415644 +8 3 5 3 6 -3071.10520681 -3070.84811912 9448.22949211 +8 3 5 3 7 3064.97795033 3065.24575000 -9458.18092790 +8 3 5 3 8 -71886.12991760 -71888.13305914 74131.61944969 +8 1 6 1 1 -0.04284795 -0.00000000 -890.03756365 +8 1 6 1 2 0.19281576 0.17139179 0.84624696 +8 1 6 1 3 -0.02142397 -0.00000000 -889.95186776 +8 1 6 1 4 -0.17139179 -0.08569589 0.89980690 +8 1 6 1 5 0.08569589 0.02142397 883.43897975 +8 1 6 1 6 -2.02456552 -1.79961379 3.55637964 +8 1 6 1 7 0.04284795 0.02142397 887.55238270 +8 1 6 1 8 2.01385353 1.77818982 3.70634745 +8 1 6 2 1 536.37060571 536.41345366 -91.33039991 +8 1 6 2 2 0.79268703 -0.58915928 2915.63142962 +8 1 6 2 3 -536.43487763 -536.49914955 -93.53706920 +8 1 6 2 4 0.06427192 -0.21423974 3374.36155462 +8 1 6 2 5 533.32840144 -533.30697747 -112.60440580 +8 1 6 2 6 -0.91051888 -3.53495566 -2951.64512942 +8 1 6 2 7 -537.97740374 537.95597976 -89.35939433 +8 1 6 2 8 4.84181806 -0.34278358 -2951.55943353 +8 1 6 3 1 1557.65143228 -3076.63259203 -3060.73600354 +8 1 6 3 2 0.29993563 574.86948646 1.08191067 +8 1 6 3 3 1557.65143228 -3076.65401600 3058.65787809 +8 1 6 3 4 0.48203941 2914.26029531 0.89980690 +8 1 6 3 5 -1554.35214033 -3080.42463537 3070.95523899 +8 1 6 3 6 3.80275533 -2950.76674650 -1.62822200 +8 1 6 3 7 -1558.67978302 -3077.06107150 -3062.21425772 +8 1 6 3 8 -6.81282364 11772.46283957 -7.05919934 +8 2 6 1 1 -536.37060571 -536.37060571 -91.33039991 +8 2 6 1 2 -0.08569589 0.14996782 3374.37226661 +8 2 6 1 3 536.37060571 536.39202968 -93.36567741 +8 2 6 1 4 -0.79268703 0.59987126 2915.67427757 +8 2 6 1 5 -533.24270555 533.28555349 -112.56155785 +8 2 6 1 6 -4.83110607 0.34278358 -2951.62370545 +8 2 6 1 7 537.97740374 -537.93455579 -89.35939433 +8 2 6 1 8 0.92123087 3.57780361 -2951.58085750 +8 2 6 2 1 0.04284795 0.08569589 -890.05898762 +8 2 6 2 2 0.06427192 -0.01071199 1.28543842 +8 2 6 2 3 0.06427192 0.02142397 -894.49375018 +8 2 6 2 4 -0.02142397 -0.00000000 1.24259047 +8 2 6 2 5 -0.02142397 -0.02142397 883.31043591 +8 2 6 2 6 -3.10647619 -0.79268703 5.52738522 +8 2 6 2 7 -0.14996782 0.04284795 887.57380667 +8 2 6 2 8 3.08505221 0.72841511 5.51667323 +8 2 6 3 1 -3076.71828792 1557.60858433 3060.73600354 +8 2 6 3 2 2914.19602338 0.54631133 0.54631133 +8 2 6 3 3 -3076.63259203 1557.67285626 -3058.65787809 +8 2 6 3 4 574.83735050 0.27851166 0.70699113 +8 2 6 3 5 -3080.46748332 -1554.39498828 3071.25517462 +8 2 6 3 6 -2950.77745849 3.87773924 -3.47068374 +8 2 6 3 7 -3076.95395163 -1558.63693507 -3062.14998580 +8 2 6 3 8 11772.51639950 -6.94136748 -8.90166107 +8 3 6 1 1 1557.65143228 -3076.71828792 3060.65030764 +8 3 6 1 2 0.55702332 2914.23887133 -0.85695895 +8 3 6 1 3 1557.54431241 -3076.76113587 -3058.65787809 +8 3 6 1 4 0.35349557 574.82663851 -1.11404663 +8 3 6 1 5 -1554.35214033 -3080.48890729 -3071.16947873 +8 3 6 1 6 -6.86638357 11772.53782347 7.11275927 +8 3 6 1 7 -1558.74405494 -3076.95395163 3062.21425772 +8 3 6 1 8 3.77061937 -2950.79888246 1.56395008 +8 3 6 2 1 -3076.73971189 1557.63000831 -3060.82169943 +8 3 6 2 2 574.82663851 0.50346338 -0.94265484 +8 3 6 2 3 -3076.71828792 1557.56573639 3058.65787809 +8 3 6 2 4 2914.24958332 0.47132742 -0.72841511 +8 3 6 2 5 -3080.44605934 -1554.43783623 -3071.12663078 +8 3 6 2 6 11773.15911871 -6.17010443 7.94829424 +8 3 6 2 7 -3077.08249547 -1558.65835905 3064.46377496 +8 3 6 2 8 -2951.45231366 3.20288407 2.52802890 +8 3 6 3 1 -0.00000000 0.04284795 -9469.88912953 +8 3 6 3 2 -1.32828637 1.16760657 3.02078029 +8 3 6 3 3 0.06427192 0.08569589 -9469.99624940 +8 3 6 3 4 1.24259047 -1.26401445 3.06362824 +8 3 6 3 5 -0.00000000 -0.00000000 9444.75880837 +8 3 6 3 6 9.36227651 9.38370048 8.56958948 +8 3 6 3 7 0.04284795 -0.04284795 9471.86013511 +8 3 6 3 8 -9.44797240 -9.38370048 8.52674154 +8 1 7 1 1 -9466.50414169 -3061.52869056 -3062.05357792 +8 1 7 1 2 9464.89734366 3057.79020715 3056.56904065 +8 1 7 1 3 1.48896617 1556.53738565 536.11351802 +8 1 7 1 4 0.27851166 -1557.43719255 -538.85578666 +8 1 7 1 5 1.49967816 537.65604413 1557.05156102 +8 1 7 1 6 -0.21423974 -538.55585103 -1557.82282407 +8 1 7 1 7 -74105.07514627 -72009.16779859 -72003.50115755 +8 1 7 1 8 74103.76828387 72014.65233586 72012.37068266 +8 1 7 2 1 3061.52869056 -889.86617186 91.33039991 +8 1 7 2 2 -0.96407882 -1554.76990782 -3072.66915689 +8 1 7 2 3 1557.90851997 -1.13547061 3076.78255984 +8 1 7 2 4 890.31607531 -3057.11535198 -88.71667512 +8 1 7 2 5 -533.64976105 2.63514877 3080.18897166 +8 1 7 2 6 0.26779967 538.38445924 -3077.53239892 +8 1 7 2 7 -72007.32533685 -67050.01063700 -80809.16140629 +8 1 7 2 8 67031.95022717 72012.04932306 80799.74556985 +8 1 7 3 1 3061.31445083 90.62340878 -889.91973179 +8 1 7 3 2 -2.05670148 -3073.98673127 -1559.90094952 +8 1 7 3 3 -538.45944314 3076.67543997 -0.06427192 +8 1 7 3 4 -1.16760657 -3075.49712142 535.85643034 +8 1 7 3 5 1554.15932457 3075.79705705 -1.60679803 +8 1 7 3 6 888.75212523 -90.34489712 -3062.77128104 +8 1 7 3 7 -71999.11995492 -80808.28302337 -67021.20610436 +8 1 7 3 8 67036.64207741 80805.02657937 71999.40917857 +8 2 7 1 1 -1.17831855 1557.91923195 3076.72899991 +8 2 7 1 2 -3056.21554508 889.73762802 -89.32725837 +8 2 7 1 3 -889.86617186 3061.48584261 91.35182388 +8 2 7 1 4 -1554.59851603 -0.87838292 -3072.73342881 +8 2 7 1 5 2.64586075 -533.58548913 3080.08185179 +8 2 7 1 6 538.55585103 0.17139179 -3077.38243110 +8 2 7 1 7 -67052.13161040 -72007.22892897 -80809.03286245 +8 2 7 1 8 72012.72417823 67032.37870664 80800.28116919 +8 2 7 2 1 1557.43719255 0.70699113 535.59934265 +8 2 7 2 2 -1556.55880962 -0.34278358 -539.48779388 +8 2 7 2 3 -3060.69315559 -9467.40394858 -3061.40014672 +8 2 7 2 4 3057.98302291 9464.96161558 3056.45120879 +8 2 7 2 5 537.92384380 1.28543842 1557.15868089 +8 2 7 2 6 -538.36303526 -0.34278358 -1557.77997612 +8 2 7 2 7 -72011.18165212 -74105.65359356 -72003.56542947 +8 2 7 2 8 72013.43116936 74106.77835218 72013.15265770 +8 2 7 3 1 3076.69686395 -538.40588321 -0.02142397 +8 2 7 3 2 -3076.46120024 -0.52488736 536.60626942 +8 2 7 3 3 90.66625672 3061.31445083 -889.90901981 +8 2 7 3 4 -3074.16883505 -2.18524532 -1559.68670978 +8 2 7 3 5 3075.79705705 1554.15932457 -1.54252611 +8 2 7 3 6 -90.54842487 888.79497318 -3062.87840091 +8 2 7 3 7 -80806.51554554 -71999.59128235 -67021.60244787 +8 2 7 3 8 80804.48026804 67036.44926165 71999.11995492 +8 3 7 1 1 -1.26401445 3077.82162257 1557.54431241 +8 3 7 1 2 -3059.64338088 -90.82693653 890.85167465 +8 3 7 1 3 -0.21423974 3076.86825574 -538.14879553 +8 3 7 1 4 534.91377550 -3075.11148989 -0.02142397 +8 3 7 1 5 -885.99914461 100.47843668 3064.57089483 +8 3 7 1 6 -1558.97971865 -3077.06107150 0.40705550 +8 3 7 1 7 -67039.08441041 -80810.96102008 -71996.66690993 +8 3 7 1 8 72010.17472536 80798.69579514 67021.52746396 +8 3 7 2 1 3076.82540779 -0.20352775 -538.14879553 +8 3 7 2 2 -3076.88967971 536.22063789 1.25330246 +8 3 7 2 3 3077.88589449 -1.22116650 1557.52288844 +8 3 7 2 4 -91.19114408 -3059.79334869 891.04449041 +8 3 7 2 5 100.47843668 -885.94558467 3064.48519893 +8 3 7 2 6 -3077.50026296 -1558.80832686 0.29993563 +8 3 7 2 7 -80806.79405720 -67039.27722618 -71996.83830172 +8 3 7 2 8 80797.19611698 72009.09281468 67020.41341733 +8 3 7 3 1 1559.60101389 535.57791868 2.20666929 +8 3 7 3 2 -1557.86567202 -537.98811572 2.71013267 +8 3 7 3 3 536.44558962 1558.76547892 2.76369261 +8 3 7 3 4 -536.30633379 -1559.49389402 3.83489129 +8 3 7 3 5 -3070.79455919 -3071.12663078 -9457.31325697 +8 3 7 3 6 3063.01765673 3062.55704130 9469.35353019 +8 3 7 3 7 -71994.68519237 -71990.52894147 -74108.67437385 +8 3 7 3 8 72000.57678514 72002.17287118 74085.15085072 +8 1 8 1 1 74108.80291769 -67033.86767282 -67025.90866658 +8 1 8 1 2 -3.74919540 -3.32071592 4.95964991 +8 1 8 1 3 -74100.09407238 67048.96086229 -67036.34214178 +8 1 8 1 4 -0.42847947 6.79139966 -9.49082035 +8 1 8 1 5 -73987.00762717 -66833.67135052 66912.89720528 +8 1 8 1 6 -0.13925583 4.88466601 -7.49839080 +8 1 8 1 7 74102.84705300 67030.41841305 67035.75298250 +8 1 8 1 8 -120.25276441 -220.12061784 125.99438937 +8 1 8 2 1 -71998.26299598 72006.72546559 80806.82619316 +8 1 8 2 2 2.37806108 0.43919146 -2960.32183877 +8 1 8 2 3 72005.60070697 -71997.25606921 80805.87282633 +8 1 8 2 4 3.72777142 -0.89980690 -2960.27899083 +8 1 8 2 5 -71805.23299288 -71800.56256662 80610.40049023 +8 1 8 2 6 2.89223645 1.84246174 11771.35950492 +8 1 8 2 7 72008.63219925 72013.14194571 80808.95787854 +8 1 8 2 8 -219.87424215 -223.70913344 -328883.09457524 +8 1 8 3 1 -71993.87108137 80814.38885588 72003.47973357 +8 1 8 3 2 -7.36984695 -2964.74588934 1.69249392 +8 1 8 3 3 -71999.11995492 80816.26345358 -72004.30455656 +8 1 8 3 4 -9.12661280 11771.27380902 1.07119869 +8 1 8 3 5 71865.80927854 80595.91788401 -71885.10156686 +8 1 8 3 6 4.52045845 -2952.73775208 -7.06991132 +8 1 8 3 7 72012.25285081 80801.49162371 72004.78659597 +8 1 8 3 8 127.02274010 -328881.83056079 -114.39330760 +8 2 8 1 1 -71998.07018021 72006.52193784 80806.55839349 +8 2 8 1 2 2.42090903 0.42847947 -2960.30041480 +8 2 8 1 3 72005.90064260 -71997.38461305 80806.12991401 +8 2 8 1 4 3.69563546 -0.92123087 -2960.30041480 +8 2 8 1 5 -71805.11516103 -71800.51971867 80610.42191421 +8 2 8 1 6 2.82796453 1.64964598 11771.55232068 +8 2 8 1 7 72008.50365541 72013.13123373 80808.89360662 +8 2 8 1 8 -220.30272162 -223.11997416 -328883.21240709 +8 2 8 2 1 67049.81782124 -74100.98316729 -67035.01385541 +8 2 8 2 2 5.20602561 0.99621478 -8.11968603 +8 2 8 2 3 -67033.01071387 74108.03165464 -67027.08698514 +8 2 8 2 4 -3.77061937 -4.13482693 5.03463382 +8 2 8 2 5 -66833.22144707 -73986.87908333 66912.57584568 +8 2 8 2 6 3.31000394 1.19974253 -7.77690246 +8 2 8 2 7 67035.07812733 74102.60067731 67035.88152634 +8 2 8 2 8 -223.36634986 -120.74551581 124.91247869 +8 2 8 3 1 80814.65665555 -71997.99519630 -72003.32976576 +8 2 8 3 2 11772.19503989 -9.80146797 1.74605386 +8 2 8 3 3 80814.47455177 -71994.53522455 72004.13316477 +8 2 8 3 4 -2964.61734550 -7.30557503 1.75676584 +8 2 8 3 5 80593.21846332 71865.81999052 -71885.20868673 +8 2 8 3 6 -2952.57707228 4.43476256 -7.13418324 +8 2 8 3 7 80799.57417806 72010.67818874 72003.22264589 +8 2 8 3 8 -328876.91375882 128.64025012 -115.12172271 +8 3 8 1 1 -71993.91392931 80810.03978921 72003.31905377 +8 3 8 1 2 -7.45554285 -2964.12459411 1.36042233 +8 3 8 1 3 -71999.54843440 80816.67050908 -72004.69018809 +8 3 8 1 4 -8.52674154 11773.97322971 -0.85695895 +8 3 8 1 5 71865.78785456 80595.98215593 -71885.25153468 +8 3 8 1 6 4.70256223 -2952.24500069 -6.83424761 +8 3 8 1 7 72012.25285081 80799.44563422 72004.86157988 +8 3 8 1 8 126.80850037 -328879.72029938 -112.21877427 +8 3 8 2 1 80814.24960005 -71997.29891716 -72002.78345443 +8 3 8 2 2 11773.09484679 -10.47632314 1.11404663 +8 3 8 2 3 80814.34600793 -71994.23528892 72004.04746888 +8 3 8 2 4 -2964.47808967 -7.15560722 1.56395008 +8 3 8 2 5 80594.00043836 71866.80549331 -71885.93710183 +8 3 8 2 6 -2952.52351235 4.39191461 -7.06991132 +8 3 8 2 7 80797.49605261 72010.98883636 72003.52258152 +8 3 8 2 8 -328876.37815948 126.85134831 -114.42544356 +8 3 8 3 1 67028.69378317 -67026.93701732 -74118.22946612 +8 3 8 3 2 -4.45618653 2.31378916 3.62065156 +8 3 8 3 3 -67026.84060944 67028.80090304 -74118.52940176 +8 3 8 3 4 1.44611823 -3.64207553 3.06362824 +8 3 8 3 5 -66906.88778066 -66906.98418854 74137.23253080 +8 3 8 3 6 1.30686240 1.67106995 3.85631527 +8 3 8 3 7 67020.44555329 67018.21746002 74090.72108389 +8 3 8 3 8 -113.37566885 -113.37566885 -1.74605386 diff --git a/examples/USER/phonon/third_order_command/silicon_input_file.lmp b/examples/USER/phonon/third_order_command/silicon_input_file.lmp new file mode 100755 index 0000000000..5066049895 --- /dev/null +++ b/examples/USER/phonon/third_order_command/silicon_input_file.lmp @@ -0,0 +1,29 @@ +LAMMPS description + + 8 atoms + 0 bonds + 0 angles + 0 dihedrals + 0 impropers + + 1 atom types + 0 bond types + 0 angle types + 0 dihedral types + 0 improper types + + + 0.0000000 5.4310000 xlo xhi + 0.0000000 5.4310000 ylo yhi + 0.0000000 5.4310000 zlo zhi + + Atoms + + 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 + 2 2 1 0.0000000 1.3577500 1.3577500 1.3572000 + 3 3 1 0.0000000 2.7155000 2.7155000 0.0000000 + 4 4 1 0.0000000 4.0732500 4.0732500 1.3572000 + 5 5 1 0.0000000 2.7155000 0.0000000 2.7144000 + 6 6 1 0.0000000 4.0732500 1.3577500 4.0732500 + 7 7 1 0.0000000 0.0000000 2.7155000 2.7155000 + 8 8 1 0.0000000 1.3577500 4.0732500 4.0732500 diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index d1b53eee01..3271a6ee37 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -244,7 +244,8 @@ void DynamicalMatrix::calculateMatrix() { int local_idx; // local index int local_jdx; // second local index - int natoms = atom->natoms; + int nlocal = atom->nlocal; + bigint natoms = atom->natoms; int *mask = atom->mask; int *type = atom->type; double imass; // dynamical matrix element @@ -262,13 +263,14 @@ void DynamicalMatrix::calculateMatrix() for (int i=1; i<=natoms; i++){ local_idx = atom->map(i); + //if (screen) fprintf(screen, "local idx = %i on proc %i with %i local\n",local_idx, comm->me, nlocal); if (local_idx >= 0){ for (int alpha=0; alpha<3; alpha++){ displace_atom(local_idx, alpha, 1); energy_force(0); for (int j=1; j<=natoms; j++){ local_jdx = atom->map(j); - if (local_jdx >= 0){ + if (local_jdx >= 0 && local_idx < nlocal){ for (int beta=0; beta<3; beta++){ dynmat[(i-1)*3+alpha][(j-1)*3+beta] += -f[j-1][beta]; } @@ -278,7 +280,7 @@ void DynamicalMatrix::calculateMatrix() energy_force(0); for (int j=1; j<=natoms; j++){ local_jdx = atom->map(j); - if (local_jdx >= 0){ + if (local_jdx >= 0 && local_idx < nlocal){ for (int beta=0; beta<3; beta++){ if (atom->rmass_flag == 1) imass = sqrt(m[i] * m[j]); @@ -365,31 +367,31 @@ void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) void DynamicalMatrix::energy_force(int resetflag) { - // check for reneighboring - // always communicate since atoms move - int nflag = neighbor->check_distance(); - - if (nflag == 0) { - //if (comm->me == 0 && screen) fprintf(screen,"b\n"); - timer->stamp(); - comm->forward_comm(); - timer->stamp(Timer::COMM); - //if (comm->me == 0 && screen) fprintf(screen,"c\n"); - } else { - if (triclinic) domain->x2lamda(atom->nlocal); - domain->pbc(); - if (domain->box_change) { - domain->reset_box(); - comm->setup(); - if (neighbor->style) neighbor->setup_bins(); - } - timer->stamp(); - comm->borders(); - if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); - timer->stamp(Timer::COMM); - neighbor->build(1); - timer->stamp(Timer::NEIGH); - } + //// check for reneighboring + //// always communicate since atoms move + //int nflag = neighbor->check_distance(); +// + //if (nflag == 0) { + ////if (comm->me == 0 && screen) fprintf(screen,"b\n"); + // timer->stamp(); + // comm->forward_comm(); + // timer->stamp(Timer::COMM); + ////if (comm->me == 0 && screen) fprintf(screen,"c\n"); + //} else { + // if (triclinic) domain->x2lamda(atom->nlocal); + // domain->pbc(); + // if (domain->box_change) { + // domain->reset_box(); + // comm->setup(); + // if (neighbor->style) neighbor->setup_bins(); + // } + // timer->stamp(); + // comm->borders(); + // if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); + // timer->stamp(Timer::COMM); + // neighbor->build(1); + // timer->stamp(Timer::NEIGH); + //} force_clear(); if (pair_compute_flag) { -- GitLab From 562bc4e5841be3785b8332e83e854f5bf98a2485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 2 Feb 2019 13:05:26 +0100 Subject: [PATCH 0097/1243] Update install.py --- python/install.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/install.py b/python/install.py index 9308506fd2..4c1560101e 100644 --- a/python/install.py +++ b/python/install.py @@ -36,7 +36,10 @@ if pydir: str = "cp ../src/liblammps.so %s" % pydir print(str) try: - shutil.copyfile("../src/liblammps.so", os.path.join(pydir,"liblammps.so") ) + if sys.platform == 'darwin': + shutil.copyfile("../src/liblammps.dylib", os.path.join(pydir,"liblammps.dylib") ) + else: + shutil.copyfile("../src/liblammps.so", os.path.join(pydir,"liblammps.so") ) except shutil.Error: pass # source and destination are identical sys.exit() -- GitLab From 7c2a61ad4c4a65fa94f21fac1ef4693f666fb6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 2 Feb 2019 17:55:09 +0100 Subject: [PATCH 0098/1243] Define lib_ext --- python/install.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/python/install.py b/python/install.py index 4c1560101e..2cd6562557 100644 --- a/python/install.py +++ b/python/install.py @@ -22,6 +22,11 @@ else: pydir = "" # copy lammps.py to pydir if it exists # if pydir not specified, install in site-packages via distutils setup() +if sys.platform == 'darwin': + lib_ext = ".dylib" +else: + lib_ext = ".so" + if pydir: if not os.path.isdir(pydir): print( "ERROR: pydir %s does not exist" % pydir) @@ -36,10 +41,7 @@ if pydir: str = "cp ../src/liblammps.so %s" % pydir print(str) try: - if sys.platform == 'darwin': - shutil.copyfile("../src/liblammps.dylib", os.path.join(pydir,"liblammps.dylib") ) - else: - shutil.copyfile("../src/liblammps.so", os.path.join(pydir,"liblammps.so") ) + shutil.copyfile("../src/liblammps" + lib_ext, os.path.join(pydir,"liblammps" + lib_ext) ) except shutil.Error: pass # source and destination are identical sys.exit() @@ -68,7 +70,7 @@ try: url = "http://lammps.sandia.gov", description = "LAMMPS molecular dynamics library", py_modules = ["lammps"], - data_files = [(get_python_lib(), ["../src/liblammps.so"])]) + data_files = [(get_python_lib(), ["../src/liblammps" + lib_ext])]) except: tryuser=True print ("Installation into global site-packages dir failed.\nTrying user site dir %s now." % site.USER_SITE) @@ -84,7 +86,7 @@ if tryuser: url = "http://lammps.sandia.gov", description = "LAMMPS molecular dynamics library", py_modules = ["lammps"], - data_files = [(site.USER_SITE, ["../src/liblammps.so"])]) + data_files = [(site.USER_SITE, ["../src/liblammps" + lib_ext])]) except: print("Installation into user site package dir failed.\nGo to ../python and install manually.") -- GitLab From 5c3e3f381bba628d781aa328b53745cc1ffff909 Mon Sep 17 00:00:00 2001 From: charlie sievers Date: Sun, 3 Feb 2019 09:13:37 -0800 Subject: [PATCH 0099/1243] added a groupmap --- src/USER-PHONON/dynamical_matrix.cpp | 124 ++++++++++++++++++--------- src/USER-PHONON/dynamical_matrix.h | 2 + 2 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index 3271a6ee37..a7d8620d00 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -40,6 +40,7 @@ DynamicalMatrix::DynamicalMatrix(LAMMPS *lmp) : Pointers(lmp), fp(NULL) DynamicalMatrix::~DynamicalMatrix() { if (fp && me == 0) fclose(fp); + memory->destroy(groupmap); memory->destroy(dynmat); memory->destroy(final_dynmat); fp = NULL; @@ -97,6 +98,13 @@ void DynamicalMatrix::setup() //modify->setup_pre_reverse(eflag,vflag); if (force->newton) comm->reverse_comm(); + + //if all then skip communication groupmap population + if (group->count(igroup) == atom->natoms) + for (int i=0; inatoms; i++) + groupmap[i] = i; + else + create_groupmap(); } /* ---------------------------------------------------------------------- */ @@ -126,6 +134,7 @@ void DynamicalMatrix::command(int narg, char **arg) if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); groupbit = group->bitmask[igroup]; dynlen = (group->count(igroup))*3; + memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); memory->create(dynmat,int(dynlen),int(dynlen),"dynamic_matrix:dynmat"); update->setupflag = 1; @@ -246,8 +255,8 @@ void DynamicalMatrix::calculateMatrix() int local_jdx; // second local index int nlocal = atom->nlocal; bigint natoms = atom->natoms; - int *mask = atom->mask; int *type = atom->type; + int *gm = groupmap; double imass; // dynamical matrix element double *m = atom->mass; double **f = atom->f; @@ -263,16 +272,15 @@ void DynamicalMatrix::calculateMatrix() for (int i=1; i<=natoms; i++){ local_idx = atom->map(i); - //if (screen) fprintf(screen, "local idx = %i on proc %i with %i local\n",local_idx, comm->me, nlocal); if (local_idx >= 0){ for (int alpha=0; alpha<3; alpha++){ displace_atom(local_idx, alpha, 1); energy_force(0); for (int j=1; j<=natoms; j++){ local_jdx = atom->map(j); - if (local_jdx >= 0 && local_idx < nlocal){ + if (local_jdx >= 0 && local_idx < nlocal && gm[i-1] >= 0 && gm[j-1] >= 0){ for (int beta=0; beta<3; beta++){ - dynmat[(i-1)*3+alpha][(j-1)*3+beta] += -f[j-1][beta]; + dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] += -f[j-1][beta]; } } } @@ -280,21 +288,15 @@ void DynamicalMatrix::calculateMatrix() energy_force(0); for (int j=1; j<=natoms; j++){ local_jdx = atom->map(j); - if (local_jdx >= 0 && local_idx < nlocal){ + if (local_jdx >= 0 && local_idx < nlocal && gm[i-1] >= 0 && gm[j-1] >= 0){ for (int beta=0; beta<3; beta++){ if (atom->rmass_flag == 1) - imass = sqrt(m[i] * m[j]); + imass = sqrt(m[local_idx] * m[local_jdx]); else - imass = sqrt(m[type[i]] * m[type[j]]); - //dynmat has length dynlen - //dynlen = (group->count(igroup))*3; - //currently dynmat is being called to natoms*3 - //Also with this implementation - //I am not recovering the correct dynamical matrix - //if I have more than 1 core - dynmat[(i-1)*3+alpha][(j-1)*3+beta] -= -f[j-1][beta]; - dynmat[(i-1)*3+alpha][(j-1)*3+beta] /= (2 * del * imass); - dynmat[(i-1)*3+alpha][(j-1)*3+beta] *= conversion; + imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); + dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] -= -f[j-1][beta]; + dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] /= (2 * del * imass); + dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] *= conversion; } } } @@ -367,31 +369,6 @@ void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) void DynamicalMatrix::energy_force(int resetflag) { - //// check for reneighboring - //// always communicate since atoms move - //int nflag = neighbor->check_distance(); -// - //if (nflag == 0) { - ////if (comm->me == 0 && screen) fprintf(screen,"b\n"); - // timer->stamp(); - // comm->forward_comm(); - // timer->stamp(Timer::COMM); - ////if (comm->me == 0 && screen) fprintf(screen,"c\n"); - //} else { - // if (triclinic) domain->x2lamda(atom->nlocal); - // domain->pbc(); - // if (domain->box_change) { - // domain->reset_box(); - // comm->setup(); - // if (neighbor->style) neighbor->setup_bins(); - // } - // timer->stamp(); - // comm->borders(); - // if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); - // timer->stamp(Timer::COMM); - // neighbor->build(1); - // timer->stamp(Timer::NEIGH); - //} force_clear(); if (pair_compute_flag) { @@ -489,3 +466,68 @@ void DynamicalMatrix::convert_units(const char *style) } else error->all(FLERR,"Units Type Conversion Not Found"); } + +/* ---------------------------------------------------------------------- */ + +void DynamicalMatrix::create_groupmap() +{ + //Create a group map which maps atom order onto group + + int local_idx; // local index + int gid = 0; //group index + int nlocal = atom->nlocal; + int *mask = atom->mask; + bigint natoms = atom->natoms; + int *recv = new int[comm->nprocs]; + int *displs = new int[comm->nprocs]; + int *temp_groupmap = new int[natoms]; + + //find number of local atoms in the group (final_gid) + for (int i=1; i<=natoms; i++){ + local_idx = atom->map(i); + if (mask[local_idx] & groupbit && local_idx < nlocal) + gid += 1; // gid at the end of loop is final_Gid + } + //create an array of length final_gid + int *sub_groupmap = new int[gid]; + + gid = 0; + //create a map between global atom id and group atom id for each proc + for (int i=1; i<=natoms; i++){ + local_idx = atom->map(i); + if (mask[local_idx] & groupbit && local_idx < nlocal){ + sub_groupmap[gid] = i; + gid += 1; + } + } + + //populate arrays for Allgatherv + for (int i=0; inprocs; i++){ + recv[i] = 0; + } + recv[comm->me] = gid; + MPI_Allreduce(recv,displs,4,MPI_INT,MPI_SUM,world); + for (int i=0; inprocs; i++){ + recv[i]=displs[i]; + if (i>0) displs[i] = displs[i-1]+recv[i-1]; + else displs[i] = 0; + } + + //combine subgroup maps into total temporary groupmap + MPI_Allgatherv(sub_groupmap,gid,MPI_INT,temp_groupmap,recv,displs,MPI_INT,world); + std::sort(temp_groupmap,temp_groupmap+group->count(igroup)); + + //populate member groupmap based on temp groupmap + for (int i=0; i Date: Sun, 3 Feb 2019 12:43:48 -0600 Subject: [PATCH 0100/1243] Some adjustments to kim Install.py --- lib/kim/Install.py | 173 +++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 92 deletions(-) diff --git a/lib/kim/Install.py b/lib/kim/Install.py index e7e2128f48..544fe2b65d 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -1,46 +1,43 @@ #!/usr/bin/env python -# install.py tool to download, compile, and setup the kim-api library -# used to automate the steps described in the README file in this dir +""" +Install.py tool to download, compile, and setup the kim-api library +used to automate the steps described in the README file in this dir +""" from __future__ import print_function -import sys,os,re,subprocess,shutil +import sys, os, subprocess, shutil +from argparse import ArgumentParser + sys.path.append('..') -from install_helpers import error,fullpath,which,geturl +from install_helpers import fullpath, geturl + +parser = ArgumentParser(prog='Install.py', + description="LAMMPS library build wrapper script") + +# settings + +thisdir = fullpath('.') +version = "kim-api-v2-2.0.0-beta.3" # help message -help = """ -Syntax from src dir: make lib-kim args="-b -v version -a kim-name" +HELP = """ +Syntax from src dir: make lib-kim args="-b -v version -a kim-name" or: make lib-kim args="-b -a everything" or: make lib-kim args="-n -a kim-name" - or: make lib-kim args="-p /home/bob/kim -a kim-name" -Syntax from lib dir: python Install.py -b -v version -a kim-name + or: make lib-kim args="-p /usr/local/open-kim -a kim-name" +Syntax from lib dir: python Install.py -b -v version -a kim-name or: python Install.py -b -a everything or: python Install.py -n -a kim-name - or: python Install.py -p /home/bob/kim -a kim-name - -specify one or more options, order does not matter - - -v = version of KIM API library to use - default = kim-api-v2.0.0-beta.3 (current as of December 2018) - -b = download and build base KIM API library with example Models - this will delete any previous installation in the current folder - -n = do NOT download and build base KIM API library. - Use an existing installation - -p = specify install prefix of KIM API installation (implies -n) - -a = add single KIM model or model driver with kim-name - to existing KIM API lib (see example below). - If kim-name = everything, then rebuild KIM API library with - *all* available OpenKIM Models (make take a long time). - -vv = be more verbose about what is happening while the script runs + or: python Install.py -p /usr/local/open-kim -a kim-name Examples: make lib-kim args="-b" # install KIM API lib with only example models -make lib-kim args="-a EAM_ErcolessiAdams_1994_Al__MO_324507536345_002" # Ditto plus one model +make lib-kim args="-b -a Glue_Ercolessi_Adams_Al__MO_324507536345_001" # Ditto plus one model make lib-kim args="-b -a everything" # install KIM API lib with all models -make lib-kim args="-n -a EAM_Dynamo_Ackland_2003_W__MO_141627196590_005" # only add one model or model driver +make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # only add one model or model driver See the list of KIM model drivers here: https://openkim.org/kim-items/model-drivers/alphabetical @@ -53,62 +50,49 @@ https://openkim.org/kim-api in the "What is in the KIM API source package?" section """ -# parse args - -args = sys.argv[1:] -nargs = len(args) -if nargs == 0: error(help=help) - -thisdir = fullpath('.') -version = "kim-api-v2-2.0.0-beta.3" - -buildflag = False +pgroup = parser.add_mutually_exclusive_group() +pgroup.add_argument("-b", "--build", action="store_true", + help="download and build base KIM API library with example Models.") +pgroup.add_argument("-n", "--nobuild", action="store_true", + help="use the previously downloaded and compiled base KIM API.") +pgroup.add_argument("-p", "--path", + help="specify location of existing KIM API installation.") +parser.add_argument("-v", "--version", default=version, + help="set version of KIM API library to download and build (default: %s)" % version) +parser.add_argument("-a", "--add", + help="add single KIM model or model driver. If adding 'everything', then all available OpenKIM models are added (may take a long time)") +parser.add_argument("-vv", "--verbose", action="store_true", + help="be more verbose about is happening while this script runs") + +args = parser.parse_args() + +# print help message and exit, if neither build nor path options are given +if not args.build and not args.path and not args.nobuild: + parser.print_help() + sys.exit(HELP) + +buildflag = args.build +pathflag = args.path is not None +addflag = args.add is not None +addmodelname = args.add everythingflag = False -addflag = False -verboseflag = False -pathflag = False - -iarg = 0 -while iarg < len(args): - if args[iarg] == "-v": - if iarg+2 > len(args): error(help=help) - version = args[iarg+1] - iarg += 2 - elif args[iarg] == "-b": - buildflag = True - iarg += 1 - elif args[iarg] == "-n": - buildflag = False - iarg += 1 - elif args[iarg] == "-p": - if iarg+2 > len(args): error(help=help) - kimdir = fullpath(args[iarg+1]) - pathflag = True - buildflag = False - iarg += 2 - elif args[iarg] == "-a": - addflag = True - if iarg+2 > len(args): error(help=help) - addmodelname = args[iarg+1] - if addmodelname == "everything": - buildflag = True - everythingflag = True - addflag = False - iarg += 2 - elif args[iarg] == "-vv": - verboseflag = True - iarg += 1 - else: error(help=help) +if addflag and addmodelname == "everything": + everythingflag = True + buildflag = True +verboseflag = args.verbose + +if pathflag: + buildflag = False + kimdir = args.path + if not os.path.isdir(kimdir): + sys.exit("KIM API path %s does not exist" % kimdir) + kimdir = fullpath(kimdir) url = "https://s3.openkim.org/kim-api/%s.txz" % version # set KIM API directory if pathflag: - if not os.path.isdir(kimdir): - print("\nkim-api is not installed at %s" % kimdir) - error(help=help) - # configure LAMMPS to use existing kim-api installation with open("%s/kim-prefix.txt" % thisdir, 'w') as pffile: pffile.write("%s" % kimdir) @@ -116,6 +100,8 @@ if pathflag: print("Created %s/kim-prefix.txt\n using %s" % (thisdir,kimdir)) else: kimdir = os.path.join(os.path.abspath(thisdir), "installed-" + version) + if args.nobuild and not os.path.isdir(kimdir): + sys.exit("Cannot use -n/--nobuild without first building the KIM API with -b") # download KIM tarball, unpack, build KIM if buildflag: @@ -136,10 +122,10 @@ if buildflag: # download entire kim-api tarball print("Downloading kim-api tarball ...") - geturl(url,"%s/%s.txz" % (thisdir,version)) + geturl(url, "%s/%s.txz" % (thisdir, version)) print("Unpacking kim-api tarball ...") - cmd = 'cd "%s"; rm -rf "%s"; tar -xJvf %s.txz' % (thisdir,version,version) - subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) + cmd = 'cd "%s"; rm -rf "%s"; tar -xJvf %s.txz' % (thisdir, version, version) + subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) # configure kim-api @@ -150,29 +136,32 @@ if buildflag: # build kim-api print("Building kim-api ...") - cmd = 'cd "%s/%s/build" && make' % (thisdir,version) - txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) - if verboseflag: print(txt.decode("UTF-8")) + cmd = 'cd "%s/%s/build" && make' % (thisdir, version) + txt = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) + if verboseflag: + print(txt.decode("UTF-8")) # install kim-api print("Installing kim-api ...") - cmd = 'cd "%s/%s/build" && make install' % (thisdir,version) - txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) - if verboseflag: print(txt.decode("UTF-8")) + cmd = 'cd "%s/%s/build" && make install' % (thisdir, version) + txt = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) + if verboseflag: + print(txt.decode("UTF-8")) # remove source files print("Removing kim-api source and build files ...") - cmd = 'cd "%s"; rm -rf %s; rm -rf %s.txz' % (thisdir,version,version) - subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) + cmd = 'cd "%s"; rm -rf %s; rm -rf %s.txz' % (thisdir, version, version) + subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) # add all OpenKIM models, if desired if everythingflag: print("Adding all OpenKIM models, this will take a while ...") cmd = '%s/bin/kim-api-v2-collections-management install system OpenKIM' % (kimdir) - txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) - if verboseflag: print(txt.decode("UTF-8")) + txt = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) + if verboseflag: + print(txt.decode("UTF-8")) # add single OpenKIM model if addflag: @@ -183,10 +172,10 @@ if addflag: kimdir = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) if not os.path.isdir(kimdir): - print("\nkim-api is not installed") - error(help=help) + sys.exit("\nkim-api is not installed") # download single model cmd = '%s/bin/kim-api-v2-collections-management install system %s' % (kimdir.decode("UTF-8"), addmodelname) - txt = subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True) - if verboseflag: print (txt.decode("UTF-8")) + txt = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) + if verboseflag: + print(txt.decode("UTF-8")) -- GitLab From b9d8b5f501d94034632333d988c1adb686ba3f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Mon, 4 Feb 2019 09:23:29 +0100 Subject: [PATCH 0101/1243] lib extension for Mac Os X --- python/lammps.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/python/lammps.py b/python/lammps.py index c393ee7ec7..3d5fc7a6b2 100644 --- a/python/lammps.py +++ b/python/lammps.py @@ -85,14 +85,19 @@ class lammps(object): # fall back to loading with a relative path, # typically requires LD_LIBRARY_PATH to be set appropriately + if sys.platform == 'darwin': + lib_ext = ".dylib" + else: + lib_ext = ".so" + if not self.lib: try: - if not name: self.lib = CDLL(join(modpath,"liblammps.so"),RTLD_GLOBAL) - else: self.lib = CDLL(join(modpath,"liblammps_%s.so" % name), + if not name: self.lib = CDLL(join(modpath,"liblammps" + lib_ext),RTLD_GLOBAL) + else: self.lib = CDLL(join(modpath,"liblammps_%s" % name + lib_ext), RTLD_GLOBAL) except: - if not name: self.lib = CDLL("liblammps.so",RTLD_GLOBAL) - else: self.lib = CDLL("liblammps_%s.so" % name,RTLD_GLOBAL) + if not name: self.lib = CDLL("liblammps" + lib_ext,RTLD_GLOBAL) + else: self.lib = CDLL("liblammps_%s" % name + lib_ext,RTLD_GLOBAL) # define ctypes API for each library method # NOTE: should add one of these for each lib function -- GitLab From 9915a6725f3c8ec3e66a86d8d49c1eb502d599db Mon Sep 17 00:00:00 2001 From: Theophile Chirac Date: Mon, 4 Feb 2019 17:21:59 +0100 Subject: [PATCH 0102/1243] Commit JT 020419 - correct in magelec (if iiall(FLERR,"Incorrect args in pair_style command"); - } /* ---------------------------------------------------------------------- @@ -287,7 +286,7 @@ void PairSpinMagelec::compute(int eflag, int vflag) // compute me interaction if (rsq <= local_cut2) { - compute_magelec(i,j,rsq,eij,fmi,spj); + compute_magelec(i,j,eij,fmi,spj); if (lattice_flag) { compute_magelec_mech(i,j,fi,spi,spj); } @@ -332,55 +331,63 @@ void PairSpinMagelec::compute_single_pair(int ii, double fmi[3]) double delx,dely,delz; double spj[3]; - int i,j,jnum,itype,jtype; + int i,j,inum,jnum,itype,jtype; int *ilist,*jlist,*numneigh,**firstneigh; double rsq, inorm; + inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; - i = ilist[ii]; - itype = type[i]; - - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xi[2] = x[i][2]; - - jlist = firstneigh[i]; - jnum = numneigh[i]; + // compute pair if - for (int jj = 0; jj < jnum; jj++) { + if (ii < inum) { - j = jlist[jj]; - j &= NEIGHMASK; - jtype = type[j]; - local_cut2 = cut_spin_magelec[itype][jtype]*cut_spin_magelec[itype][jtype]; - - spj[0] = sp[j][0]; - spj[1] = sp[j][1]; - spj[2] = sp[j][2]; - - delx = xi[0] - x[j][0]; - dely = xi[1] - x[j][1]; - delz = xi[2] - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - inorm = 1.0/sqrt(rsq); - eij[0] = -inorm*delx; - eij[1] = -inorm*dely; - eij[2] = -inorm*delz; - - if (rsq <= local_cut2) { - compute_magelec(i,j,rsq,eij,fmi,spj); + i = ilist[ii]; + itype = type[i]; + + xi[0] = xi[1] = xi[2] = 0.0; + xi[0] = x[i][0]; + xi[1] = x[i][1]; + xi[2] = x[i][2]; + + jlist = firstneigh[i]; + jnum = numneigh[i]; + + for (int jj = 0; jj < jnum; jj++) { + + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + local_cut2 = cut_spin_magelec[itype][jtype]*cut_spin_magelec[itype][jtype]; + + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + + delx = xi[0] - x[j][0]; + dely = xi[1] - x[j][1]; + delz = xi[2] - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + inorm = 1.0/sqrt(rsq); + eij[0] = -inorm*delx; + eij[1] = -inorm*dely; + eij[2] = -inorm*delz; + + if (rsq <= local_cut2) { + compute_magelec(i,j,eij,fmi,spj); + } + } + } - } } /* ---------------------------------------------------------------------- */ -void PairSpinMagelec::compute_magelec(int i, int j, double /*rsq*/, double eij[3], double fmi[3], double spj[3]) +void PairSpinMagelec::compute_magelec(int i, int j, double eij[3], double fmi[3], double spj[3]) { int *type = atom->type; int itype, jtype; diff --git a/src/SPIN/pair_spin_magelec.h b/src/SPIN/pair_spin_magelec.h index ce13476271..5e72a4c35e 100644 --- a/src/SPIN/pair_spin_magelec.h +++ b/src/SPIN/pair_spin_magelec.h @@ -37,7 +37,7 @@ class PairSpinMagelec : public PairSpin { void compute(int, int); void compute_single_pair(int, double *); - void compute_magelec(int, int, double, double *, double *, double *); + void compute_magelec(int, int, double *, double *, double *); void compute_magelec_mech(int, int, double *, double *, double *); void write_restart(FILE *); -- GitLab From 9fcd69921fd268bcec2d23d6ec519581f2a76794 Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 4 Feb 2019 11:27:00 -0700 Subject: [PATCH 0103/1243] Commit JT 020419 - neb/spin implemneted - rotational initial states to be implemented - climbing image to be implemented --- examples/SPIN/gneb_bfo/final.iron_spin | 64 ++-- examples/SPIN/gneb_bfo/in.neb.hop1 | 1 + examples/SPIN/gneb_bfo/in.neb.spin_iron | 82 +--- examples/SPIN/gneb_bfo/in.spin.iron | 4 +- src/REPLICA/fix_neb_spin.cpp | 481 +++++++++++++++--------- src/REPLICA/fix_neb_spin.h | 7 +- src/REPLICA/neb_spin.cpp | 455 +++++++++++++++++++--- src/REPLICA/neb_spin.h | 7 +- src/SPIN/pair_spin_exchange.cpp | 3 +- 9 files changed, 755 insertions(+), 349 deletions(-) diff --git a/examples/SPIN/gneb_bfo/final.iron_spin b/examples/SPIN/gneb_bfo/final.iron_spin index a921287ccb..aa1cbae770 100644 --- a/examples/SPIN/gneb_bfo/final.iron_spin +++ b/examples/SPIN/gneb_bfo/final.iron_spin @@ -1,36 +1,36 @@ 32 -2.2000000000000002e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 2.8664999999999998e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 5.7329999999999997e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 8.5994999999999990e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 0.0000000000000000e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 2.8664999999999998e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 5.7329999999999997e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 8.5994999999999990e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.4332499999999999e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 4.2997499999999995e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 7.1662499999999998e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.0032750000000000e+01 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 0.0000000000000000e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.4332499999999999e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 2.8664999999999998e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 4.2997499999999995e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 5.7329999999999997e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 7.1662499999999998e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 8.5994999999999990e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.0032750000000000e+01 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 0.0000000000000000e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 2.8664999999999998e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 5.7329999999999997e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 8.5994999999999990e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.4332499999999999e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 4.2997499999999995e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 7.1662499999999998e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2.2000000000000002e+00 1.0032750000000000e+01 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +1 2.2000000000000002e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +2 2.2000000000000002e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +3 2.2000000000000002e+00 2.8664999999999998e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +4 2.2000000000000002e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +5 2.2000000000000002e+00 5.7329999999999997e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +6 2.2000000000000002e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +7 2.2000000000000002e+00 8.5994999999999990e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +8 2.2000000000000002e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +9 2.2000000000000002e+00 0.0000000000000000e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +10 2.2000000000000002e+00 2.8664999999999998e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +11 2.2000000000000002e+00 5.7329999999999997e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +12 2.2000000000000002e+00 8.5994999999999990e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +13 2.2000000000000002e+00 1.4332499999999999e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +14 2.2000000000000002e+00 4.2997499999999995e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +15 2.2000000000000002e+00 7.1662499999999998e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +16 2.2000000000000002e+00 1.0032750000000000e+01 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +17 2.2000000000000002e+00 0.0000000000000000e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +18 2.2000000000000002e+00 1.4332499999999999e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +19 2.2000000000000002e+00 2.8664999999999998e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +20 2.2000000000000002e+00 4.2997499999999995e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +21 2.2000000000000002e+00 5.7329999999999997e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +22 2.2000000000000002e+00 7.1662499999999998e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +23 2.2000000000000002e+00 8.5994999999999990e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +24 2.2000000000000002e+00 1.0032750000000000e+01 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +25 2.2000000000000002e+00 0.0000000000000000e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +26 2.2000000000000002e+00 2.8664999999999998e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +27 2.2000000000000002e+00 5.7329999999999997e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +28 2.2000000000000002e+00 8.5994999999999990e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +29 2.2000000000000002e+00 1.4332499999999999e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +30 2.2000000000000002e+00 4.2997499999999995e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +31 2.2000000000000002e+00 7.1662499999999998e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 +32 2.2000000000000002e+00 1.0032750000000000e+01 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 diff --git a/examples/SPIN/gneb_bfo/in.neb.hop1 b/examples/SPIN/gneb_bfo/in.neb.hop1 index 4e203afd82..6697330faa 100644 --- a/examples/SPIN/gneb_bfo/in.neb.hop1 +++ b/examples/SPIN/gneb_bfo/in.neb.hop1 @@ -1,4 +1,5 @@ # 2d NEB surface simulation, hop from surface to become adatom +print "Test 1" dimension 2 boundary p s p diff --git a/examples/SPIN/gneb_bfo/in.neb.spin_iron b/examples/SPIN/gneb_bfo/in.neb.spin_iron index 6b99cd4639..2cf3a8653e 100644 --- a/examples/SPIN/gneb_bfo/in.neb.spin_iron +++ b/examples/SPIN/gneb_bfo/in.neb.spin_iron @@ -1,12 +1,12 @@ # bcc iron in a 3d periodic box +print "Test 1" -clear units metal -atom_style spin - dimension 3 boundary p p f +atom_style spin + # necessary for the serial algorithm (sametag) atom_modify map array @@ -20,7 +20,7 @@ read_data ../examples/SPIN/gneb_bfo/initial.iron_spin # setting mass, mag. moments, and interactions for bcc iron mass 1 55.845 -set group all spin 2.2 -1.0 0.0 0.0 +#set group all spin 2.2 -1.0 0.0 0.0 pair_style spin/exchange 3.5 pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 @@ -28,73 +28,13 @@ pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 -fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 -fix 2 all langevin/spin 0.0 0.0 21 -fix 2 nebatoms neb_spin 1.0 +fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 +#fix 2 all langevin/spin 0.0 0.0 21 +fix 2 all neb/spin 1.0 #parallel ideal -min_style quickmin -neb 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin - - -############################################################# - -# 2d NEB surface simulation, hop from surface to become adatom - - -variable u uloop 20 - -# create geometry with flat surface - -lattice hex 0.9 -region box block 0 20 0 10 -0.25 0.25 - -#create_box 3 box -#create_atoms 1 box -#mass * 1.0 -#write_data initial.hop1 - -read_data ../examples/SPIN/gneb_bfo/initial.hop1 - -# LJ potentials - -pair_style lj/cut 2.5 -pair_coeff * * 1.0 1.0 2.5 -pair_modify shift yes - -# initial minimization to relax surface - -minimize 1.0e-6 1.0e-4 1000 10000 -reset_timestep 0 - -# define groups - -region 1 block INF INF INF 1.25 INF INF -group lower region 1 -group mobile subtract all lower -set group lower type 2 - -timestep 0.05 - -# group of NEB atoms - either block or single atom ID 412 - -region surround block 10 18 17 20 0 0 units box -group nebatoms region surround -#group nebatoms id 412 -set group nebatoms type 3 -group nonneb subtract all nebatoms - -fix 1 lower setforce 0.0 0.0 0.0 -fix 2 nebatoms neb 1.0 parallel ideal -fix 3 all enforce2d - -thermo 100 - -#dump 1 nebatoms atom 10 dump.neb.$u -#dump 2 nonneb atom 10 dump.nonneb.$u - -# run NEB for 2000 steps or to force tolerance - -min_style quickmin +timestep 0.0001 -neb 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.hop1 +#min_style quickmin +neb/spin 0.0 0.1 1 1 1 final ../examples/SPIN/gneb_bfo/final.iron_spin +#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spin.iron b/examples/SPIN/gneb_bfo/in.spin.iron index 6d291c633b..0c84845f5f 100644 --- a/examples/SPIN/gneb_bfo/in.spin.iron +++ b/examples/SPIN/gneb_bfo/in.spin.iron @@ -19,7 +19,7 @@ create_atoms 1 box mass 1 55.845 -set group all spin 2.2 -1.0 0.0 0.0 +set group all spin 2.2 1.0 0.0 0.0 #velocity all create 100 4928459 rot yes dist gaussian pair_style spin/exchange 3.5 @@ -53,4 +53,4 @@ compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] run 0 -write_data final.iron_spin +write_data initial.iron_spin diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index a96af45267..150c37a03e 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -11,11 +11,6 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -/* ---------------------------------------------------------------------- - Contributing author for: Emile Maras (CEA, France) - new options for inter-replica forces, first/last replica treatment -------------------------------------------------------------------------- */ - #include #include #include @@ -392,6 +387,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) nlen = 0.0; double tlen = 0.0; double gradnextlen = 0.0; + double delndots, delpdots; dotgrad = gradlen = dotpath = dottangrad = 0.0; @@ -403,12 +399,20 @@ void FixNEB_spin::min_post_force(int /*vflag*/) for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { + // tangent vector delspxp = sp[i][0] - spprev[i][0]; delspyp = sp[i][1] - spprev[i][1]; delspzp = sp[i][2] - spprev[i][2]; - domain->minimum_image(delspxp,delspyp,delspzp); // check what it does - delsqp = delspxp*delspxp+delspyp*delspyp+delspzp*delspzp; + + // project delp vector on tangent space + delpdots = delspxp*sp[i][0]+delspyp*sp[i][1]+delspzp*sp[i][2]; + delspxp -= delpdots*sp[i][0]; + delspyp -= delpdots*sp[i][1]; + delspzp -= delpdots*sp[i][2]; + + // adjust distance if pbc + //domain->minimum_image(delspxp,delspyp,delspzp); // calc. geodesic length spi[0]=sp[i][0]; @@ -419,7 +423,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) spj[2]=spprev[i][2]; templen = geodesic_distance(spi, spj); plen += templen*templen; - dottangrad += delxp*fm[i][0]+ delyp*fm[i][1]+delzp*fm[i][2]; + dottangrad += delspxp*fm[i][0]+ delspyp*fm[i][1]+delspzp*fm[i][2]; gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; //plen += delxp*delxp + delyp*delyp + delzp*delzp; @@ -430,14 +434,14 @@ void FixNEB_spin::min_post_force(int /*vflag*/) // (unless FreeEnd option) if (FreeEndFinal||FreeEndFinalWithRespToEIni) { error->all(FLERR,"Free End option not yet active"); - tangent[i][0]=delspxp; - tangent[i][1]=delspyp; - tangent[i][2]=delspzp; - // if needed, tlen has to be modified - tlen += tangent[i][0]*tangent[i][0] + - tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - dot += fm[i][0]*tangent[i][0] + fm[i][1]*tangent[i][1] + - fm[i][2]*tangent[i][2]; + //tangent[i][0]=delspxp; + //tangent[i][1]=delspyp; + //tangent[i][2]=delspzp; + //// if needed, tlen has to be modified + //tlen += tangent[i][0]*tangent[i][0] + + // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + //dot += fm[i][0]*tangent[i][0] + fm[i][1]*tangent[i][1] + + // fm[i][2]*tangent[i][2]; } @@ -469,9 +473,16 @@ void FixNEB_spin::min_post_force(int /*vflag*/) delspxn = spnext[i][0]- sp[i][0]; delspyn = spnext[i][1]- sp[i][1]; delspzn = spnext[i][2]- sp[i][2]; - domain->minimum_image(delspxn,delspyn,delspzn); // check what it does - delsqn = delspxn*delspxn+delspyn*delspyn+delspzn*delspzn; + // project deln vector on tangent space + delndots = delspxn*sp[i][0]+delspyn*sp[i][1]+delspzn*sp[i][2]; + delspxn -= delndots*sp[i][0]; + delspyn -= delndots*sp[i][1]; + delspzn -= delndots*sp[i][2]; + + // adjust del. if pbc + //domain->minimum_image(delspxn,delspyn,delspzn); + // calc. geodesic length spi[0]=sp[i][0]; spi[1]=sp[i][1]; @@ -485,14 +496,14 @@ void FixNEB_spin::min_post_force(int /*vflag*/) gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; if (FreeEndIni) { error->all(FLERR,"Free End option not yet active"); - tangent[i][0]=delxn; - tangent[i][1]=delyn; - tangent[i][2]=delzn; - // if needed, tlen has to be modified - tlen += tangent[i][0]*tangent[i][0] + - tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + - f[i][2]*tangent[i][2]; + //tangent[i][0]=delxn; + //tangent[i][1]=delyn; + //tangent[i][2]=delzn; + //// if needed, tlen has to be modified + //tlen += tangent[i][0]*tangent[i][0] + + // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + //dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + + // f[i][2]*tangent[i][2]; } //delxn = xnext[i][0] - x[i][0]; @@ -528,10 +539,20 @@ void FixNEB_spin::min_post_force(int /*vflag*/) for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { - delspxp = spx[i][0] - spxprev[i][0]; - delspyp = spx[i][1] - spxprev[i][1]; - delspzp = spx[i][2] - spxprev[i][2]; - domain->minimum_image(delspxp,delspyp,delspzp); + + // calc. delp vector + delspxp = sp[i][0] - spprev[i][0]; + delspyp = sp[i][1] - spprev[i][1]; + delspzp = sp[i][2] - spprev[i][2]; + + // project delp vector on tangent space + delndots = delspxp*sp[i][0]+delspyp*sp[i][1]+delspzp*sp[i][2]; + delspxp -= delpdots*sp[i][0]; + delspyp -= delpdots*sp[i][1]; + delspzp -= delpdots*sp[i][2]; + + // adjust distance if pbc + //domain->minimum_image(delspxp,delspyp,delspzp); // calc. geodesic length spi[0]=sp[i][0]; @@ -543,10 +564,19 @@ void FixNEB_spin::min_post_force(int /*vflag*/) templen = geodesic_distance(spi, spj); plen += templen*templen; - delspxn = spxnext[i][0] - spx[i][0]; - delspyn = spxnext[i][1] - spx[i][1]; - delspzn = spxnext[i][2] - spx[i][2]; - domain->minimum_image(delspxn,delspyn,delspzn); + // calc. deln vector + delspxn = spnext[i][0] - sp[i][0]; + delspyn = spnext[i][1] - sp[i][1]; + delspzn = spnext[i][2] - sp[i][2]; + + // project deln vector on tangent space + delndots = delspxn*sp[i][0]+delspyn*sp[i][1]+delspzn*sp[i][2]; + delspxn -= delndots*sp[i][0]; + delspyn -= delndots*sp[i][1]; + delspzn -= delndots*sp[i][2]; + + // adjust distance if pbc + //domain->minimum_image(delspxn,delspyn,delspzn); if (vnext > veng && veng > vprev) { tangent[i][0] = delspxn; @@ -593,63 +623,11 @@ void FixNEB_spin::min_post_force(int /*vflag*/) dotgrad += fm[i][0]*fnext[i][0] + fm[i][1]*fnext[i][1] + fm[i][2]*fnext[i][2]; - // is this a perpandicular spring force? + // no Perpendicular nudging force option active yet + // see fix_neb for example if (kspringPerp != 0.0) - error->all(FLERR,"Perpendicular nudging force not yet active"); - //springF[i][0] = kspringPerp*(delxn-delxp); - //springF[i][1] = kspringPerp*(delyn-delyp); - //springF[i][2] = kspringPerp*(delzn-delzp); + error->all(FLERR,"NEB_spin Perpendicular nudging force not yet active"); - //delxp = x[i][0] - xprev[i][0]; - //delyp = x[i][1] - xprev[i][1]; - //delzp = x[i][2] - xprev[i][2]; - //domain->minimum_image(delxp,delyp,delzp); - //plen += delxp*delxp + delyp*delyp + delzp*delzp; - - //delxn = xnext[i][0] - x[i][0]; - //delyn = xnext[i][1] - x[i][1]; - //delzn = xnext[i][2] - x[i][2]; - //domain->minimum_image(delxn,delyn,delzn); - - //if (vnext > veng && veng > vprev) { - // tangent[i][0] = delxn; - // tangent[i][1] = delyn; - // tangent[i][2] = delzn; - //} else if (vnext < veng && veng < vprev) { - // tangent[i][0] = delxp; - // tangent[i][1] = delyp; - // tangent[i][2] = delzp; - //} else { - // if (vnext > vprev) { - // tangent[i][0] = vmax*delxn + vmin*delxp; - // tangent[i][1] = vmax*delyn + vmin*delyp; - // tangent[i][2] = vmax*delzn + vmin*delzp; - // } else if (vnext < vprev) { - // tangent[i][0] = vmin*delxn + vmax*delxp; - // tangent[i][1] = vmin*delyn + vmax*delyp; - // tangent[i][2] = vmin*delzn + vmax*delzp; - // } else { // vnext == vprev, e.g. for potentials that do not compute an energy - // tangent[i][0] = delxn + delxp; - // tangent[i][1] = delyn + delyp; - // tangent[i][2] = delzn + delzp; - // } - //} - - //nlen += delxn*delxn + delyn*delyn + delzn*delzn; - //tlen += tangent[i][0]*tangent[i][0] + - // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; - //dotpath += delxp*delxn + delyp*delyn + delzp*delzn; - //dottangrad += tangent[i][0]*f[i][0] + - // tangent[i][1]*f[i][1] + tangent[i][2]*f[i][2]; - //gradnextlen += fnext[i][0]*fnext[i][0] + - // fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2]; - //dotgrad += f[i][0]*fnext[i][0] + f[i][1]*fnext[i][1] + - // f[i][2]*fnext[i][2]; - - //springF[i][0] = kspringPerp*(delxn-delxp); - //springF[i][1] = kspringPerp*(delyn-delyp); - //springF[i][2] = kspringPerp*(delzn-delzp); } } @@ -675,6 +653,24 @@ void FixNEB_spin::min_post_force(int /*vflag*/) dottangrad = bufout[6]; dotgrad = bufout[7]; + + // project tangent vector on tangent space + + double buftan[3]; + double tandots; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + tandots = tangent[i][0]*sp[i][0]+tangent[i][1]*sp[i][1]+ + tangent[i][2]*sp[i][2]; + buftan[0] = tangent[i][0]-tandots*sp[i][0]; + buftan[1] = tangent[i][1]-tandots*sp[i][1]; + buftan[2] = tangent[i][2]-tandots*sp[i][2]; + tangent[i][0] = buftan[0]; + tangent[i][1] = buftan[1]; + tangent[i][2] = buftan[2]; + } + + // normalize tangent vector if (tlen > 0.0) { @@ -687,8 +683,6 @@ void FixNEB_spin::min_post_force(int /*vflag*/) } } -//////////////////////////////////////////////////////// - // first or last replica has no change to forces, just return if (ireplica > 0 && ireplica < nreplica-1) @@ -700,93 +694,31 @@ void FixNEB_spin::min_post_force(int /*vflag*/) if (ireplica < nreplica-1) dotgrad = dotgrad /(gradlen*gradnextlen); + // no Free End option active yet + // see fix_neb for example if (FreeEndIni && ireplica == 0) { - if (tlen > 0.0) { - double dotall; - MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); - dot=dotall/tlen; - - if (dot<0) prefactor = -dot - kspringIni*(veng-EIniIni); - else prefactor = -dot + kspringIni*(veng-EIniIni); - - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - f[i][0] += prefactor *tangent[i][0]; - f[i][1] += prefactor *tangent[i][1]; - f[i][2] += prefactor *tangent[i][2]; - } - } + error->all(FLERR,"NEB_spin Free End option not yet active"); } + // no Free End option active yet + // see fix_neb for example if (FreeEndFinal && ireplica == nreplica -1) { - if (tlen > 0.0) { - double dotall; - MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); - dot=dotall/tlen; - - if (vengall(FLERR,"NEB_spin Free End option not yet active"); } + // no Free End option active yet + // see fix_neb for example if (FreeEndFinalWithRespToEIni&&ireplica == nreplica -1) { - if (tlen > 0.0) { - double dotall; - MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); - dot=dotall/tlen; - if (vengall(FLERR,"NEB_spin Free End option not yet active"); } + // no NEB_spin long range option + // see fix_neb for example double lentot = 0; double meanDist,idealPos,lenuntilIm,lenuntilClimber; lenuntilClimber=0; if (NEBLongRange) { - if (cmode == SINGLE_PROC_DIRECT || cmode == SINGLE_PROC_MAP) { - MPI_Allgather(&nlen,1,MPI_DOUBLE,&nlenall[0],1,MPI_DOUBLE,uworld); - } else { - if (me == 0) - MPI_Allgather(&nlen,1,MPI_DOUBLE,&nlenall[0],1,MPI_DOUBLE,rootworld); - MPI_Bcast(nlenall,nreplica,MPI_DOUBLE,0,world); - } - - lenuntilIm = 0; - for (int i = 0; i < ireplica; i++) - lenuntilIm += nlenall[i]; - - for (int i = 0; i < nreplica; i++) - lentot += nlenall[i]; - - meanDist = lentot/(nreplica -1); - - if (rclimber>0) { - for (int i = 0; i < rclimber; i++) - lenuntilClimber += nlenall[i]; - double meanDistBeforeClimber = lenuntilClimber/rclimber; - double meanDistAfterClimber = - (lentot-lenuntilClimber)/(nreplica-rclimber-1); - if (ireplicaall(FLERR,"NEB_spin long range option not yet active"); } if (ireplica == 0 || ireplica == nreplica-1) return ; @@ -800,12 +732,19 @@ void FixNEB_spin::min_post_force(int /*vflag*/) for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { - dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + - f[i][2]*tangent[i][2]; - dotSpringTangent += springF[i][0]*tangent[i][0] + + dot += fm[i][0]*tangent[i][0] + fm[i][1]*tangent[i][1] + + fm[i][2]*tangent[i][2]; + // springF defined for perp. spring option + // not defined here + //dotSpringTangent += springF[i][0]*tangent[i][0] + springF[i][1]*tangent[i][1] + springF[i][2]*tangent[i][2];} + //dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + + // f[i][2]*tangent[i][2]; + //dotSpringTangent += springF[i][0]*tangent[i][0] + + // springF[i][1]*tangent[i][1] + springF[i][2]*tangent[i][2];} } + // gather all dot and dotSpring for this replica (world) double dotSpringTangentall; MPI_Allreduce(&dotSpringTangent,&dotSpringTangentall,1, MPI_DOUBLE,MPI_SUM,world); @@ -814,20 +753,26 @@ void FixNEB_spin::min_post_force(int /*vflag*/) MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); dot=dotall; - if (ireplica == rclimber) prefactor = -2.0*dot; - else { + + // implement climbing image here + + if (ireplica == rclimber) { + error->all(FLERR,"NEB_spin climber option not yet active"); + //prefactor = -2.0*dot; + } else { if (NEBLongRange) { - prefactor = -dot - kspring*(lenuntilIm-idealPos)/(2*meanDist); + error->all(FLERR,"NEB_spin climber option not yet active"); + //prefactor = -dot - kspring*(lenuntilIm-idealPos)/(2*meanDist); } else if (StandardNEB) { prefactor = -dot + kspring*(nlen-plen); } if (FinalAndInterWithRespToEIni&& vengsametag; + int nlocal = atom->nlocal; + int *mask = atom->mask; + double **sp = atom->sp; + double **fm = atom->fm; + double tdampx,tdampy,tdampz; + double msq,scale,fm2,energy,dts2; + double alpha; + double spi[3],fmi[3]; + double cp[3],g[3]; + + //cp[0] = cp[1] = cp[2] = 0.0; + //g[0] = g[1] = g[2] = 0.0; + dts2 = dts*dts; + + // fictitious Gilbert damping of 1 + alpha = 1.0; + + // loop on all spins on proc. + + if (ireplica != nreplica-1 && ireplica != 0) + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + + fmi[0] = fm[i][0]; + fmi[1] = fm[i][1]; + fmi[2] = fm[i][2]; + + // calc. damping torque + + tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); + tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); + tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); + + // apply advance algorithm (geometric, norm preserving) + + fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); + energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); + + cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; + cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; + cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; + + g[0] = sp[i][0]+cp[0]*dts; + g[1] = sp[i][1]+cp[1]*dts; + g[2] = sp[i][2]+cp[2]*dts; + + g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; + g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; + g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; + + g[0] /= (1+0.25*fm2*dts2); + g[1] /= (1+0.25*fm2*dts2); + g[2] /= (1+0.25*fm2*dts2); + + sp[i][0] = g[0]; + sp[i][1] = g[1]; + sp[i][2] = g[2]; + + // renormalization (check if necessary) + + msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; + scale = 1.0/sqrt(msq); + sp[i][0] *= scale; + sp[i][1] *= scale; + sp[i][2] *= scale; + + // comm. sp[i] to atoms with same tag (for serial algo) + + // no need for simplecticity + //if (sector_flag == 0) { + // if (sametag[i] >= 0) { + // j = sametag[i]; + // while (j >= 0) { + // sp[j][0] = sp[i][0]; + // sp[j][1] = sp[i][1]; + // sp[j][2] = sp[i][2]; + // j = sametag[j]; + // } + // } + //} + // + + } +} + +/* ---------------------------------------------------------------------- + evaluate max timestep +---------------------------------------------------------------------- */ + +double FixNEB_spin::evaluate_dt() +{ + double dtmax; + double fmsq; + double fmaxsqone,fmaxsqloc,fmaxsqall; + int nlocal = atom->nlocal; + int *mask = atom->mask; + double **fm = atom->fm; + + // finding max fm on this proc. + + fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) { + fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; + fmaxsqone = MAX(fmaxsqone,fmsq); + } + + // finding max fm on this replica + + fmaxsqloc = fmaxsqone; + MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); + + // finding max fm over all replicas, if necessary + // this communicator would be invalid for multiprocess replicas + + if (update->multireplica == 1) { + fmaxsqall = fmaxsqloc; + MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); + } + + if (fmaxsqall < fmaxsqloc) + error->all(FLERR,"Incorrect fmaxall calc."); + + // define max timestep + // dividing by 10 the inverse of max frequency + + dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); + + return dtmax; +} + /* ---------------------------------------------------------------------- send/recv NEB atoms to/from adjacent replicas received atoms matching my local atoms are stored in xprev,xnext @@ -913,19 +1018,25 @@ void FixNEB_spin::inter_replica_comm() if (cmode == SINGLE_PROC_DIRECT) { if (ireplica > 0) MPI_Irecv(xprev[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld,&request); + MPI_Irecv(spprev[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld,&request); if (ireplica < nreplica-1) MPI_Send(x[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld); + MPI_Send(sp[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld); if (ireplica > 0) MPI_Wait(&request,MPI_STATUS_IGNORE); if (ireplica < nreplica-1) MPI_Irecv(xnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request); + MPI_Irecv(spnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request); if (ireplica > 0) MPI_Send(x[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(sp[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld); if (ireplica < nreplica-1) MPI_Wait(&request,MPI_STATUS_IGNORE); if (ireplica < nreplica-1) MPI_Irecv(fnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request); + MPI_Irecv(fmnext[0],3*nlocal,MPI_DOUBLE,procnext,0,uworld,&request); if (ireplica > 0) MPI_Send(f[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld); + MPI_Send(fm[0],3*nlocal,MPI_DOUBLE,procprev,0,uworld); if (ireplica < nreplica-1) MPI_Wait(&request,MPI_STATUS_IGNORE); return; @@ -1077,7 +1188,7 @@ void FixNEB_spin::inter_replica_comm() fmsendall[0],counts,displacements,MPI_DOUBLE,0,world); } else { MPI_Gatherv(NULL,3*m,MPI_DOUBLE, - xsendall[0],counts,displacements,MPI_DOUBLE,0,world); + spsendall[0],counts,displacements,MPI_DOUBLE,0,world); MPI_Gatherv(NULL,3*m,MPI_DOUBLE, fmsendall[0],counts,displacements,MPI_DOUBLE,0,world); } diff --git a/src/REPLICA/fix_neb_spin.h b/src/REPLICA/fix_neb_spin.h index e3bdd6889d..291341860e 100644 --- a/src/REPLICA/fix_neb_spin.h +++ b/src/REPLICA/fix_neb_spin.h @@ -13,8 +13,8 @@ #ifdef FIX_CLASS -FixStyle(neb,FixNEB) -FixStyle(neb_spin,FixNEB_spin) +//FixStyle(neb,FixNEB) +FixStyle(neb/spin,FixNEB_spin) #else @@ -36,6 +36,8 @@ class FixNEB_spin : public Fix { void init(); void min_setup(int); void min_post_force(int); + void advance_spins(double); + double evaluate_dt(); private: int me,nprocs,nprocs_universe; @@ -79,6 +81,7 @@ class FixNEB_spin : public Fix { int *counts,*displacements; // used for MPI_Gather + double geodesic_distance(double *, double *); void inter_replica_comm(); void reallocate(); }; diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index 7860553532..60d44d1875 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -13,7 +13,7 @@ // lmptype.h must be first b/c this file uses MAXBIGINT and includes mpi.h // due to OpenMPI bug which sets INT64_MAX via its mpi.h -// before lmptype.h can set flags to insure it is done correctly +// before lmptype.h can set flags to insure it is done correctly #include "lmptype.h" #include @@ -21,7 +21,10 @@ #include #include //#include "neb.h" +// test spin #include "neb_spin.h" +#include "compute.h" + #include "universe.h" #include "atom.h" #include "update.h" @@ -30,7 +33,10 @@ #include "min.h" #include "modify.h" #include "fix.h" -#include "fix_neb.h" +//#include "fix_neb.h" +// test spin +#include "fix_neb_spin.h" + #include "output.h" #include "thermo.h" #include "finish.h" @@ -46,7 +52,7 @@ using namespace MathConst; #define MAXLINE 256 #define CHUNK 1024 //#define ATTRIBUTE_PERLINE 4 -// 8 attributes: tag number, coords, spin norm, spin dir. +// 8 attributes: tag, spin norm, position (3), spin direction (3) #define ATTRIBUTE_PERLINE 8 /* ---------------------------------------------------------------------- */ @@ -61,7 +67,8 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, int n2steps_in, int nevery_in, double *buf_init, double *buf_final) : Pointers(lmp) { - double delx,dely,delz; + //double delx,dely,delz; + double delspx,delspy,delspz; etol = etol_in; ftol = ftol_in; @@ -82,19 +89,40 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, double fraction = ireplica/(nreplica-1.0); double **x = atom->x; + // spin quantitites double **sp = atom->sp; int nlocal = atom->nlocal; - // modif interp. int ii = 0; + double spinit[3],spfinal[3]; for (int i = 0; i < nlocal; i++) { - delx = buf_final[ii] - buf_init[ii]; - dely = buf_final[ii+1] - buf_init[ii+1]; - delz = buf_final[ii+2] - buf_init[ii+2]; - domain->minimum_image(delx,dely,delz); - x[i][0] = buf_init[ii] + fraction*delx; - x[i][1] = buf_init[ii+1] + fraction*dely; - x[i][2] = buf_init[ii+2] + fraction*delz; + + spinit[0] = buf_init[ii]; + spinit[1] = buf_init[ii+1]; + spinit[2] = buf_init[ii+2]; + spfinal[0] = buf_final[ii]; + spfinal[1] = buf_final[ii+1]; + spfinal[2] = buf_final[ii+2]; + + initial_rotation(spinit,spfinal,fraction); + + sp[i][0] = spfinal[0]; + sp[i][1] = spfinal[1]; + sp[i][2] = spfinal[2]; + + //delx = buf_final[ii] - buf_init[ii]; + //dely = buf_final[ii+1] - buf_init[ii+1]; + //delz = buf_final[ii+2] - buf_init[ii+2]; + + // adjust distance if pbc + // not implemented yet + //domain->minimum_image(delx,dely,delz); + + // need to define a procedure for circular initialization + + //x[i][0] = buf_init[ii] + fraction*delx; + //x[i][1] = buf_init[ii+1] + fraction*dely; + //x[i][2] = buf_init[ii+2] + fraction*delz; ii += 3; } } @@ -114,6 +142,15 @@ NEB_spin::~NEB_spin() void NEB_spin::command(int narg, char **arg) { + + printf("test 1 \n"); + + // test 1 + double **sp1 = atom->sp; + printf("test 1 atom: i=%d,%g,%g,%g \n",1,sp1[1][0],sp1[1][1],sp1[1][2]); + //error->all(FLERR,"end neb_spin test"); + + if (domain->box_exist == 0) error->all(FLERR,"NEB_spin command before simulation box is defined"); @@ -141,6 +178,13 @@ void NEB_spin::command(int narg, char **arg) uworld = universe->uworld; MPI_Comm_rank(world,&me); + // check metal units and spin atom/style + + if (!atom->sp_flag) + error->all(FLERR,"neb/spin requires atom/spin style"); + if (strcmp(update->unit_style,"metal") != 0) + error->all(FLERR,"neb/spin simulation requires metal unit style"); + // error checks if (nreplica == 1) error->all(FLERR,"Cannot use NEB_spin with a single replica"); @@ -149,6 +193,7 @@ void NEB_spin::command(int narg, char **arg) // process file-style setting to setup initial configs for all replicas + // check what options are available if (strcmp(arg[5],"final") == 0) { if (narg != 7 && narg !=8) error->universe_all(FLERR,"Illegal NEB_spin command"); infile = arg[6]; @@ -163,6 +208,13 @@ void NEB_spin::command(int narg, char **arg) verbose=false; if (strcmp(arg[narg-1],"verbose") == 0) verbose=true; + + + // test 1 + double **sp = atom->sp; + printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + error->all(FLERR,"end neb_spin test"); + // run the NEB_spin calculation run(); @@ -181,17 +233,13 @@ void NEB_spin::run() else color = 1; MPI_Comm_split(uworld,color,0,&roots); + // search for neb_spin fix, allocate it int ineb; for (ineb = 0; ineb < modify->nfix; ineb++) - if (strcmp(modify->fix[ineb]->style,"neb_spin") == 0) break; - if (ineb == modify->nfix) error->all(FLERR,"NEB_spin requires use of fix neb_spin"); - //int ineb; - //for (ineb = 0; ineb < modify->nfix; ineb++) - // if (strcmp(modify->fix[ineb]->style,"neb") == 0) break; - //if (ineb == modify->nfix) error->all(FLERR,"NEB_spin requires use of fix neb"); - - //fneb = (FixNEB_spin *) modify->fix[ineb]; - fneb_spin = (FixNEB_spin *) modify->fix[ineb]; + if (strcmp(modify->fix[ineb]->style,"neb/spin") == 0) break; + if (ineb == modify->nfix) error->all(FLERR,"NEB_spin requires use of fix neb/spin"); + + fneb = (FixNEB_spin *) modify->fix[ineb]; if (verbose) numall =7; else numall = 4; memory->create(all,nreplica,numall,"neb:all"); @@ -206,8 +254,10 @@ void NEB_spin::run() lmp->init(); - if (update->minimize->searchflag) - error->all(FLERR,"NEB_spin requires damped dynamics minimizer"); + // put flag to check gilbert damping procedure is set + + //if (update->minimize->searchflag) + // error->all(FLERR,"NEB_spin requires damped dynamics minimizer"); // setup regular NEB_spin minimization FILE *uscreen = universe->uscreen; @@ -264,8 +314,19 @@ void NEB_spin::run() timer->init(); timer->barrier_start(); + double dts; while (update->minimize->niter < n1steps) { - update->minimize->run(nevery); + //dts = evaluate_dt(); + //advance_spins(dts); + dts = fneb->evaluate_dt(); + fneb->advance_spins(dts); + + // no minimizer for spins + //update->minimize->run(nevery); + // + // evaluate dts + // loop on spins, damped advance + // print_status(); if (update->minimize->stop_condition) break; } @@ -309,8 +370,7 @@ void NEB_spin::run() error->all(FLERR,"Too many timesteps"); update->minimize->init(); - //fneb->rclimber = top; - fneb_spin->rclimber = top; + fneb->rclimber = top; update->minimize->setup(); if (me_universe == 0) { @@ -356,7 +416,11 @@ void NEB_spin::run() timer->barrier_start(); while (update->minimize->niter < n2steps) { - update->minimize->run(nevery); + //dts = evaluate_dt(); + //advance_spins(dts); + dts = fneb->evaluate_dt(); + fneb->advance_spins(dts); + //update->minimize->run(nevery); print_status(); if (update->minimize->stop_condition) break; } @@ -373,6 +437,174 @@ void NEB_spin::run() update->beginstep = update->endstep = 0; } +/* ---------------------------------------------------------------------- + geodesic distance calculation (Vincenty's formula) +------------------------------------------------------------------------- */ + +//double NEB_spin::geodesic_distance2(double spi[3], double spj[3]) +//{ +// double dist; +// double crossx,crossy,crossz; +// double dotx,doty,dotz; +// double crosslen,dots; +// +// crossx = spi[1]*spj[2]-spi[2]*spj[1]; +// crossy = spi[2]*spj[0]-spi[0]*spj[2]; +// crossz = spi[0]*spj[1]-spi[1]*spj[0]; +// crosslen = sqrt(crossx*crossx + crossy*crossy + crossz*crossz); +// dotx = spi[0]*spj[0]; +// doty = spi[1]*spj[1]; +// dotz = spi[2]*spj[2]; +// dots = dotx+doty+dotz; +// +// dist = atan2(crosslen,dots); +// +// return dist; +//} + +/* ---------------------------------------------------------------------- + evaluate max timestep +---------------------------------------------------------------------- */ + +//double NEB_spin::evaluate_dt() +//{ +// double dtmax; +// double fmsq; +// double fmaxsqone,fmaxsqloc,fmaxsqall; +// int nlocal = atom->nlocal; +// int *mask = atom->mask; +// double **fm = atom->fm; +// +// // finding max fm on this proc. +// +// fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; +// for (int i = 0; i < nlocal; i++) +// if (mask[i] & groupbit) { +// fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; +// fmaxsqone = MAX(fmaxsqone,fmsq); +// } +// +// // finding max fm on this replica +// +// fmaxsqloc = fmaxsqone; +// MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); +// +// // finding max fm over all replicas, if necessary +// // this communicator would be invalid for multiprocess replicas +// +// if (update->multireplica == 1) { +// fmaxsqall = fmaxsqloc; +// MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); +// } +// +// if (fmaxsqall < fmaxsqloc) +// error->all(FLERR,"Incorrect fmaxall calc."); +// +// // define max timestep +// // dividing by 10 the inverse of max frequency +// +// dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); +// +// return dtmax; +//} + +/* ---------------------------------------------------------------------- + geometric damped advance os spins +---------------------------------------------------------------------- */ + +//void NEB_spin::advance_spins(double dts) +//{ +// //int j=0; +// //int *sametag = atom->sametag; +// int nlocal = atom->nlocal; +// int *mask = atom->mask; +// double **sp = atom->sp; +// double **fm = atom->fm; +// double tdampx,tdampy,tdampz; +// double msq,scale,fm2,energy,dts2; +// double alpha; +// double spi[3],fmi[3]; +// double cp[3],g[3]; +// +// //cp[0] = cp[1] = cp[2] = 0.0; +// //g[0] = g[1] = g[2] = 0.0; +// dts2 = dts*dts; +// +// // fictitious Gilbert damping of 1 +// alpha = 1.0; +// +// // loop on all spins on proc. +// +// if (ireplica != nreplica-1 && ireplica != 0) +// for (int i = 0; i < nlocal; i++) +// if (mask[i] & groupbit) { +// +// spi[0] = sp[i][0]; +// spi[1] = sp[i][1]; +// spi[2] = sp[i][2]; +// +// fmi[0] = fm[i][0]; +// fmi[1] = fm[i][1]; +// fmi[2] = fm[i][2]; +// +// // calc. damping torque +// +// tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); +// tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); +// tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); +// +// // apply advance algorithm (geometric, norm preserving) +// +// fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); +// energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); +// +// cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; +// cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; +// cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; +// +// g[0] = sp[i][0]+cp[0]*dts; +// g[1] = sp[i][1]+cp[1]*dts; +// g[2] = sp[i][2]+cp[2]*dts; +// +// g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; +// g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; +// g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; +// +// g[0] /= (1+0.25*fm2*dts2); +// g[1] /= (1+0.25*fm2*dts2); +// g[2] /= (1+0.25*fm2*dts2); +// +// sp[i][0] = g[0]; +// sp[i][1] = g[1]; +// sp[i][2] = g[2]; +// +// // renormalization (check if necessary) +// +// msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; +// scale = 1.0/sqrt(msq); +// sp[i][0] *= scale; +// sp[i][1] *= scale; +// sp[i][2] *= scale; +// +// // comm. sp[i] to atoms with same tag (for serial algo) +// +// // no need for simplecticity +// //if (sector_flag == 0) { +// // if (sametag[i] >= 0) { +// // j = sametag[i]; +// // while (j >= 0) { +// // sp[j][0] = sp[i][0]; +// // sp[j][1] = sp[i][1]; +// // sp[j][2] = sp[i][2]; +// // j = sametag[j]; +// // } +// // } +// //} +// // +// +// } +//} + /* ---------------------------------------------------------------------- read initial config atom coords from file flag = 0 @@ -395,8 +627,9 @@ void NEB_spin::readfile(char *file, int flag) char *eof,*start,*next,*buf; char line[MAXLINE]; double xx,yy,zz,delx,dely,delz; - // creating new temp. sp - double spx,spy,spz,delspx,delspy,delspz; + // spin quantities + double musp,spx,spy,spz; + //,delx,dely,delz; if (me_universe == 0 && screen) fprintf(screen,"Reading NEB_spin coordinate file(s) ...\n"); @@ -440,10 +673,17 @@ void NEB_spin::readfile(char *file, int flag) double fraction = ireplica/(nreplica-1.0); double **x = atom->x; - // spin table + // spin quantities double **sp = atom->sp; + double spinit[3],spfinal[3]; int nlocal = atom->nlocal; + // test 1.2 + //double **sp = atom->sp; + printf("test 1.2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //error->all(FLERR,"end neb_spin test"); + + // loop over chunks of lines read from file // two versions of read_lines_from_file() for world vs universe bcast // count # of atom coords changed so can check for invalid atom IDs in file @@ -493,22 +733,59 @@ void NEB_spin::readfile(char *file, int flag) m = atom->map(tag); if (m >= 0 && m < nlocal) { ncount++; - xx = atof(values[1]); - yy = atof(values[2]); - zz = atof(values[3]); + musp = atof(values[1]); + xx = atof(values[2]); + yy = atof(values[3]); + zz = atof(values[4]); + spx = atof(values[5]); + spy = atof(values[6]); + spz = atof(values[7]); + //xx = atof(values[1]); + //yy = atof(values[2]); + //zz = atof(values[3]); if (flag == 0) { - delx = xx - x[m][0]; - dely = yy - x[m][1]; - delz = zz - x[m][2]; - domain->minimum_image(delx,dely,delz); - x[m][0] += fraction*delx; - x[m][1] += fraction*dely; - x[m][2] += fraction*delz; + + // here, function interp. spin states + + //spinit[0] = x[m][0]; + //spinit[1] = x[m][1]; + //spinit[2] = x[m][2]; + spinit[0] = sp[m][0]; + spinit[1] = sp[m][1]; + spinit[2] = sp[m][2]; + spfinal[0] = spx; + spfinal[1] = spy; + spfinal[2] = spz; + //domain->minimum_image(delx,dely,delz); + + // test + printf("spinit: %g %g %g \n",spinit[0],spinit[1],spinit[2]); + printf("spfinal bef: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); + + initial_rotation(spinit,spfinal,fraction); + + // test + printf("spfinal aft: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); + + sp[m][0] = spfinal[0]; + sp[m][1] = spfinal[1]; + sp[m][2] = spfinal[2]; + sp[m][3] = musp; + //delx = xx - x[m][0]; + //dely = yy - x[m][1]; + //delz = zz - x[m][2]; + //x[m][0] += fraction*delx; + //x[m][1] += fraction*dely; + //x[m][2] += fraction*delz; } else { - x[m][0] = xx; + sp[m][3] = musp; + x[m][0] = xx; x[m][1] = yy; x[m][2] = zz; + sp[m][0] = spx; + sp[m][1] = spy; + sp[m][2] = spz; } } @@ -518,6 +795,12 @@ void NEB_spin::readfile(char *file, int flag) nread += nchunk; } + // test 1.3 + //double **sp = atom->sp; + printf("test 1.3 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //error->all(FLERR,"end neb_spin test"); + + // check that all atom IDs in file were found by a proc if (flag == 0) { @@ -550,6 +833,75 @@ void NEB_spin::readfile(char *file, int flag) } } +/* ---------------------------------------------------------------------- + initial configuration of spin sploc using Rodrigues' formula + interpolates between initial (spi) and final (stored in sploc) +------------------------------------------------------------------------- */ + +void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) +{ + + + // implementing initial rotation using atan2 + + //atan2(crosslen,dots); + + + + double theta,spdot; + double inormdot,ispinorm; + double kix,kiy,kiz; + double kinorm, ikinorm; + double crossx,crossy,crossz; + + //printf("inside rot, spi %g, spf %g \n",spi[0],sploc[0]); + + spdot = spi[0]*sploc[0]+spi[1]*sploc[1]+spi[2]*sploc[2]; + theta = fraction*acos(spdot); + + printf("inside rot, theta %g \n",theta); + + kix = spi[1]*sploc[2]-spi[2]*sploc[1]; + kiy = spi[2]*sploc[0]-spi[0]*sploc[2]; + kiz = spi[0]*sploc[1]-spi[1]*sploc[0]; + + //printf("inside rot1.1, ki %g %g %g \n",kix,kiy,kiz); + + inormdot = 1.0/sqrt(spdot); + kinorm = kix*kix+kiy*kiy+kiz*kiz; + if (kinorm == 0.0) { + kix = 0.0; + kiy = 0.0; + kiz = 0.0; + } else { + ikinorm = 1.0/kinorm; + kix *= ikinorm; + kiy *= ikinorm; + kiz *= ikinorm; + } + + //printf("inside rot1.2, kin %g %g %g \n",kix,kiy,kiz); + + crossx = kiy*spi[2]-kiz*spi[1]; + crossy = kiz*spi[0]-kix*spi[2]; + crossz = kix*spi[1]-kiy*spi[0]; + + //printf("inside rot1.3, cross %g %g %g \n",crossx,crossy,crossz); + + sploc[0] = spi[0]*cos(theta)+crossx*sin(theta); + sploc[1] = spi[1]*cos(theta)+crossy*sin(theta); + sploc[2] = spi[2]*cos(theta)+crossz*sin(theta); + + //printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); + + ispinorm = 1.0/sqrt(sploc[0]*sploc[0]+sploc[1]*sploc[1]+sploc[2]*sploc[2]); + + sploc[0] *= ispinorm; + sploc[1] *= ispinorm; + sploc[2] *= ispinorm; + printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); +} + /* ---------------------------------------------------------------------- universe proc 0 opens NEB_spin data file test if gzipped @@ -606,22 +958,15 @@ void NEB_spin::print_status() } double one[7]; - //one[0] = fneb->veng; - //one[1] = fneb->plen; - //one[2] = fneb->nlen; - //one[3] = fneb->gradlen; - one[0] = fneb_neb->veng; - one[1] = fneb_neb->plen; - one[2] = fneb_neb->nlen; - one[3] = fneb_neb->gradlen; + one[0] = fneb->veng; + one[1] = fneb->plen; + one[2] = fneb->nlen; + one[3] = fneb->gradlen; if (verbose) { - //one[4] = fneb->dotpath; - //one[5] = fneb->dottangrad; - //one[6] = fneb->dotgrad; - one[4] = fneb_spin->dotpath; - one[5] = fneb_spin->dottangrad; - one[6] = fneb_spin->dotgrad; + one[4] = fneb->dotpath; + one[5] = fneb->dottangrad; + one[6] = fneb->dotgrad; } if (output->thermo->normflag) one[0] /= atom->natoms; diff --git a/src/REPLICA/neb_spin.h b/src/REPLICA/neb_spin.h index 3fa19460fc..6541658fd7 100644 --- a/src/REPLICA/neb_spin.h +++ b/src/REPLICA/neb_spin.h @@ -13,7 +13,8 @@ #ifdef COMMAND_CLASS -CommandStyle(neb_spin,NEB_SPIN) +CommandStyle(neb/spin,NEB_spin) +//CommandStyle(neb,NEB_spin) #else @@ -56,7 +57,11 @@ class NEB_spin : protected Pointers { double *freplica; // force on an image double *fmaxatomInRepl; // force on an image + //double geodesic_distance2(double *, double *); + //double evaluate_dt(); + //void advance_spins(double); void readfile(char *, int); + void initial_rotation(double *, double *, double); void open(char *); void print_status(); }; diff --git a/src/SPIN/pair_spin_exchange.cpp b/src/SPIN/pair_spin_exchange.cpp index 8cd9d33abd..ec21fe8838 100644 --- a/src/SPIN/pair_spin_exchange.cpp +++ b/src/SPIN/pair_spin_exchange.cpp @@ -153,11 +153,12 @@ void PairSpinExchange::init_style() neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; - // checking if nve/spin is a listed fix + // checking if nve/spin or neb/spin are a listed fix int ifix = 0; while (ifix < modify->nfix) { if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; + if (strcmp(modify->fix[ifix]->style,"neb/spin") == 0) break; ifix++; } if (ifix == modify->nfix) -- GitLab From 8ec9b6fb64930cc3798c4efd684f05f2f2e28296 Mon Sep 17 00:00:00 2001 From: casievers Date: Tue, 5 Feb 2019 11:49:15 -0800 Subject: [PATCH 0104/1243] Memory Use Reduction --- src/USER-PHONON/dynamical_matrix.cpp | 131 +++++++++++++++------------ src/USER-PHONON/dynamical_matrix.h | 8 +- 2 files changed, 77 insertions(+), 62 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index a7d8620d00..7d4caad226 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -23,6 +23,7 @@ #include "pair.h" #include "timer.h" #include "finish.h" +#include using namespace LAMMPS_NS; @@ -41,8 +42,6 @@ DynamicalMatrix::~DynamicalMatrix() { if (fp && me == 0) fclose(fp); memory->destroy(groupmap); - memory->destroy(dynmat); - memory->destroy(final_dynmat); fp = NULL; } @@ -75,32 +74,13 @@ void DynamicalMatrix::setup() neighbor->ndanger = 0; // compute all forces - force_clear(); external_force_clear = 0; - eflag=0; vflag=0; - if (pair_compute_flag) force->pair->compute(eflag,vflag); - else if (force->pair) force->pair->compute_dummy(eflag,vflag); - - if (atom->molecular) { - if (force->bond) force->bond->compute(eflag,vflag); - if (force->angle) force->angle->compute(eflag,vflag); - if (force->dihedral) force->dihedral->compute(eflag,vflag); - if (force->improper) force->improper->compute(eflag,vflag); - } - - if (force->kspace) { - force->kspace->setup(); - if (kspace_compute_flag) force->kspace->compute(eflag,vflag); - else force->kspace->compute_dummy(eflag,vflag); - } - - //modify->setup_pre_reverse(eflag,vflag); - if (force->newton) comm->reverse_comm(); + update_force(); //if all then skip communication groupmap population - if (group->count(igroup) == atom->natoms) + if (ngatoms == atom->natoms) for (int i=0; inatoms; i++) groupmap[i] = i; else @@ -133,9 +113,9 @@ void DynamicalMatrix::command(int narg, char **arg) igroup = group->find(arg[0]); if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); groupbit = group->bitmask[igroup]; - dynlen = (group->count(igroup))*3; + ngatoms = group->count(igroup); + dynlen = (ngatoms)*3; memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); - memory->create(dynmat,int(dynlen),int(dynlen),"dynamic_matrix:dynmat"); update->setupflag = 1; int style = -1; @@ -162,16 +142,20 @@ void DynamicalMatrix::command(int narg, char **arg) if (style == REGULAR) { setup(); + timer->init(); + timer->barrier_start(); calculateMatrix(); - if (me ==0) writeMatrix(); + timer->barrier_stop(); } if (style == ESKM) { setup(); convert_units(update->unit_style); conversion = conv_energy/conv_distance/conv_mass; + timer->init(); + timer->barrier_start(); calculateMatrix(); - if (me ==0) writeMatrix(); + timer->barrier_stop(); } Finish finish(lmp); @@ -219,7 +203,7 @@ void DynamicalMatrix::options(int narg, char **arg) void DynamicalMatrix::openfile(const char* filename) { // if file already opened, return - if (me!=0) return; + //if (me!=0) return; if (file_opened) return; if (compressed) { @@ -261,54 +245,68 @@ void DynamicalMatrix::calculateMatrix() double *m = atom->mass; double **f = atom->f; - //initialize dynmat to all zeros - for (int i=0; i < dynlen; i++) - for (int j=0; j < dynlen; j++) - dynmat[i][j] = 0.; + double **dynmat = new double*[3]; + for (int i=0; i<3; i++) + dynmat[i] = new double[dynlen]; - energy_force(0); + double **fdynmat = new double*[3]; + for (int i=0; i<3; i++) + fdynmat[i] = new double[dynlen]; + + //initialize dynmat to all zeros + dynmat_clear(dynmat); if (comm->me == 0 && screen) fprintf(screen,"Calculating Dynamical Matrix...\n"); - for (int i=1; i<=natoms; i++){ + for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); if (local_idx >= 0){ - for (int alpha=0; alpha<3; alpha++){ + for (bigint alpha=0; alpha<3; alpha++){ displace_atom(local_idx, alpha, 1); - energy_force(0); - for (int j=1; j<=natoms; j++){ + update_force(); + for (bigint j=1; j<=natoms; j++){ local_jdx = atom->map(j); - if (local_jdx >= 0 && local_idx < nlocal && gm[i-1] >= 0 && gm[j-1] >= 0){ + if (local_jdx >= 0 && local_jdx < nlocal + && gm[i-1] >= 0 && gm[j-1] >= 0){ for (int beta=0; beta<3; beta++){ - dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] += -f[j-1][beta]; + dynmat[alpha][(gm[j-1])*3+beta] = -f[local_jdx][beta]; } } } displace_atom(local_idx,alpha,-2); - energy_force(0); - for (int j=1; j<=natoms; j++){ + update_force(); + for (bigint j=1; j<=natoms; j++){ local_jdx = atom->map(j); - if (local_jdx >= 0 && local_idx < nlocal && gm[i-1] >= 0 && gm[j-1] >= 0){ - for (int beta=0; beta<3; beta++){ + if (local_jdx >= 0 && local_jdx < nlocal + && gm[i-1] >= 0 && gm[j-1] >= 0){ + for (bigint beta=0; beta<3; beta++){ if (atom->rmass_flag == 1) imass = sqrt(m[local_idx] * m[local_jdx]); else imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); - dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] -= -f[j-1][beta]; - dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] /= (2 * del * imass); - dynmat[(gm[i-1])*3+alpha][(gm[j-1])*3+beta] *= conversion; + dynmat[alpha][(gm[j-1])*3+beta] -= -f[local_jdx][beta]; + dynmat[alpha][(gm[j-1])*3+beta] /= (2 * del * imass); + dynmat[alpha][(gm[j-1])*3+beta] *= conversion; } } } displace_atom(local_idx,alpha,1); } + for (int k=0; k<3; k++) + MPI_Reduce(dynmat[k],fdynmat[k],dynlen,MPI_DOUBLE,MPI_SUM,0,world); + if (me == 0) + writeMatrix(fdynmat); + dynmat_clear(dynmat); } } + for (int i=0; i < 3; i++) + delete [] dynmat[i]; + delete [] dynmat; - memory->create(final_dynmat,int(dynlen),int(dynlen),"dynamic_matrix_buffer:buf"); - for (int i = 0; i < dynlen; i++) - MPI_Reduce(dynmat[i], final_dynmat[i], int(dynlen), MPI_DOUBLE, MPI_SUM, 0, world); + for (int i=0; i < 3; i++) + delete [] fdynmat[i]; + delete [] fdynmat; if (screen && me ==0 ) fprintf(screen,"Finished Calculating Dynamical Matrix\n"); } @@ -317,15 +315,17 @@ void DynamicalMatrix::calculateMatrix() write dynamical matrix ------------------------------------------------------------------------- */ -void DynamicalMatrix::writeMatrix() +void DynamicalMatrix::writeMatrix(double **dynmat) { + if (me != 0) + return; // print file comment lines if (!binaryflag && fp) { clearerr(fp); - for (int i = 0; i < dynlen; i++) { + for (int i = 0; i < 3; i++) { for (int j = 0; j < dynlen; j++) { - if ((j+1)%3==0) fprintf(fp, "%4.8f\n", final_dynmat[j][i]); - else fprintf(fp, "%4.8f ",final_dynmat[j][i]); + if ((j+1)%3==0) fprintf(fp, "%4.8f\n", dynmat[i][j]); + else fprintf(fp, "%4.8f ",dynmat[i][j]); } } } @@ -334,7 +334,7 @@ void DynamicalMatrix::writeMatrix() if (binaryflag && fp) { clearerr(fp); - fwrite(&final_dynmat[0], sizeof(double), dynlen * dynlen, fp); + fwrite(&dynmat[0], sizeof(double), 3 * dynlen, fp); if (ferror(fp)) error->one(FLERR, "Error writing to binary file"); } @@ -367,7 +367,7 @@ void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) return negative gradient for nextra_global dof in fextra ------------------------------------------------------------------------- */ -void DynamicalMatrix::energy_force(int resetflag) +void DynamicalMatrix::update_force() { force_clear(); @@ -412,6 +412,21 @@ void DynamicalMatrix::force_clear() } } +/* ---------------------------------------------------------------------- + clear dynmat needed +------------------------------------------------------------------------- */ + +void DynamicalMatrix::dynmat_clear(double **dynmat) +{ + + size_t nbytes = sizeof(double) * dynlen; + + if (nbytes) { + for (int i=0; i<3; i++) + memset(&dynmat[i][0],0,nbytes); + } +} + /* ---------------------------------------------------------------------- */ void DynamicalMatrix::convert_units(const char *style) @@ -485,7 +500,7 @@ void DynamicalMatrix::create_groupmap() //find number of local atoms in the group (final_gid) for (int i=1; i<=natoms; i++){ local_idx = atom->map(i); - if (mask[local_idx] & groupbit && local_idx < nlocal) + if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) gid += 1; // gid at the end of loop is final_Gid } //create an array of length final_gid @@ -495,7 +510,7 @@ void DynamicalMatrix::create_groupmap() //create a map between global atom id and group atom id for each proc for (int i=1; i<=natoms; i++){ local_idx = atom->map(i); - if (mask[local_idx] & groupbit && local_idx < nlocal){ + if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit){ sub_groupmap[gid] = i; gid += 1; } @@ -515,7 +530,7 @@ void DynamicalMatrix::create_groupmap() //combine subgroup maps into total temporary groupmap MPI_Allgatherv(sub_groupmap,gid,MPI_INT,temp_groupmap,recv,displs,MPI_INT,world); - std::sort(temp_groupmap,temp_groupmap+group->count(igroup)); + std::sort(temp_groupmap,temp_groupmap+ngatoms); //populate member groupmap based on temp groupmap for (int i=0; i Date: Tue, 5 Feb 2019 17:52:28 -0800 Subject: [PATCH 0105/1243] minor dynmat changes and start of third order changes --- src/USER-PHONON/dynamical_matrix.cpp | 72 +++++----- src/USER-PHONON/dynamical_matrix.h | 2 +- src/USER-PHONON/third_order.cpp | 199 ++++++++++++++++++--------- src/USER-PHONON/third_order.h | 5 +- 4 files changed, 177 insertions(+), 101 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index 7d4caad226..854d46adca 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -80,7 +80,7 @@ void DynamicalMatrix::setup() update_force(); //if all then skip communication groupmap population - if (ngatoms == atom->natoms) + if (gcount == atom->natoms) for (int i=0; inatoms; i++) groupmap[i] = i; else @@ -113,8 +113,8 @@ void DynamicalMatrix::command(int narg, char **arg) igroup = group->find(arg[0]); if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); groupbit = group->bitmask[igroup]; - ngatoms = group->count(igroup); - dynlen = (ngatoms)*3; + gcount = group->count(igroup); + dynlen = (gcount)*3; memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); update->setupflag = 1; @@ -260,44 +260,42 @@ void DynamicalMatrix::calculateMatrix() for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); - if (local_idx >= 0){ - for (bigint alpha=0; alpha<3; alpha++){ - displace_atom(local_idx, alpha, 1); - update_force(); - for (bigint j=1; j<=natoms; j++){ - local_jdx = atom->map(j); - if (local_jdx >= 0 && local_jdx < nlocal - && gm[i-1] >= 0 && gm[j-1] >= 0){ - for (int beta=0; beta<3; beta++){ - dynmat[alpha][(gm[j-1])*3+beta] = -f[local_jdx][beta]; - } + for (bigint alpha=0; alpha<3; alpha++){ + displace_atom(local_idx, alpha, 1); + update_force(); + for (bigint j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal + && gm[i-1] >= 0 && gm[j-1] >= 0){ + for (int beta=0; beta<3; beta++){ + dynmat[alpha][(gm[j-1])*3+beta] = -f[local_jdx][beta]; } } - displace_atom(local_idx,alpha,-2); - update_force(); - for (bigint j=1; j<=natoms; j++){ - local_jdx = atom->map(j); - if (local_jdx >= 0 && local_jdx < nlocal - && gm[i-1] >= 0 && gm[j-1] >= 0){ - for (bigint beta=0; beta<3; beta++){ - if (atom->rmass_flag == 1) - imass = sqrt(m[local_idx] * m[local_jdx]); - else - imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); - dynmat[alpha][(gm[j-1])*3+beta] -= -f[local_jdx][beta]; - dynmat[alpha][(gm[j-1])*3+beta] /= (2 * del * imass); - dynmat[alpha][(gm[j-1])*3+beta] *= conversion; - } + } + displace_atom(local_idx,alpha,-2); + update_force(); + for (bigint j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal + && gm[i-1] >= 0 && gm[j-1] >= 0){ + for (bigint beta=0; beta<3; beta++){ + if (atom->rmass_flag == 1) + imass = sqrt(m[local_idx] * m[local_jdx]); + else + imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); + dynmat[alpha][(gm[j-1])*3+beta] -= -f[local_jdx][beta]; + dynmat[alpha][(gm[j-1])*3+beta] /= (2 * del * imass); + dynmat[alpha][(gm[j-1])*3+beta] *= conversion; } } - displace_atom(local_idx,alpha,1); } - for (int k=0; k<3; k++) - MPI_Reduce(dynmat[k],fdynmat[k],dynlen,MPI_DOUBLE,MPI_SUM,0,world); - if (me == 0) - writeMatrix(fdynmat); - dynmat_clear(dynmat); + displace_atom(local_idx,alpha,1); } + for (int k=0; k<3; k++) + MPI_Reduce(dynmat[k],fdynmat[k],dynlen,MPI_DOUBLE,MPI_SUM,0,world); + if (me == 0) + writeMatrix(fdynmat); + dynmat_clear(dynmat); } for (int i=0; i < 3; i++) @@ -530,7 +528,7 @@ void DynamicalMatrix::create_groupmap() //combine subgroup maps into total temporary groupmap MPI_Allgatherv(sub_groupmap,gid,MPI_INT,temp_groupmap,recv,displs,MPI_INT,world); - std::sort(temp_groupmap,temp_groupmap+ngatoms); + std::sort(temp_groupmap,temp_groupmap+gcount); //populate member groupmap based on temp groupmap for (int i=0; i using namespace LAMMPS_NS; @@ -72,28 +73,16 @@ void ThirdOrder::setup() neighbor->ndanger = 0; // compute all forces - force_clear(); + update_force(); external_force_clear = 0; - eflag=0; vflag=0; - if (pair_compute_flag) force->pair->compute(eflag,vflag); - else if (force->pair) force->pair->compute_dummy(eflag,vflag); - if (atom->molecular) { - if (force->bond) force->bond->compute(eflag,vflag); - if (force->angle) force->angle->compute(eflag,vflag); - if (force->dihedral) force->dihedral->compute(eflag,vflag); - if (force->improper) force->improper->compute(eflag,vflag); - } - - if (force->kspace) { - force->kspace->setup(); - if (kspace_compute_flag) force->kspace->compute(eflag,vflag); - else force->kspace->compute_dummy(eflag,vflag); - } - - if (force->newton) comm->reverse_comm(); + if (gcount == atom->natoms) + for (int i=0; inatoms; i++) + groupmap[i] = i; + else + create_groupmap(); } /* ---------------------------------------------------------------------- */ @@ -148,14 +137,20 @@ void ThirdOrder::command(int narg, char **arg) if (style == REGULAR) { setup(); + timer->init(); + timer->barrier_start(); calculateMatrix(); + timer->barrier_stop(); } if (style == BALLISTICO) { setup(); convert_units(update->unit_style); conversion = conv_energy/conv_distance/conv_distance; + timer->init(); + timer->barrier_start(); calculateMatrix(); + timer->barrier_stop(); } Finish finish(lmp); @@ -240,37 +235,78 @@ void ThirdOrder::calculateMatrix() int local_idx; // local index int local_jdx; // second local index int local_kdx; // third local index + int nlocal = atom->nlocal; int natoms = atom->natoms; - int *mask = atom->mask; + int *gm = groupmap; double **f = atom->f; - energy_force(0); + update_force(); if (comm->me == 0 && screen) fprintf(screen,"Calculating Anharmonic Dynamical Matrix...\n"); - for (int i=1; i<=natoms; i++){ + for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); - if (local_idx >= 0 && mask[local_idx] && groupbit){ - for (int alpha=0; alpha<3; alpha++){ - displace_atom(local_idx, alpha, 1); - for (int j=1; j<=natoms; j++){ - local_jdx = atom->map(j); - if (local_jdx >= 0&& mask[local_jdx] && groupbit){ - for (int beta=0; beta<3; beta++){ + for (bigint alpha=0; alpha<3; alpha++){ + displace_atom(local_idx, alpha, 1); + for (bigint j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + for (int beta=0; beta<3; beta++){ + displace_atom(local_jdx, beta, 1); + update_force(); + for (bigint k=1; k<=natoms; k++){ + local_kdx = atom->map(k); + for (int gamma=0; gamma<3; gamma++){ + if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 + && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && local_kdx < nlocal) { + //first_derv[k*3+gamma] = f[k][gamma]; + } } } + displace_atom(local_jdx, beta, -2); + update_force(); + for (bigint k=1; k<=natoms; k++){ + local_kdx = atom->map(k); + for (int gamma=0; gamma<3; gamma++){ + if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 + && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && local_kdx < nlocal) { + } + } + } + displace_atom(local_jdx, beta, 1); } - displace_atom(local_idx,alpha,-2); - for (int j=1; j<=natoms; j++){ - local_jdx = atom->map(j); - if (local_jdx >= 0 && mask[local_jdx] && groupbit){ - for (int beta=0; beta<3; beta++){ - + } + displace_atom(local_idx,alpha,-2); + for (bigint j=1; j<=natoms; j++){ + local_jdx = atom->map(j); + for (int beta=0; beta<3; beta++){ + displace_atom(local_jdx, beta, 1); + update_force(); + for (bigint k=1; k<=natoms; k++){ + local_kdx = atom->map(k); + for (int gamma=0; gamma<3; gamma++){ + if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 + && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && local_kdx < nlocal) { + } } } + displace_atom(local_jdx, beta, -2); + update_force(); + for (bigint k=1; k<=natoms; k++){ + local_kdx = atom->map(k); + for (int gamma=0; gamma<3; gamma++){ + if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 + && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 + && local_kdx < nlocal) { + } + } + } + displace_atom(local_jdx, beta, 1); } - displace_atom(local_idx,alpha,1); } + displace_atom(local_idx,alpha,1); } } @@ -397,34 +433,8 @@ void ThirdOrder::displace_atom(int local_idx, int direction, int magnitude) return negative gradient for nextra_global dof in fextra ------------------------------------------------------------------------- */ -void ThirdOrder::energy_force(int resetflag) +void ThirdOrder::update_force() { - // check for reneighboring - // always communicate since atoms move - int nflag = neighbor->decide(); - - if (nflag == 0) { - timer->stamp(); - comm->forward_comm(); - timer->stamp(Timer::COMM); - } else { - if (triclinic) domain->x2lamda(atom->nlocal); - domain->pbc(); - if (domain->box_change) { - domain->reset_box(); - comm->setup(); - if (neighbor->style) neighbor->setup_bins(); - } - timer->stamp(); - - comm->borders(); - if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); - timer->stamp(Timer::COMM); - - neighbor->build(1); - timer->stamp(Timer::NEIGH); - } - force_clear(); timer->stamp(); @@ -527,3 +537,68 @@ void ThirdOrder::convert_units(const char *style) } else error->all(FLERR,"Units Type Conversion Not Found"); } + +/* ---------------------------------------------------------------------- */ + +void ThirdOrder::create_groupmap() +{ + //Create a group map which maps atom order onto group + + int local_idx; // local index + int gid = 0; //group index + int nlocal = atom->nlocal; + int *mask = atom->mask; + bigint natoms = atom->natoms; + int *recv = new int[comm->nprocs]; + int *displs = new int[comm->nprocs]; + int *temp_groupmap = new int[natoms]; + + //find number of local atoms in the group (final_gid) + for (int i=1; i<=natoms; i++){ + local_idx = atom->map(i); + if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) + gid += 1; // gid at the end of loop is final_Gid + } + //create an array of length final_gid + int *sub_groupmap = new int[gid]; + + gid = 0; + //create a map between global atom id and group atom id for each proc + for (int i=1; i<=natoms; i++){ + local_idx = atom->map(i); + if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit){ + sub_groupmap[gid] = i; + gid += 1; + } + } + + //populate arrays for Allgatherv + for (int i=0; inprocs; i++){ + recv[i] = 0; + } + recv[comm->me] = gid; + MPI_Allreduce(recv,displs,4,MPI_INT,MPI_SUM,world); + for (int i=0; inprocs; i++){ + recv[i]=displs[i]; + if (i>0) displs[i] = displs[i-1]+recv[i-1]; + else displs[i] = 0; + } + + //combine subgroup maps into total temporary groupmap + MPI_Allgatherv(sub_groupmap,gid,MPI_INT,temp_groupmap,recv,displs,MPI_INT,world); + std::sort(temp_groupmap,temp_groupmap+gcount); + + //populate member groupmap based on temp groupmap + for (int i=0; i Date: Wed, 6 Feb 2019 11:35:33 -0700 Subject: [PATCH 0106/1243] Commit JT 020619 - correction gneb/spin - run but do not converge yet - check forces --- src/REPLICA/neb_spin.cpp | 163 +++++++++++++++++++++++++-------------- 1 file changed, 106 insertions(+), 57 deletions(-) diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index 60d44d1875..8780cb9a0a 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -143,11 +143,11 @@ NEB_spin::~NEB_spin() void NEB_spin::command(int narg, char **arg) { - printf("test 1 \n"); + //printf("test 1 \n"); // test 1 double **sp1 = atom->sp; - printf("test 1 atom: i=%d,%g,%g,%g \n",1,sp1[1][0],sp1[1][1],sp1[1][2]); + //printf("test 1 atom: i=%d,%g,%g,%g \n",1,sp1[1][0],sp1[1][1],sp1[1][2]); //error->all(FLERR,"end neb_spin test"); @@ -212,8 +212,8 @@ void NEB_spin::command(int narg, char **arg) // test 1 double **sp = atom->sp; - printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); - error->all(FLERR,"end neb_spin test"); + //printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //error->all(FLERR,"end neb_spin test"); // run the NEB_spin calculation @@ -680,7 +680,7 @@ void NEB_spin::readfile(char *file, int flag) // test 1.2 //double **sp = atom->sp; - printf("test 1.2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //printf("test 1.2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); //error->all(FLERR,"end neb_spin test"); @@ -760,13 +760,13 @@ void NEB_spin::readfile(char *file, int flag) //domain->minimum_image(delx,dely,delz); // test - printf("spinit: %g %g %g \n",spinit[0],spinit[1],spinit[2]); - printf("spfinal bef: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); + //printf("spinit: %g %g %g \n",spinit[0],spinit[1],spinit[2]); + //printf("spfinal bef: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); initial_rotation(spinit,spfinal,fraction); // test - printf("spfinal aft: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); + //printf("spfinal aft: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); sp[m][0] = spfinal[0]; sp[m][1] = spfinal[1]; @@ -797,7 +797,7 @@ void NEB_spin::readfile(char *file, int flag) // test 1.3 //double **sp = atom->sp; - printf("test 1.3 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //printf("test 1.3 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); //error->all(FLERR,"end neb_spin test"); @@ -841,65 +841,101 @@ void NEB_spin::readfile(char *file, int flag) void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) { - // implementing initial rotation using atan2 - //atan2(crosslen,dots); - - - - double theta,spdot; - double inormdot,ispinorm; - double kix,kiy,kiz; - double kinorm, ikinorm; - double crossx,crossy,crossz; - //printf("inside rot, spi %g, spf %g \n",spi[0],sploc[0]); + // this is not a sufficient routine, + // we need more accurate verifications + - spdot = spi[0]*sploc[0]+spi[1]*sploc[1]+spi[2]*sploc[2]; - theta = fraction*acos(spdot); + // initial and final and inter ang. values + double itheta,iphi,ftheta,fphi,ktheta,kphi; + double spix,spiy,spiz,spfx,spfy,spfz; + double spkx,spky,spkz,iknorm; + + spix = spi[0]; + spiy = spi[1]; + spiz = spi[2]; + + spfx = sploc[0]; + spfy = sploc[1]; + spfz = sploc[2]; + + iphi = acos(spiz); + itheta = acos(spix/sin(iphi)); + + fphi = acos(spfz); + ftheta = acos(spfx/sin(fphi)); - printf("inside rot, theta %g \n",theta); + kphi = iphi + fraction*(fphi-iphi); + ktheta = itheta + fraction*(ftheta-itheta); + + spkx = cos(ktheta)*sin(kphi); + spky = sin(ktheta)*sin(kphi); + spkz = cos(kphi); + + iknorm = spkx*spkx+spky*spky+spkz*spkz; + + spkx *= iknorm; + spky *= iknorm; + spkz *= iknorm; - kix = spi[1]*sploc[2]-spi[2]*sploc[1]; - kiy = spi[2]*sploc[0]-spi[0]*sploc[2]; - kiz = spi[0]*sploc[1]-spi[1]*sploc[0]; + sploc[0] = spkx; + sploc[1] = spky; + sploc[2] = spkz; - //printf("inside rot1.1, ki %g %g %g \n",kix,kiy,kiz); - - inormdot = 1.0/sqrt(spdot); - kinorm = kix*kix+kiy*kiy+kiz*kiz; - if (kinorm == 0.0) { - kix = 0.0; - kiy = 0.0; - kiz = 0.0; - } else { - ikinorm = 1.0/kinorm; - kix *= ikinorm; - kiy *= ikinorm; - kiz *= ikinorm; - } + //double theta,spdot; + //double inormdot,ispinorm; + //double kix,kiy,kiz; + //double kinorm, ikinorm; + //double crossx,crossy,crossz; + + ////printf("inside rot, spi %g, spf %g \n",spi[0],sploc[0]); + + //spdot = spi[0]*sploc[0]+spi[1]*sploc[1]+spi[2]*sploc[2]; + //theta = fraction*acos(spdot); - //printf("inside rot1.2, kin %g %g %g \n",kix,kiy,kiz); + //printf("inside rot, theta %g \n",theta); + + //kix = spi[1]*sploc[2]-spi[2]*sploc[1]; + //kiy = spi[2]*sploc[0]-spi[0]*sploc[2]; + //kiz = spi[0]*sploc[1]-spi[1]*sploc[0]; + // + ////printf("inside rot1.1, ki %g %g %g \n",kix,kiy,kiz); + + //inormdot = 1.0/sqrt(spdot); + //kinorm = kix*kix+kiy*kiy+kiz*kiz; + //if (kinorm == 0.0) { + // kix = 0.0; + // kiy = 0.0; + // kiz = 0.0; + //} else { + // ikinorm = 1.0/kinorm; + // kix *= ikinorm; + // kiy *= ikinorm; + // kiz *= ikinorm; + //} + + ////printf("inside rot1.2, kin %g %g %g \n",kix,kiy,kiz); - crossx = kiy*spi[2]-kiz*spi[1]; - crossy = kiz*spi[0]-kix*spi[2]; - crossz = kix*spi[1]-kiy*spi[0]; - - //printf("inside rot1.3, cross %g %g %g \n",crossx,crossy,crossz); + //crossx = kiy*spi[2]-kiz*spi[1]; + //crossy = kiz*spi[0]-kix*spi[2]; + //crossz = kix*spi[1]-kiy*spi[0]; + // + ////printf("inside rot1.3, cross %g %g %g \n",crossx,crossy,crossz); - sploc[0] = spi[0]*cos(theta)+crossx*sin(theta); - sploc[1] = spi[1]*cos(theta)+crossy*sin(theta); - sploc[2] = spi[2]*cos(theta)+crossz*sin(theta); - - //printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); + //sploc[0] = spi[0]*cos(theta)+crossx*sin(theta); + //sploc[1] = spi[1]*cos(theta)+crossy*sin(theta); + //sploc[2] = spi[2]*cos(theta)+crossz*sin(theta); + // + ////printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); - ispinorm = 1.0/sqrt(sploc[0]*sploc[0]+sploc[1]*sploc[1]+sploc[2]*sploc[2]); + //ispinorm = 1.0/sqrt(sploc[0]*sploc[0]+sploc[1]*sploc[1]+sploc[2]*sploc[2]); - sploc[0] *= ispinorm; - sploc[1] *= ispinorm; - sploc[2] *= ispinorm; - printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); + //sploc[0] *= ispinorm; + //sploc[1] *= ispinorm; + //sploc[2] *= ispinorm; + //printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); } /* ---------------------------------------------------------------------- @@ -943,7 +979,20 @@ void NEB_spin::open(char *file) void NEB_spin::print_status() { - double fnorm2 = sqrt(update->minimize->fnorm_sqr()); + + //double fnorm2 = sqrt(update->minimize->fnorm_sqr()); + + // test fmax spin + int nlocal = atom->nlocal; + double **fm = atom->fm; + double fnorm2; + for (int i = 0; i < nlocal; i++) + fnorm2 += (fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]); + //for (int i = 0; i < nlocal; i++) + // if (mask[i] & groupbit) { + // fnorm2 += (fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]); + // } + double fmaxreplica; MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); double fnorminf = update->minimize->fnorm_inf(); -- GitLab From 490f67d332927091bc58ad02b2499b3414a0a590 Mon Sep 17 00:00:00 2001 From: casievers Date: Wed, 6 Feb 2019 12:05:41 -0800 Subject: [PATCH 0107/1243] third order tensor calculator --- src/USER-PHONON/dynamical_matrix.cpp | 14 ++- src/USER-PHONON/third_order.cpp | 167 ++++++++++----------------- src/USER-PHONON/third_order.h | 2 + 3 files changed, 70 insertions(+), 113 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index 854d46adca..da98a23a7d 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -81,7 +81,7 @@ void DynamicalMatrix::setup() //if all then skip communication groupmap population if (gcount == atom->natoms) - for (int i=0; inatoms; i++) + for (bigint i=0; inatoms; i++) groupmap[i] = i; else create_groupmap(); @@ -268,7 +268,7 @@ void DynamicalMatrix::calculateMatrix() if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal && gm[i-1] >= 0 && gm[j-1] >= 0){ for (int beta=0; beta<3; beta++){ - dynmat[alpha][(gm[j-1])*3+beta] = -f[local_jdx][beta]; + dynmat[alpha][(gm[j-1])*3+beta] -= f[local_jdx][beta]; } } } @@ -321,7 +321,7 @@ void DynamicalMatrix::writeMatrix(double **dynmat) if (!binaryflag && fp) { clearerr(fp); for (int i = 0; i < 3; i++) { - for (int j = 0; j < dynlen; j++) { + for (bigint j = 0; j < dynlen; j++) { if ((j+1)%3==0) fprintf(fp, "%4.8f\n", dynmat[i][j]); else fprintf(fp, "%4.8f ",dynmat[i][j]); } @@ -344,6 +344,8 @@ void DynamicalMatrix::writeMatrix(double **dynmat) void DynamicalMatrix::displace_atom(int local_idx, int direction, int magnitude) { + if (local_idx < 0) return; + double **x = atom->x; int *sametag = atom->sametag; int j = local_idx; @@ -496,7 +498,7 @@ void DynamicalMatrix::create_groupmap() int *temp_groupmap = new int[natoms]; //find number of local atoms in the group (final_gid) - for (int i=1; i<=natoms; i++){ + for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) gid += 1; // gid at the end of loop is final_Gid @@ -506,7 +508,7 @@ void DynamicalMatrix::create_groupmap() gid = 0; //create a map between global atom id and group atom id for each proc - for (int i=1; i<=natoms; i++){ + for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit){ sub_groupmap[gid] = i; @@ -531,7 +533,7 @@ void DynamicalMatrix::create_groupmap() std::sort(temp_groupmap,temp_groupmap+gcount); //populate member groupmap based on temp groupmap - for (int i=0; inatoms) - for (int i=0; inatoms; i++) + for (bigint i=0; inatoms; i++) groupmap[i] = i; else create_groupmap(); @@ -111,6 +111,8 @@ void ThirdOrder::command(int narg, char **arg) igroup = group->find(arg[0]); if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); groupbit = group->bitmask[igroup]; + gcount = group->count(igroup); + dynlen = (gcount)*3; update->setupflag = 1; int style = -1; @@ -187,7 +189,7 @@ void ThirdOrder::options(int narg, char **arg) iarg += 2; } else error->all(FLERR,"Illegal dynamical_matrix command"); } - if (file_flag == 1) { + if (file_flag == 1 and me == 0) { openfile(filename); } } @@ -240,17 +242,20 @@ void ThirdOrder::calculateMatrix() int *gm = groupmap; double **f = atom->f; - update_force(); + double *dynmat = new double[3*dynlen]; + double *fdynmat = new double[3*dynlen]; + memset(&dynmat[0],0,dynlen*sizeof(double)); + memset(&fdynmat[0],0,dynlen*sizeof(double)); if (comm->me == 0 && screen) fprintf(screen,"Calculating Anharmonic Dynamical Matrix...\n"); for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); for (bigint alpha=0; alpha<3; alpha++){ - displace_atom(local_idx, alpha, 1); for (bigint j=1; j<=natoms; j++){ local_jdx = atom->map(j); for (int beta=0; beta<3; beta++){ + displace_atom(local_idx, alpha, 1); displace_atom(local_jdx, beta, 1); update_force(); for (bigint k=1; k<=natoms; k++){ @@ -259,7 +264,7 @@ void ThirdOrder::calculateMatrix() if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 && local_kdx < nlocal) { - //first_derv[k*3+gamma] = f[k][gamma]; + dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; } } } @@ -271,16 +276,12 @@ void ThirdOrder::calculateMatrix() if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 && local_kdx < nlocal) { + dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; } } } displace_atom(local_jdx, beta, 1); - } - } - displace_atom(local_idx,alpha,-2); - for (bigint j=1; j<=natoms; j++){ - local_jdx = atom->map(j); - for (int beta=0; beta<3; beta++){ + displace_atom(local_idx,alpha,-2); displace_atom(local_jdx, beta, 1); update_force(); for (bigint k=1; k<=natoms; k++){ @@ -289,6 +290,7 @@ void ThirdOrder::calculateMatrix() if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 && local_kdx < nlocal) { + dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; } } } @@ -300,119 +302,70 @@ void ThirdOrder::calculateMatrix() if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 && local_kdx < nlocal) { + dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; + dynmat[gm[k-1]*3+gamma] /= -(4 * del * del); } } } displace_atom(local_jdx, beta, 1); + displace_atom(local_idx, alpha, 1); + MPI_Reduce(dynmat,fdynmat,3*dynlen,MPI_DOUBLE,MPI_SUM,0,world); + if (me == 0){ + writeMatrix(fdynmat, gm[i-1], alpha, gm[j-1], beta); + } + memset(&dynmat[0],0,dynlen*sizeof(double)); } } - displace_atom(local_idx,alpha,1); } } - //for (int proc1=0; proc1 < comm->nprocs; proc1++) { - // plocal1 = atom->nlocal; // 1 proc nlocal = 8 - // MPI_Bcast(&plocal1, 1, MPI_INT, proc1, MPI_COMM_WORLD); // plocal1 = 8 - // for (int i = 0; i < plocal1; i++) { - // if (me==proc1 & mask[i] & groupbit) - // group_flag_1 = 1; - // MPI_Bcast(&group_flag_1, 1, MPI_INT, proc1, MPI_COMM_WORLD); - // if (group_flag_1) { - // if (me == proc1) id1 = aid[i]; - // MPI_Bcast(&id1, 1, MPI_INT, proc1, MPI_COMM_WORLD); - // for (int alpha = 0; alpha < 3; alpha++) { - // for (int proc2 = 0; proc2 < comm->nprocs; proc2++) { - // plocal2 = atom->nlocal; - // MPI_Bcast(&plocal2, 1, MPI_INT, proc2, MPI_COMM_WORLD); - // for (int j = 0; j < plocal2; j++) { - // if (me==proc2 & mask[j] & groupbit) - // group_flag_2 = 1; - // MPI_Bcast(&group_flag_2, 1, MPI_INT, proc2, MPI_COMM_WORLD); - // if (mask[j] & groupbit) { - // if (me == proc2) id2 = aid[j]; - // MPI_Bcast(&id2, 1, MPI_INT, proc2, MPI_COMM_WORLD); - // for (int beta = 0; beta < 3; beta++) { -// - // if (me == proc1) x[i][alpha] += del; -// - // if (me == proc2) x[j][beta] += del; - // energy_force(0); -//// - // for (int gamma = 0; gamma < 3; gamma++) { - // for (int k = 0; k < nlocal; k++) - // if (mask[k] & groupbit) { - // first_derv[k*3+gamma] = f[k][gamma]; - // } - // } -// - // if (me == proc2) x[j][beta] -= 2 * del; - // energy_force(0); -//// - // for (int gamma = 0; gamma < 3; gamma++) { - // for (int k = 0; k < nlocal; k++) - // if (mask[k] & groupbit) { - // first_derv[k*3+gamma] -= f[k][gamma]; - // } - // } -// - // if (me == proc2) x[j][beta] += 2 * del; -// - // if (me == proc1) x[i][alpha] -= 2 * del; -// - // energy_force(0); -//// - // for (int gamma = 0; gamma < 3; gamma++) { - // for (int k = 0; k < nlocal; k++) - // if (mask[k] & groupbit) { - // first_derv[k*3+gamma] -= f[k][gamma]; - // } - // } -//// - // if (me == proc2) x[j][beta] -= 2 * del; - // energy_force(0); -//// - // for (int k = 0; k < nlocal; k++) - // if (mask[k] & groupbit) { - // for (int gamma = 0; gamma < 3; gamma++) { - // first_derv[k*3+gamma] += f[k][gamma]; - // first_derv[k*3+gamma] /= -4*del*del; - // } - // double norm = pow(first_derv[k*3], 2) - // + pow(first_derv[k*3+1], 2) - // + pow(first_derv[k+3+2], 2); - // if (fp && norm > 1.0e-16) - // fprintf(fp, - // "%d %d %d %d %d %7.8f %7.8f %7.8f\n", - // id1, alpha + 1, id2, beta + 1, aid[k], - // first_derv[k*3] * conversion, - // first_derv[k*3+1] * conversion, - // first_derv[k*3+2] * conversion); - // } -//// - // if (me == proc2) x[j][beta] += del; -// - // if (me == proc1) x[i][alpha] += del; - // } - // } - // } - // } -//// - // } - // } - // } - //} -// + delete [] dynmat; + delete [] fdynmat; if (screen && me ==0 ) fprintf(screen,"Finished Calculating Third Order Tensor\n"); } +/* ---------------------------------------------------------------------- + write dynamical matrix +------------------------------------------------------------------------- */ + +void ThirdOrder::writeMatrix(double *dynmat, int i, int a, int j, int b) +{ + if (me != 0) + return; + + if (!binaryflag && fp) { + clearerr(fp); + for (int k = 0; k < gcount; k++){ + double norm = pow(dynmat[k*3], 2) + + pow(dynmat[k*3+1], 2) + + pow(dynmat[k+3+2], 2); + if (norm > 1.0e-16) + fprintf(fp, + "%d %d %d %d %d %7.8f %7.8f %7.8f\n", + i+1, a + 1, j+1, b + 1, groupmap[k]+1, + dynmat[k*3] * conversion, + dynmat[k*3+1] * conversion, + dynmat[k*3+2] * conversion); + } + } + else if (binaryflag && fp){ + clearerr(fp); + fwrite(&dynmat[0], sizeof(double), dynlen, fp); + } + if (ferror(fp)) error->one(FLERR,"Error writing to file"); + +} + /* ---------------------------------------------------------------------- Displace atoms ---------------------------------------------------------------------- */ void ThirdOrder::displace_atom(int local_idx, int direction, int magnitude) { + if (local_idx < 0) return; + double **x = atom->x; int *sametag = atom->sametag; int j = local_idx; @@ -554,7 +507,7 @@ void ThirdOrder::create_groupmap() int *temp_groupmap = new int[natoms]; //find number of local atoms in the group (final_gid) - for (int i=1; i<=natoms; i++){ + for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) gid += 1; // gid at the end of loop is final_Gid @@ -564,7 +517,7 @@ void ThirdOrder::create_groupmap() gid = 0; //create a map between global atom id and group atom id for each proc - for (int i=1; i<=natoms; i++){ + for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit){ sub_groupmap[gid] = i; @@ -589,7 +542,7 @@ void ThirdOrder::create_groupmap() std::sort(temp_groupmap,temp_groupmap+gcount); //populate member groupmap based on temp groupmap - for (int i=0; i Date: Wed, 6 Feb 2019 14:42:37 -0700 Subject: [PATCH 0108/1243] Add team-based calcs to some KOKKOS package pair_styles --- src/KOKKOS/kokkos.cpp | 8 + src/KOKKOS/kokkos.h | 1 + src/KOKKOS/kokkos_type.h | 46 +++++ src/KOKKOS/pair_kokkos.h | 393 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 439 insertions(+), 9 deletions(-) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 9973b5a688..5d041bcbb0 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -192,6 +192,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) forward_comm_on_host = 0; reverse_comm_on_host = 0; gpu_direct_flag = 1; + team_flag = 0; #if KOKKOS_USE_CUDA // only if we can safely detect, that GPU-direct is not available, change default @@ -228,6 +229,7 @@ void KokkosLMP::accelerator(int narg, char **arg) exchange_comm_classic = forward_comm_classic = reverse_comm_classic = 0; exchange_comm_on_host = forward_comm_on_host = reverse_comm_on_host = 0; gpu_direct_flag = 1; + team_flag = 0; int iarg = 0; while (iarg < narg) { @@ -317,6 +319,12 @@ void KokkosLMP::accelerator(int narg, char **arg) else if (strcmp(arg[iarg+1],"on") == 0) gpu_direct_flag = 1; else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; + } else if (strcmp(arg[iarg],"team") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); + if (strcmp(arg[iarg+1],"off") == 0) team_flag = 0; + else if (strcmp(arg[iarg+1],"on") == 0) team_flag = 1; + else error->all(FLERR,"Illegal package kokkos command"); + iarg += 2; } else error->all(FLERR,"Illegal package kokkos command"); } diff --git a/src/KOKKOS/kokkos.h b/src/KOKKOS/kokkos.h index cd429d5c1c..a665329d70 100644 --- a/src/KOKKOS/kokkos.h +++ b/src/KOKKOS/kokkos.h @@ -36,6 +36,7 @@ class KokkosLMP : protected Pointers { int numa; int auto_sync; int gpu_direct_flag; + int team_flag; KokkosLMP(class LAMMPS *, int, char **); ~KokkosLMP(); diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index b88c92ff73..16d7c3cbd2 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -448,6 +448,52 @@ struct s_EV_FLOAT_REAX { }; typedef struct s_EV_FLOAT_REAX EV_FLOAT_REAX; +struct s_FEV_FLOAT { + F_FLOAT f[3]; + E_FLOAT evdwl; + E_FLOAT ecoul; + E_FLOAT v[6]; + KOKKOS_INLINE_FUNCTION + s_FEV_FLOAT() { + f[0] = 0; f[1] = 0; f[2] = 0; + evdwl = 0; + ecoul = 0; + v[0] = 0; v[1] = 0; v[2] = 0; + v[3] = 0; v[4] = 0; v[5] = 0; + } + + KOKKOS_INLINE_FUNCTION + void operator+=(const s_FEV_FLOAT &rhs) { + f[0] += rhs.f[0]; + f[1] += rhs.f[1]; + f[2] += rhs.f[2]; + evdwl += rhs.evdwl; + ecoul += rhs.ecoul; + v[0] += rhs.v[0]; + v[1] += rhs.v[1]; + v[2] += rhs.v[2]; + v[3] += rhs.v[3]; + v[4] += rhs.v[4]; + v[5] += rhs.v[5]; + } + + KOKKOS_INLINE_FUNCTION + void operator+=(const volatile s_FEV_FLOAT &rhs) volatile { + f[0] += rhs.f[0]; + f[1] += rhs.f[1]; + f[2] += rhs.f[2]; + evdwl += rhs.evdwl; + ecoul += rhs.ecoul; + v[0] += rhs.v[0]; + v[1] += rhs.v[1]; + v[2] += rhs.v[2]; + v[3] += rhs.v[3]; + v[4] += rhs.v[4]; + v[5] += rhs.v[5]; + } +}; +typedef struct s_FEV_FLOAT FEV_FLOAT; + #ifndef PREC_POS #define PREC_POS PRECISION #endif diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index ab616d2c07..8758b2f03c 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -86,6 +86,7 @@ struct PairComputeFunctor { NeighListKokkos* list_ptr): c(*c_ptr),list(*list_ptr) { // allocate duplicated memory + f = c.f; dup_f = Kokkos::Experimental::create_scatter_view::value >(c.f); dup_eatom = Kokkos::Experimental::create_scatter_view::value >(c.d_eatom); dup_vatom = Kokkos::Experimental::create_scatter_view::value >(c.d_vatom); @@ -255,6 +256,329 @@ struct PairComputeFunctor { return ev; } + // Use TeamPolicy, assume Newton off, Full Neighborlist, and no energy/virial + // Loop over neighbors of one atom without coulomb interaction + // This function is called in parallel + KOKKOS_FUNCTION + void compute_item_team(Kokkos::TeamPolicy<>::member_type team, + const NeighListKokkos &list, const NoCoulTag&) const { + + const int inum = team.league_size(); + const int atoms_per_team = team.team_size(); + const int firstatom = team.league_rank()*atoms_per_team; + const int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; + Kokkos::parallel_for(Kokkos::TeamThreadRange(team, firstatom, lastatom), [&] (const int &ii) { + + const int i = list.d_ilist[ii]; + const X_FLOAT xtmp = c.x(i,0); + const X_FLOAT ytmp = c.x(i,1); + const X_FLOAT ztmp = c.x(i,2); + const int itype = c.type(i); + + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); + const int jnum = list.d_numneigh[i]; + + t_scalar3 fsum; + + Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,jnum), + [&] (const int jj, t_scalar3& ftmp) { + + int j = neighbors_i(jj); + const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - c.x(j,0); + const X_FLOAT dely = ytmp - c.x(j,1); + const X_FLOAT delz = ztmp - c.x(j,2); + const int jtype = c.type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { + + const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + + ftmp.x += delx*fpair; + ftmp.y += dely*fpair; + ftmp.z += delz*fpair; + } + + },fsum); + + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) += fsum.x; + f(i,1) += fsum.y; + f(i,2) += fsum.z; + }); + + }); + } + + // Use TeamPolicy, assume Newton off, Full Neighborlist, and no energy/virial + // Loop over neighbors of one atom with coulomb interaction + // This function is called in parallel + KOKKOS_FUNCTION + void compute_item_team(Kokkos::TeamPolicy<>::member_type team, + const NeighListKokkos &list, const CoulTag& ) const { + + const int inum = team.league_size(); + const int atoms_per_team = team.team_size(); + int firstatom = team.league_rank()*atoms_per_team; + int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; + Kokkos::parallel_for(Kokkos::TeamThreadRange(team, firstatom, lastatom), [&] (const int &ii) { + + const int i = list.d_ilist[ii]; + const X_FLOAT xtmp = c.x(i,0); + const X_FLOAT ytmp = c.x(i,1); + const X_FLOAT ztmp = c.x(i,2); + const int itype = c.type(i); + const F_FLOAT qtmp = c.q(i); + + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); + const int jnum = list.d_numneigh[i]; + + t_scalar3 fsum; + + Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,jnum), + [&] (const int jj, t_scalar3& ftmp) { + int j = neighbors_i(jj); + const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; + const F_FLOAT factor_coul = c.special_coul[sbmask(j)]; + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - c.x(j,0); + const X_FLOAT dely = ytmp - c.x(j,1); + const X_FLOAT delz = ztmp - c.x(j,2); + const int jtype = c.type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { + + F_FLOAT fpair = F_FLOAT(); + + if(rsq < (STACKPARAMS?c.m_cut_ljsq[itype][jtype]:c.d_cut_ljsq(itype,jtype))) + fpair+=factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + if(rsq < (STACKPARAMS?c.m_cut_coulsq[itype][jtype]:c.d_cut_coulsq(itype,jtype))) + fpair+=c.template compute_fcoul(rsq,i,j,itype,jtype,factor_coul,qtmp); + + ftmp.x += delx*fpair; + ftmp.y += dely*fpair; + ftmp.z += delz*fpair; + } + },fsum); + + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) += fsum.x; + f(i,1) += fsum.y; + f(i,2) += fsum.z; + }); + }); + } + + + // Use TeamPolicy, assume Newton off, Full Neighborlist, and energy/virial + // Loop over neighbors of one atom without coulomb interaction + // This function is called in parallel + KOKKOS_FUNCTION + EV_FLOAT compute_item_team_ev(Kokkos::TeamPolicy<>::member_type team, + const NeighListKokkos &list, const NoCoulTag&) const { + + EV_FLOAT ev; + + const int inum = team.league_size(); + const int atoms_per_team = team.team_size(); + const int firstatom = team.league_rank()*atoms_per_team; + const int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; + Kokkos::parallel_for(Kokkos::TeamThreadRange(team, firstatom, lastatom), [&] (const int &ii) { + + + const int i = list.d_ilist[ii]; + const X_FLOAT xtmp = c.x(i,0); + const X_FLOAT ytmp = c.x(i,1); + const X_FLOAT ztmp = c.x(i,2); + const int itype = c.type(i); + + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); + const int jnum = list.d_numneigh[i]; + + FEV_FLOAT fev; + + Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,jnum), + [&] (const int jj, FEV_FLOAT& fev_tmp) { + + int j = neighbors_i(jj); + const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - c.x(j,0); + const X_FLOAT dely = ytmp - c.x(j,1); + const X_FLOAT delz = ztmp - c.x(j,2); + const int jtype = c.type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { + + const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + + fev_tmp.f[0] += delx*fpair; + fev_tmp.f[1] += dely*fpair; + fev_tmp.f[2] += delz*fpair; + + F_FLOAT evdwl = 0.0; + if (c.eflag) { + evdwl = factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); + fev.evdwl += 0.5*evdwl; + } + if (c.vflag_either) { + fev.v[0] += 0.5*delx*delx*fpair; + fev.v[1] += 0.5*dely*dely*fpair; + fev.v[2] += 0.5*delz*delz*fpair; + fev.v[3] += 0.5*delx*dely*fpair; + fev.v[4] += 0.5*delx*delz*fpair; + fev.v[5] += 0.5*dely*delz*fpair; + } + } + },fev); + + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) += fev.f[0]; + f(i,1) += fev.f[1]; + f(i,2) += fev.f[2]; + + if (c.eflag_global) + ev.evdwl += fev.evdwl; + + if (c.eflag_atom) + d_eatom(i,0) += fev.evdwl; + + if (c.vflag_global) { + ev.v[0] += fev.v[0]; + ev.v[1] += fev.v[1]; + ev.v[2] += fev.v[2]; + ev.v[3] += fev.v[3]; + ev.v[4] += fev.v[4]; + ev.v[5] += fev.v[5]; + } + + if (c.vflag_atom) { + d_vatom(i,0) += fev.v[0]; + d_vatom(i,1) += fev.v[1]; + d_vatom(i,2) += fev.v[2]; + d_vatom(i,3) += fev.v[3]; + d_vatom(i,4) += fev.v[4]; + d_vatom(i,5) += fev.v[5]; + } + }); + }); + return ev; + } + + // Use TeamPolicy, assume Newton off, Full Neighborlist, and energy/virial + // Loop over neighbors of one atom with coulomb interaction + // This function is called in parallel + KOKKOS_FUNCTION + EV_FLOAT compute_item_team_ev(Kokkos::TeamPolicy<>::member_type team, + const NeighListKokkos &list, const CoulTag& ) const { + + EV_FLOAT ev; + + const int inum = team.league_size(); + const int atoms_per_team = team.team_size(); + int firstatom = team.league_rank()*atoms_per_team; + int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; + Kokkos::parallel_for(Kokkos::TeamThreadRange(team, firstatom, lastatom), [&] (const int &ii) { + + const int i = list.d_ilist[ii]; + const X_FLOAT xtmp = c.x(i,0); + const X_FLOAT ytmp = c.x(i,1); + const X_FLOAT ztmp = c.x(i,2); + const int itype = c.type(i); + const F_FLOAT qtmp = c.q(i); + + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); + const int jnum = list.d_numneigh[i]; + + FEV_FLOAT fev; + + Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(team,jnum), + [&] (const int jj, FEV_FLOAT& fev_tmp) { + int j = neighbors_i(jj); + const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; + const F_FLOAT factor_coul = c.special_coul[sbmask(j)]; + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - c.x(j,0); + const X_FLOAT dely = ytmp - c.x(j,1); + const X_FLOAT delz = ztmp - c.x(j,2); + const int jtype = c.type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { + + F_FLOAT fpair = F_FLOAT(); + + if(rsq < (STACKPARAMS?c.m_cut_ljsq[itype][jtype]:c.d_cut_ljsq(itype,jtype))) + fpair+=factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); + if(rsq < (STACKPARAMS?c.m_cut_coulsq[itype][jtype]:c.d_cut_coulsq(itype,jtype))) + fpair+=c.template compute_fcoul(rsq,i,j,itype,jtype,factor_coul,qtmp); + + fev.f[0] += delx*fpair; + fev.f[1] += dely*fpair; + fev.f[2] += delz*fpair; + + F_FLOAT evdwl = 0.0; + F_FLOAT ecoul = 0.0; + if (c.eflag) { + if(rsq < (STACKPARAMS?c.m_cut_ljsq[itype][jtype]:c.d_cut_ljsq(itype,jtype))) { + evdwl = factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); + ev.evdwl += 0.5*evdwl; + } + if(rsq < (STACKPARAMS?c.m_cut_coulsq[itype][jtype]:c.d_cut_coulsq(itype,jtype))) { + ecoul = c.template compute_ecoul(rsq,i,j,itype,jtype,factor_coul,qtmp); + ev.ecoul += 0.5*ecoul; + } + } + if (c.vflag) { + fev.v[0] += 0.5*delx*delx*fpair; + fev.v[1] += 0.5*dely*dely*fpair; + fev.v[2] += 0.5*delz*delz*fpair; + fev.v[3] += 0.5*delx*dely*fpair; + fev.v[4] += 0.5*delx*delz*fpair; + fev.v[5] += 0.5*dely*delz*fpair; + } + } + },fev); + + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) += fev.f[0]; + f(i,1) += fev.f[1]; + f(i,2) += fev.f[2]; + + if (c.eflag_global) { + ev.evdwl += fev.evdwl; + ev.ecoul += fev.ecoul; + } + + if (c.eflag_atom) + d_eatom(i,0) += fev.evdwl + fev.ecoul; + + if (c.vflag_global) { + ev.v[0] += fev.v[0]; + ev.v[1] += fev.v[1]; + ev.v[2] += fev.v[2]; + ev.v[3] += fev.v[3]; + ev.v[4] += fev.v[4]; + ev.v[5] += fev.v[5]; + } + + if (c.vflag_atom) { + d_vatom(i,0) += fev.v[0]; + d_vatom(i,1) += fev.v[1]; + d_vatom(i,2) += fev.v[2]; + d_vatom(i,3) += fev.v[3]; + d_vatom(i,4) += fev.v[4]; + d_vatom(i,5) += fev.v[5]; + } + }); + }); + return ev; + } + KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, @@ -355,6 +679,16 @@ struct PairComputeFunctor { else energy_virial += compute_item<1,0>(i,list,typename DoCoul::type()); } + + KOKKOS_INLINE_FUNCTION + void operator()(const typename Kokkos::TeamPolicy<>::member_type& team) const { + compute_item_team(team,list,typename DoCoul::type()); + } + + KOKKOS_INLINE_FUNCTION + void operator()(const typename Kokkos::TeamPolicy<>::member_type& team, value_type &energy_virial) const { + energy_virial += compute_item_team_ev(team,list,typename DoCoul::type()); + } }; template @@ -489,6 +823,15 @@ struct PairComputeFunctor { void operator()(const int i, value_type &energy_virial) const { energy_virial += compute_item<1,0>(i,list,typename DoCoul::type()); } + + KOKKOS_INLINE_FUNCTION + void operator()(const typename Kokkos::TeamPolicy<>::member_type& team) const + {} + + KOKKOS_INLINE_FUNCTION + void operator()(const typename Kokkos::TeamPolicy<>::member_type& team, value_type &energy_virial) const + {} + }; // Filter out Neighflags which are not supported for PairStyle @@ -507,20 +850,52 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable return ev; } +template +int GetTeamSize(FunctorStyle& functor, int team_size, int vector_length) { + int team_size_max = Kokkos::TeamPolicy<>::team_size_max(functor); + +#ifdef KOKKOS_ENABLE_CUDA + if(team_size*vector_length > team_size_max) + team_size = team_size_max/vector_length; +#else + team_size = 1; +#endif + return team_size; +} + // Submit ParallelFor for NEIGHFLAG=HALF,HALFTHREAD,FULL,N2 template EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if<(NEIGHFLAG&PairStyle::EnabledNeighFlags) != 0, NeighListKokkos*>::type list) { EV_FLOAT ev; - if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { - PairComputeFunctor ff(fpair,list); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); - else Kokkos::parallel_for(list->inum,ff); - ff.contribute(); + if (fpair->lmp->kokkos->team_flag) { + int vector_length = 8; + int atoms_per_team = 32; + + if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { + PairComputeFunctor ff(fpair,list); + atoms_per_team = GetTeamSize(ff, atoms_per_team, vector_length); + Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); + else Kokkos::parallel_for(policy,ff); + } else { + PairComputeFunctor ff(fpair,list); + atoms_per_team = GetTeamSize(ff, atoms_per_team, vector_length); + Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); + else Kokkos::parallel_for(policy,ff); + } } else { - PairComputeFunctor ff(fpair,list); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); - else Kokkos::parallel_for(list->inum,ff); - ff.contribute(); + if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { + PairComputeFunctor ff(fpair,list); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); + else Kokkos::parallel_for(list->inum,ff); + ff.contribute(); + } else { + PairComputeFunctor ff(fpair,list); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(list->inum,ff,ev); + else Kokkos::parallel_for(list->inum,ff); + ff.contribute(); + } } return ev; } -- GitLab From 4fe6528ed49ec73b25f1e372b785bac6d0b726ee Mon Sep 17 00:00:00 2001 From: efetis Date: Wed, 6 Feb 2019 16:56:09 -0800 Subject: [PATCH 0109/1243] Add support for Sphinx+PDF+MathJax --- doc/.gitignore | 1 + doc/Makefile | 38 +++++++++++++++++++++++--------- doc/src/JPG/coul_soft.jpg | Bin 12676 -> 38635 bytes doc/src/JPG/lj_soft.jpg | Bin 12313 -> 35805 bytes doc/src/JPG/uef_frames.jpg | Bin 12271 -> 37518 bytes doc/utils/sphinx-config/conf.py | 6 +++-- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/doc/.gitignore b/doc/.gitignore index 7d30949237..96112ac19c 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,3 +1,4 @@ +/latex /html /spelling /LAMMPS.epub diff --git a/doc/Makefile b/doc/Makefile index d117c2d98c..3bb4c44502 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -56,7 +56,7 @@ clean-all: clean rm -rf $(BUILDDIR)/* utils/txt2html/txt2html.exe clean: - rm -rf $(RSTDIR) html old epub + rm -rf $(RSTDIR) html old epub latex rm -rf spelling clean-spelling: @@ -115,21 +115,39 @@ mobi: epub @ebook-convert LAMMPS.epub LAMMPS.mobi @echo "Conversion finished. The MOBI manual file is created." -pdf: utils/txt2html/txt2html.exe +pdf: $(OBJECTS) $(ANCHORCHECK) + @(\ + . $(VENV)/bin/activate ;\ + cp -r src/* $(RSTDIR)/ ;\ + sphinx-build $(SPHINXEXTRA) -b latex -c utils/sphinx-config -d $(BUILDDIR)/doctrees $(RSTDIR) latex ;\ + echo "############################################" ;\ + doc_anchor_check src/*.txt ;\ + echo "############################################" ;\ + deactivate ;\ + ) + @cd latex && \ + sed -i '' 's/\\begin{equation}//g' LAMMPS.tex && \ + sed -i '' 's/\\end{equation}//g' LAMMPS.tex && \ + make && \ + mv LAMMPS.pdf ../Manual.pdf && \ + cd ../; @(\ - set -e; \ cd src/Developer; \ pdflatex developer; \ pdflatex developer; \ mv developer.pdf ../../Developer.pdf; \ - cd ..; \ - ../utils/txt2html/txt2html.exe -b *.txt; \ - htmldoc --batch lammps.book; \ - for s in `echo *.txt | sed -e 's/ \(pairs\|bonds\|angles\|dihedrals\|impropers\|commands_list\|fixes\|computes\).txt/ /g' | sed -e 's,\.txt,\.html,g'` ; \ - do grep -q ^$$s lammps.book || \ - echo WARNING: doc file $$s missing in src/lammps.book; done; \ - rm *.html; \ + cd ../../; \ ) + @rm -rf latex/_sources + @rm -rf latex/PDF + @rm -rf latex/USER + @cp -r src/PDF latex/PDF + @cp -r src/USER latex/USER + @rm -rf latex/PDF/.[sg]* + @rm -rf latex/USER/.[sg]* + @rm -rf latex/USER/*/.[sg]* + @rm -rf latex/USER/*/*.[sg]* + @echo "Build finished. Manual.pdf and Developer.pdf are in this directory." old: utils/txt2html/txt2html.exe @rm -rf old diff --git a/doc/src/JPG/coul_soft.jpg b/doc/src/JPG/coul_soft.jpg index d2cc4c0c9af061cd00618ce42821a845073fbe2c..618d23b3060498b188b937ece2682f5f5911137f 100644 GIT binary patch literal 38635 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 diff --git a/doc/src/JPG/lj_soft.jpg b/doc/src/JPG/lj_soft.jpg index 47c6a04b9183d3af54795000ccde6732c6f075d6..98404f857d351a86433f2a20ebcbb0eeeea43748 100644 GIT binary patch literal 35805 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�d!-_Z^@0(lg-nYv-A_ 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 L*nL^d|8D{Sd&>(x literal 12313 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 ADF6Tf delta 11934 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 diff --git a/doc/utils/sphinx-config/conf.py b/doc/utils/sphinx-config/conf.py index 3056687ff8..736aac3eb9 100644 --- a/doc/utils/sphinx-config/conf.py +++ b/doc/utils/sphinx-config/conf.py @@ -211,7 +211,9 @@ latex_elements = { #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. -#'preamble': '', +'preamble': r''' +\setcounter{tocdepth}{2} +''' } # Grouping the document tree into LaTeX files. List of tuples @@ -229,7 +231,7 @@ latex_documents = [ # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False - +latex_toplevel_sectioning = 'part' # If true, show page references after internal links. #latex_show_pagerefs = False -- GitLab From 7c1fb847f4a006a8713e48939910a368f82819b8 Mon Sep 17 00:00:00 2001 From: efetis Date: Wed, 6 Feb 2019 17:32:47 -0800 Subject: [PATCH 0110/1243] Slight tweak to sed in doc/Makefile --- doc/Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 3bb4c44502..a38186666a 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -126,8 +126,13 @@ pdf: $(OBJECTS) $(ANCHORCHECK) deactivate ;\ ) @cd latex && \ - sed -i '' 's/\\begin{equation}//g' LAMMPS.tex && \ - sed -i '' 's/\\end{equation}//g' LAMMPS.tex && \ + sed 's/latexmk -pdf -dvi- -ps-/pdflatex/g' Makefile > temp && \ + mv temp Makefile && \ + sed 's/\\begin{equation}//g' LAMMPS.tex > tmp.tex && \ + mv tmp.tex LAMMPS.tex && \ + sed 's/\\end{equation}//g' LAMMPS.tex > tmp.tex && \ + mv tmp.tex LAMMPS.tex && \ + make && \ make && \ mv LAMMPS.pdf ../Manual.pdf && \ cd ../; -- GitLab From 927dc262b21f048576fe5de7ea1c1214c3654f4d Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 6 Feb 2019 23:41:45 -0600 Subject: [PATCH 0111/1243] Update CMake & Install.py for KIM API v2 --- cmake/CMakeLists.txt | 4 ++-- lib/kim/Install.py | 10 +++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index ae2510c68b..ffef5d07c5 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -663,8 +663,8 @@ if(PKG_KIM) enable_language(Fortran) include(ExternalProject) ExternalProject_Add(kim_build - URL https://s3.openkim.org/kim-api/kim-api-v2-2.0.0-beta.3.txz - URL_MD5 67c103a00e84865848d004837262c76e + URL https://s3.openkim.org/kim-api/kim-api-v2-2.0.0.txz + URL_MD5 1ff8f563ad5991f7a2a25b35a13d7308 BINARY_DIR build CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} diff --git a/lib/kim/Install.py b/lib/kim/Install.py index 544fe2b65d..e2465eec85 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -18,7 +18,7 @@ parser = ArgumentParser(prog='Install.py', # settings thisdir = fullpath('.') -version = "kim-api-v2-2.0.0-beta.3" +version = "kim-api-v2-2.0.0" # help message @@ -35,19 +35,15 @@ Syntax from lib dir: python Install.py -b -v version -a kim-name Examples: make lib-kim args="-b" # install KIM API lib with only example models -make lib-kim args="-b -a Glue_Ercolessi_Adams_Al__MO_324507536345_001" # Ditto plus one model +make lib-kim args="-b -a EAM_ErcolessiAdams_1994_Al__MO_324507536345_002" # Ditto plus one model make lib-kim args="-b -a everything" # install KIM API lib with all models -make lib-kim args="-n -a EAM_Dynamo_Ackland_W__MO_141627196590_002" # only add one model or model driver +make lib-kim args="-n -a EAM_Dynamo_Ackland_2003_W__MO_141627196590_005" # only add one model or model driver See the list of KIM model drivers here: https://openkim.org/kim-items/model-drivers/alphabetical See the list of all KIM models here: https://openkim.org/kim-items/models/by-model-drivers - -See the list of example KIM models included by default here: -https://openkim.org/kim-api -in the "What is in the KIM API source package?" section """ pgroup = parser.add_mutually_exclusive_group() -- GitLab From 6068a719ff4d6641a5f703594da83b7d8fadcf65 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 6 Feb 2019 23:53:47 -0600 Subject: [PATCH 0112/1243] Updated example/kim/log.* files --- ... log.06Feb2019.in.kim.lj.lmp.newton-off.1} | 24 +++++++++---------- ... log.06Feb2019.in.kim.lj.lmp.newton-off.4} | 22 ++++++++--------- ...> log.06Feb2019.in.kim.lj.lmp.newton-on.1} | 20 ++++++++-------- ...> log.06Feb2019.in.kim.lj.lmp.newton-on.4} | 22 ++++++++--------- ...1 => log.06Feb2019.in.kim.lj.newton-off.1} | 22 ++++++++--------- ...4 => log.06Feb2019.in.kim.lj.newton-off.4} | 22 ++++++++--------- ....1 => log.06Feb2019.in.kim.lj.newton-on.1} | 22 ++++++++--------- ....4 => log.06Feb2019.in.kim.lj.newton-on.4} | 22 ++++++++--------- 8 files changed, 88 insertions(+), 88 deletions(-) rename examples/kim/{log.12Dec2018.in.kim.lj.lmp.newton-off.1 => log.06Feb2019.in.kim.lj.lmp.newton-off.1} (71%) rename examples/kim/{log.12Dec2018.in.kim.lj.lmp.newton-off.4 => log.06Feb2019.in.kim.lj.lmp.newton-off.4} (71%) rename examples/kim/{log.12Dec2018.in.kim.lj.lmp.newton-on.1 => log.06Feb2019.in.kim.lj.lmp.newton-on.1} (74%) rename examples/kim/{log.12Dec2018.in.kim.lj.lmp.newton-on.4 => log.06Feb2019.in.kim.lj.lmp.newton-on.4} (71%) rename examples/kim/{log.12Dec2018.in.kim.lj.newton-off.1 => log.06Feb2019.in.kim.lj.newton-off.1} (75%) rename examples/kim/{log.12Dec2018.in.kim.lj.newton-off.4 => log.06Feb2019.in.kim.lj.newton-off.4} (80%) rename examples/kim/{log.12Dec2018.in.kim.lj.newton-on.1 => log.06Feb2019.in.kim.lj.newton-on.1} (75%) rename examples/kim/{log.12Dec2018.in.kim.lj.newton-on.4 => log.06Feb2019.in.kim.lj.newton-on.4} (80%) diff --git a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.1 b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-off.1 similarity index 71% rename from examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.1 rename to examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-off.1 index 0b67cc1ccb..5925fd750d 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.1 +++ b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-off.1 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00307703 secs + Time spent = 0.004499 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -26,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 20.37 | 20.37 | 20.37 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.58348 on 1 procs for 100 steps with 32000 atoms +Loop time of 2.92885 on 1 procs for 100 steps with 32000 atoms -Performance: 3.344 ns/day, 7.176 hours/ns, 38.707 timesteps/s -99.9% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 2.950 ns/day, 8.136 hours/ns, 34.143 timesteps/s +99.1% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.2621 | 2.2621 | 2.2621 | 0.0 | 87.56 -Neigh | 0.28294 | 0.28294 | 0.28294 | 0.0 | 10.95 -Comm | 0.0057185 | 0.0057185 | 0.0057185 | 0.0 | 0.22 -Output | 0.00010109 | 0.00010109 | 0.00010109 | 0.0 | 0.00 -Modify | 0.023396 | 0.023396 | 0.023396 | 0.0 | 0.91 -Other | | 0.009175 | | | 0.36 +Pair | 2.5638 | 2.5638 | 2.5638 | 0.0 | 87.54 +Neigh | 0.31935 | 0.31935 | 0.31935 | 0.0 | 10.90 +Comm | 0.006833 | 0.006833 | 0.006833 | 0.0 | 0.23 +Output | 0.000107 | 0.000107 | 0.000107 | 0.0 | 0.00 +Modify | 0.027806 | 0.027806 | 0.027806 | 0.0 | 0.95 +Other | | 0.01091 | | | 0.37 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -52,4 +52,4 @@ Total # of neighbors = 2370499 Ave neighs/atom = 74.0781 Neighbor list builds = 3 Dangerous builds = 0 -Total wall time: 0:00:02 +Total wall time: 0:00:03 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.4 b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-off.4 similarity index 71% rename from examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.4 rename to examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-off.4 index e2ee8e39bb..c1ca108c7b 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-off.4 +++ b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-off.4 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.000934124 secs + Time spent = 0.001039 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -26,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 8.013 | 8.013 | 8.013 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 0.76167 on 4 procs for 100 steps with 32000 atoms +Loop time of 0.778581 on 4 procs for 100 steps with 32000 atoms -Performance: 11.343 ns/day, 2.116 hours/ns, 131.290 timesteps/s -99.7% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 11.097 ns/day, 2.163 hours/ns, 128.439 timesteps/s +99.8% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.65549 | 0.6589 | 0.66089 | 0.3 | 86.51 -Neigh | 0.075691 | 0.075959 | 0.07641 | 0.1 | 9.97 -Comm | 0.0073049 | 0.007397 | 0.0074785 | 0.1 | 0.97 -Output | 5.6982e-05 | 0.00014746 | 0.00024986 | 0.0 | 0.02 -Modify | 0.0068338 | 0.0068703 | 0.0068941 | 0.0 | 0.90 -Other | | 0.0124 | | | 1.63 +Pair | 0.65171 | 0.65891 | 0.67656 | 1.3 | 84.63 +Neigh | 0.07924 | 0.079548 | 0.07997 | 0.1 | 10.22 +Comm | 0.006755 | 0.0069015 | 0.007072 | 0.2 | 0.89 +Output | 4.6e-05 | 9.725e-05 | 0.000203 | 0.0 | 0.01 +Modify | 0.006841 | 0.006941 | 0.007015 | 0.1 | 0.89 +Other | | 0.02618 | | | 3.36 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.1 b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-on.1 similarity index 74% rename from examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.1 rename to examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-on.1 index 91731438de..53555743d7 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.1 +++ b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-on.1 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00311494 secs + Time spent = 0.003479 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -26,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 19.23 | 19.23 | 19.23 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.22646 on 1 procs for 100 steps with 32000 atoms +Loop time of 2.17978 on 1 procs for 100 steps with 32000 atoms -Performance: 3.881 ns/day, 6.185 hours/ns, 44.914 timesteps/s +Performance: 3.964 ns/day, 6.055 hours/ns, 45.876 timesteps/s 99.9% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.0344 | 2.0344 | 2.0344 | 0.0 | 91.38 -Neigh | 0.14575 | 0.14575 | 0.14575 | 0.0 | 6.55 -Comm | 0.01127 | 0.01127 | 0.01127 | 0.0 | 0.51 -Output | 0.000103 | 0.000103 | 0.000103 | 0.0 | 0.00 -Modify | 0.024057 | 0.024057 | 0.024057 | 0.0 | 1.08 -Other | | 0.01083 | | | 0.49 +Pair | 1.9892 | 1.9892 | 1.9892 | 0.0 | 91.26 +Neigh | 0.14506 | 0.14506 | 0.14506 | 0.0 | 6.65 +Comm | 0.011049 | 0.011049 | 0.011049 | 0.0 | 0.51 +Output | 9.1e-05 | 9.1e-05 | 9.1e-05 | 0.0 | 0.00 +Modify | 0.02347 | 0.02347 | 0.02347 | 0.0 | 1.08 +Other | | 0.01094 | | | 0.50 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.4 b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-on.4 similarity index 71% rename from examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.4 rename to examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-on.4 index 92eb8ba8bc..f0fdf66193 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.lmp.newton-on.4 +++ b/examples/kim/log.06Feb2019.in.kim.lj.lmp.newton-on.4 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.000946045 secs + Time spent = 0.000919 secs Neighbor list info ... update every 1 steps, delay 0 steps, check yes max neighbors/atom: 2000, page size: 100000 @@ -26,20 +26,20 @@ Per MPI rank memory allocation (min/avg/max) = 7.632 | 7.632 | 7.632 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 0.639437 on 4 procs for 100 steps with 32000 atoms +Loop time of 0.63515 on 4 procs for 100 steps with 32000 atoms -Performance: 13.512 ns/day, 1.776 hours/ns, 156.388 timesteps/s -99.7% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 13.603 ns/day, 1.764 hours/ns, 157.443 timesteps/s +99.8% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.55655 | 0.55752 | 0.55833 | 0.1 | 87.19 -Neigh | 0.040557 | 0.040752 | 0.041148 | 0.1 | 6.37 -Comm | 0.024693 | 0.025886 | 0.026853 | 0.5 | 4.05 -Output | 4.6015e-05 | 5.1558e-05 | 6.0081e-05 | 0.0 | 0.01 -Modify | 0.0088108 | 0.0089263 | 0.0090554 | 0.1 | 1.40 -Other | | 0.006306 | | | 0.99 +Pair | 0.55365 | 0.5566 | 0.55868 | 0.2 | 87.63 +Neigh | 0.041495 | 0.0418 | 0.04211 | 0.1 | 6.58 +Comm | 0.019086 | 0.021075 | 0.023898 | 1.2 | 3.32 +Output | 4.4e-05 | 5.025e-05 | 6e-05 | 0.0 | 0.01 +Modify | 0.009315 | 0.0093595 | 0.009422 | 0.0 | 1.47 +Other | | 0.006263 | | | 0.99 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 b/examples/kim/log.06Feb2019.in.kim.lj.newton-off.1 similarity index 75% rename from examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 rename to examples/kim/log.06Feb2019.in.kim.lj.newton-off.1 index c25368b917..0ab258fe0d 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.newton-off.1 +++ b/examples/kim/log.06Feb2019.in.kim.lj.newton-off.1 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.00450015 secs + Time spent = 0.003446 secs WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) Neighbor list info ... @@ -28,20 +28,20 @@ Per MPI rank memory allocation (min/avg/max) = 28.51 | 28.51 | 28.51 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 3.35585 on 1 procs for 100 steps with 32000 atoms +Loop time of 3.01669 on 1 procs for 100 steps with 32000 atoms -Performance: 2.575 ns/day, 9.322 hours/ns, 29.799 timesteps/s -99.2% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 2.864 ns/day, 8.380 hours/ns, 33.149 timesteps/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.9239 | 2.9239 | 2.9239 | 0.0 | 87.13 -Neigh | 0.38492 | 0.38492 | 0.38492 | 0.0 | 11.47 -Comm | 0.0072038 | 0.0072038 | 0.0072038 | 0.0 | 0.21 -Output | 0.00010204 | 0.00010204 | 0.00010204 | 0.0 | 0.00 -Modify | 0.028316 | 0.028316 | 0.028316 | 0.0 | 0.84 -Other | | 0.01146 | | | 0.34 +Pair | 2.6562 | 2.6562 | 2.6562 | 0.0 | 88.05 +Neigh | 0.31903 | 0.31903 | 0.31903 | 0.0 | 10.58 +Comm | 0.00634 | 0.00634 | 0.00634 | 0.0 | 0.21 +Output | 9.1e-05 | 9.1e-05 | 9.1e-05 | 0.0 | 0.00 +Modify | 0.024723 | 0.024723 | 0.024723 | 0.0 | 0.82 +Other | | 0.01032 | | | 0.34 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 b/examples/kim/log.06Feb2019.in.kim.lj.newton-off.4 similarity index 80% rename from examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 rename to examples/kim/log.06Feb2019.in.kim.lj.newton-off.4 index c8c52d6e09..c17ea6afb7 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.newton-off.4 +++ b/examples/kim/log.06Feb2019.in.kim.lj.newton-off.4 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.00106215 secs + Time spent = 0.000921 secs WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) @@ -34,20 +34,20 @@ Per MPI rank memory allocation (min/avg/max) = 10.05 | 10.05 | 10.05 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 0.930494 on 4 procs for 100 steps with 32000 atoms +Loop time of 0.890192 on 4 procs for 100 steps with 32000 atoms -Performance: 9.285 ns/day, 2.585 hours/ns, 107.470 timesteps/s -99.5% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 9.706 ns/day, 2.473 hours/ns, 112.335 timesteps/s +99.7% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.80926 | 0.81195 | 0.81464 | 0.3 | 87.26 -Neigh | 0.089949 | 0.092688 | 0.095287 | 0.8 | 9.96 -Comm | 0.007302 | 0.0074284 | 0.0075471 | 0.1 | 0.80 -Output | 0.00012898 | 0.00014371 | 0.00016093 | 0.0 | 0.02 -Modify | 0.011517 | 0.011761 | 0.011959 | 0.2 | 1.26 -Other | | 0.006522 | | | 0.70 +Pair | 0.77867 | 0.77906 | 0.7794 | 0.0 | 87.52 +Neigh | 0.087831 | 0.088176 | 0.088805 | 0.1 | 9.91 +Comm | 0.006358 | 0.0065898 | 0.006815 | 0.3 | 0.74 +Output | 4.9e-05 | 5.975e-05 | 6.8e-05 | 0.0 | 0.01 +Modify | 0.010265 | 0.010429 | 0.010678 | 0.2 | 1.17 +Other | | 0.005874 | | | 0.66 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 b/examples/kim/log.06Feb2019.in.kim.lj.newton-on.1 similarity index 75% rename from examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 rename to examples/kim/log.06Feb2019.in.kim.lj.newton-on.1 index eec26307ac..59d018e12a 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.newton-on.1 +++ b/examples/kim/log.06Feb2019.in.kim.lj.newton-on.1 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 1 by 1 MPI processor grid Created 32000 atoms - Time spent = 0.0030508 secs + Time spent = 0.003089 secs WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) Neighbor list info ... @@ -28,20 +28,20 @@ Per MPI rank memory allocation (min/avg/max) = 28.12 | 28.12 | 28.12 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 2.97001 on 1 procs for 100 steps with 32000 atoms +Loop time of 3.05849 on 1 procs for 100 steps with 32000 atoms -Performance: 2.909 ns/day, 8.250 hours/ns, 33.670 timesteps/s -99.8% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 2.825 ns/day, 8.496 hours/ns, 32.696 timesteps/s +99.6% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.5982 | 2.5982 | 2.5982 | 0.0 | 87.48 -Neigh | 0.32516 | 0.32516 | 0.32516 | 0.0 | 10.95 -Comm | 0.012059 | 0.012059 | 0.012059 | 0.0 | 0.41 -Output | 0.000103 | 0.000103 | 0.000103 | 0.0 | 0.00 -Modify | 0.023878 | 0.023878 | 0.023878 | 0.0 | 0.80 -Other | | 0.01058 | | | 0.36 +Pair | 2.6786 | 2.6786 | 2.6786 | 0.0 | 87.58 +Neigh | 0.33105 | 0.33105 | 0.33105 | 0.0 | 10.82 +Comm | 0.012602 | 0.012602 | 0.012602 | 0.0 | 0.41 +Output | 9.5e-05 | 9.5e-05 | 9.5e-05 | 0.0 | 0.00 +Modify | 0.024858 | 0.024858 | 0.024858 | 0.0 | 0.81 +Other | | 0.01132 | | | 0.37 Nlocal: 32000 ave 32000 max 32000 min Histogram: 1 0 0 0 0 0 0 0 0 0 diff --git a/examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 b/examples/kim/log.06Feb2019.in.kim.lj.newton-on.4 similarity index 80% rename from examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 rename to examples/kim/log.06Feb2019.in.kim.lj.newton-on.4 index 6c0da32ba4..da8c9f0faa 100644 --- a/examples/kim/log.12Dec2018.in.kim.lj.newton-on.4 +++ b/examples/kim/log.06Feb2019.in.kim.lj.newton-on.4 @@ -1,11 +1,11 @@ -LAMMPS (24 Oct 2018) +LAMMPS (1 Feb 2019) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) using 1 OpenMP thread(s) per MPI task Lattice spacing in x,y,z = 4.43 4.43 4.43 Created orthogonal box = (0 0 0) to (88.6 88.6 88.6) 1 by 2 by 2 MPI processor grid Created 32000 atoms - Time spent = 0.000946999 secs + Time spent = 0.000893 secs WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) WARNING: KIM Model does not provide `partialParticleVirial'; virial per atom will be zero (src/KIM/pair_kim.cpp:1102) WARNING: KIM Model does not provide `partialParticleEnergy'; energy per atom will be zero (src/KIM/pair_kim.cpp:1097) @@ -34,20 +34,20 @@ Per MPI rank memory allocation (min/avg/max) = 9.789 | 9.789 | 9.789 Mbytes Step Temp E_pair E_mol TotEng Press 0 200 6290.8194 0 7118.0584 129712.25 100 95.179725 6718.814 0 7112.496 133346.59 -Loop time of 0.891065 on 4 procs for 100 steps with 32000 atoms +Loop time of 0.903182 on 4 procs for 100 steps with 32000 atoms -Performance: 9.696 ns/day, 2.475 hours/ns, 112.225 timesteps/s -99.8% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 9.566 ns/day, 2.509 hours/ns, 110.720 timesteps/s +99.6% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.75777 | 0.75864 | 0.75996 | 0.1 | 85.14 -Neigh | 0.088332 | 0.088883 | 0.089737 | 0.2 | 9.97 -Comm | 0.027187 | 0.02829 | 0.029602 | 0.6 | 3.17 -Output | 4.9114e-05 | 5.4777e-05 | 6.6042e-05 | 0.0 | 0.01 -Modify | 0.0088358 | 0.0089488 | 0.0091376 | 0.1 | 1.00 -Other | | 0.00625 | | | 0.70 +Pair | 0.76173 | 0.76349 | 0.76597 | 0.2 | 84.53 +Neigh | 0.088773 | 0.088938 | 0.089074 | 0.0 | 9.85 +Comm | 0.032018 | 0.03452 | 0.03638 | 0.9 | 3.82 +Output | 4e-05 | 4.425e-05 | 5.2e-05 | 0.0 | 0.00 +Modify | 0.009278 | 0.0093917 | 0.009528 | 0.1 | 1.04 +Other | | 0.006797 | | | 0.75 Nlocal: 8000 ave 8018 max 7967 min Histogram: 1 0 0 0 0 0 1 0 0 2 -- GitLab From 622eb4790220dfca53e40edf537ee4782cd94db6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 7 Feb 2019 01:16:48 -0500 Subject: [PATCH 0113/1243] some small tweaks, fixes for typos, and url corrections for the manual --- doc/.gitignore | 1 + doc/src/Install_windows.txt | 2 +- doc/src/Manual.txt | 10 ++-------- doc/utils/sphinx-config/conf.py | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/doc/.gitignore b/doc/.gitignore index 96112ac19c..920c5b9830 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,5 +1,6 @@ /latex /html +/latex /spelling /LAMMPS.epub /LAMMPS.mobi diff --git a/doc/src/Install_windows.txt b/doc/src/Install_windows.txt index 78de4f09f7..7d5aab34f5 100644 --- a/doc/src/Install_windows.txt +++ b/doc/src/Install_windows.txt @@ -12,7 +12,7 @@ Download an executable for Windows :h3 Pre-compiled Windows installers which install LAMMPS executables on a Windows system can be downloaded from this site: -"http://rpm.lammps.org/windows.html"_http://rpm.lammps.org/windows.html +"http://packages.lammps.org/windows.html"_http://packages.lammps.org/windows.html Note that each installer package has a date in its name, which corresponds to the LAMMPS version of the same date. Installers for diff --git a/doc/src/Manual.txt b/doc/src/Manual.txt index b477ce9cf0..f5c6f914c7 100644 --- a/doc/src/Manual.txt +++ b/doc/src/Manual.txt @@ -37,27 +37,21 @@ LAMMPS is an open-source code, distributed freely under the terms of the GNU Public License (GPL). The "LAMMPS website"_lws has a variety of information about the code. -It includes links to an on-line version of this manual, a "mail +It includes links to an on-line version of this manual, a "mailing list"_http://lammps.sandia.gov/mail.html where users can post -questions, and a "GitHub site"https://github.com/lammps/lammps where +questions, and a "GitHub site"_https://github.com/lammps/lammps where all LAMMPS development is coordinated. :line -"PDF file"_Manual.pdf of the entire manual, generated by -"htmldoc"_http://freecode.com/projects/htmldoc - The content for this manual is part of the LAMMPS distribution. You can build a local copy of the Manual as HTML pages or a PDF file, by following the steps on the "Manual build"_Manual_build.html doc page. - There is also a "Developer.pdf"_Developer.pdf document which gives a brief description of the basic code structure of LAMMPS. :line -This manual is organized into the following sections. - Once you are familiar with LAMMPS, you may want to bookmark "this page"_Commands.html since it gives quick access to a doc page for every LAMMPS command. diff --git a/doc/utils/sphinx-config/conf.py b/doc/utils/sphinx-config/conf.py index 736aac3eb9..29de3af156 100644 --- a/doc/utils/sphinx-config/conf.py +++ b/doc/utils/sphinx-config/conf.py @@ -221,7 +221,7 @@ latex_elements = { # author, documentclass [howto, manual, or own class]). latex_documents = [ ('Manual', 'LAMMPS.tex', 'LAMMPS Documentation', - 'Steve Plimpton', 'manual'), + 'The LAMMPS Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of -- GitLab From 0fade44b43f89d39448700f6150acc5c60a43ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 9 Feb 2019 08:45:03 +0100 Subject: [PATCH 0114/1243] Update install.py --- python/install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/install.py b/python/install.py index 2cd6562557..5a97b6106d 100644 --- a/python/install.py +++ b/python/install.py @@ -22,7 +22,7 @@ else: pydir = "" # copy lammps.py to pydir if it exists # if pydir not specified, install in site-packages via distutils setup() -if sys.platform == 'darwin': +if 'liblammps.dylib' in os.listdir('../src/'): lib_ext = ".dylib" else: lib_ext = ".so" -- GitLab From 277f8356b1f34e3e449871c376706b2db1a724f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Sat, 9 Feb 2019 08:46:22 +0100 Subject: [PATCH 0115/1243] Update lammps.py --- python/lammps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/lammps.py b/python/lammps.py index 3d5fc7a6b2..c5c7dca33d 100644 --- a/python/lammps.py +++ b/python/lammps.py @@ -85,7 +85,7 @@ class lammps(object): # fall back to loading with a relative path, # typically requires LD_LIBRARY_PATH to be set appropriately - if sys.platform == 'darwin': + if 'liblammps.dylib' in os.listdir(modpath): lib_ext = ".dylib" else: lib_ext = ".so" -- GitLab From 4b8621e7ef9927058653d6f9cd48882a042c6563 Mon Sep 17 00:00:00 2001 From: casievers Date: Mon, 11 Feb 2019 19:46:22 -0800 Subject: [PATCH 0116/1243] Added additional tutorials for the dynamical matrix calculator --- .../dynamical_matrix_command/GaAs/GaAs.py | 39 +++++++++++++ .../dynamical_matrix_command/GaN/GaN.py | 39 +++++++++++++ .../dynamical_matrix_command/Quartz/quartz.py | 57 +++++++++++++++++++ .../{ => Silicon}/README.md | 4 +- .../{ => Silicon}/Si.opt.tersoff | 0 .../{ => Silicon}/ff-silicon.lmp | 0 .../{ => Silicon}/in.silicon | 0 .../lmp_bank/amorphous_silicon.lmp | 0 .../{ => Silicon}/lmp_bank/silicon_216.lmp | 0 .../{ => Silicon}/lmp_bank/silicon_512.lmp | 0 .../{ => Silicon}/lmp_bank/silicon_8.lmp | 0 .../{ => Silicon}/results/dynmat.dat | 0 .../{ => Silicon}/results/out.silicon | 0 .../{ => Silicon}/silicon_input_file.lmp | 0 .../{ => silicon}/Manual.md | 0 .../{ => silicon}/README.md | 4 +- .../{ => silicon}/Si.opt.tersoff | 0 .../{ => silicon}/combine.sh | 0 .../{ => silicon}/ff-silicon.lmp | 0 .../{ => silicon}/in.silicon | 0 .../{ => silicon}/lmp_bank/silicon_216.lmp | 0 .../{ => silicon}/lmp_bank/silicon_512.lmp | 0 .../{ => silicon}/lmp_bank/silicon_8.lmp | 0 .../{ => silicon}/results/out.silicon | 0 .../{ => silicon}/results/third_order | 0 .../{ => silicon}/silicon_input_file.lmp | 0 src/USER-PHONON/third_order.cpp | 13 ++--- 27 files changed, 144 insertions(+), 12 deletions(-) create mode 100644 examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py create mode 100644 examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py create mode 100644 examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/README.md (77%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/Si.opt.tersoff (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/ff-silicon.lmp (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/in.silicon (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/lmp_bank/amorphous_silicon.lmp (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/lmp_bank/silicon_216.lmp (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/lmp_bank/silicon_512.lmp (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/lmp_bank/silicon_8.lmp (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/results/dynmat.dat (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/results/out.silicon (100%) rename examples/USER/phonon/dynamical_matrix_command/{ => Silicon}/silicon_input_file.lmp (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/Manual.md (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/README.md (82%) rename examples/USER/phonon/third_order_command/{ => silicon}/Si.opt.tersoff (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/combine.sh (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/ff-silicon.lmp (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/in.silicon (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/lmp_bank/silicon_216.lmp (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/lmp_bank/silicon_512.lmp (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/lmp_bank/silicon_8.lmp (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/results/out.silicon (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/results/third_order (100%) rename examples/USER/phonon/third_order_command/{ => silicon}/silicon_input_file.lmp (100%) diff --git a/examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py b/examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py new file mode 100644 index 0000000000..1e9d58a71b --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py @@ -0,0 +1,39 @@ +from ase import Atoms, Atom +from ase.calculators.lammpslib import LAMMPSlib +import numpy as np +import matplotlib.pyplot as plt +from mpi4py import MPI + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() + +GaAs = Atoms([Atom('Ga', (0.0, 0.0, 0.0)), + Atom('As', (1.413425, 1.413425, 1.413425))], + cell=[(0.0, 2.82685, 2.82685), (2.82685, 0.0, 2.82685), (2.82685, 2.82685, 0.0)], + pbc=True,) + +cmds = ["pair_style bop", "pair_coeff * * ../../../../../potentials/GaAs.bop.table Ga As", + "comm_modify cutoff 12"] + +mends = ["info system", + "dynamical_matrix all eskm 0.000001 file dynmat.dat binary no", + "neigh_modify delay 0"] + +N = 5 +GaAs = GaAs.repeat([N, N, N]) + +lammps = LAMMPSlib(lmpcmds=cmds, atom_types={'Ga': 1, 'As': 2}, amendments=mends, log_file='lammps.log') + +GaAs.set_calculator(lammps) +GaAs.get_potential_energy() + +if rank == 0: + dynmat = np.loadtxt("dynmat.dat") + dynmat = dynmat.reshape(([int(3*(len(dynmat)/3)**0.5), int(3*(len(dynmat)/3)**0.5)])) + eigv = np.linalg.eigvals(dynmat) + eigv.sort() + eigv = np.sqrt(np.abs(eigv))/(2*np.pi) + plt.hist(eigv, 80) + plt.xlabel('Frequency (THz)') + plt.show() + diff --git a/examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py b/examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py new file mode 100644 index 0000000000..52e14ca47d --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py @@ -0,0 +1,39 @@ +from ase import Atoms, Atom +from ase.calculators.lammpslib import LAMMPSlib +import numpy as np +import matplotlib.pyplot as plt +from mpi4py import MPI + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() + +GaN = Atoms([Atom('Ga', (1.59, 0.917986928012, 0.0)), + Atom('Ga', (1.59, -0.917986928012, 2.583)), + Atom('N', (1.59, 0.917986928012, 1.98891)), + Atom('N', (1.59, -0.917986928012, 4.57191))], + cell=[(1.59, -2.75396078403, 0.0), (1.59, 2.75396078403, 0.0), (0.0, 0.0, 5.166)], + pbc=True) + +cmds = ["pair_style tersoff", "pair_coeff * * ../../../../../potentials/GaN.tersoff Ga N"] + +mends = ["info system", + "dynamical_matrix all eskm 0.000001 file dynmat.dat binary no", + "neigh_modify delay 0"] + +N = 6 +GaN = GaN.repeat([N, N, N]) + +lammps = LAMMPSlib(lmpcmds=cmds, atom_types={'Ga': 1, 'N': 2}, amendments=mends, log_file='lammps.log') + +GaN.set_calculator(lammps) +GaN.get_potential_energy() + +if rank == 0: + dynmat = np.loadtxt("dynmat.dat") + dynmat = dynmat.reshape(([int(3*(len(dynmat)/3)**0.5), int(3*(len(dynmat)/3)**0.5)])) + eigv = np.linalg.eigvals(dynmat) + eigv.sort() + eigv = np.sqrt(np.abs(eigv))/(2*np.pi) + plt.hist(eigv, 80) + plt.xlabel('Frequency (THz)') + plt.show() diff --git a/examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py b/examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py new file mode 100644 index 0000000000..79a81aa95c --- /dev/null +++ b/examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py @@ -0,0 +1,57 @@ +from ase import Atoms, Atom +from ase.calculators.lammpslib import LAMMPSlib +import numpy as np +import matplotlib.pyplot as plt +from mpi4py import MPI + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() + +quartz = Atoms( + [Atom('Si', (1.1545226, -1.99969180169, 0.0)), + Atom('Si', (1.1545226, 1.99969180169, 3.6036)), + Atom('Si', (2.6069548, 2.15247249027e-16, 1.8018)), + Atom('O', (1.6724232, -0.624132037742, 0.64378314)), + Atom('O', (1.6724232, 0.624132037742, 2.9598186618)), + Atom('O', (2.1623026, -2.49695388906, 4.2473849418)), + Atom('O', (3.5392742, 1.13629495821, 1.1580150582)), + Atom('O', (3.5392742, -1.13629495821, 2.4455813382)), + Atom('O', (2.1623026, 2.49695388906, 4.76161686))], + cell=[(2.458, -4.257380885, 0.0), (2.458, 4.257380885, 0.0), (0.0, 0.0, 5.4054)], + pbc=True, + ) + +# number of repeats +N = 3 +quartz = quartz.repeat([N, N, N]) + +header = ['units metal', + 'atom_style charge', + 'atom_modify map array sort 0 0'] + +cmds = ["pair_style buck/coul/long 10.0 8.0", + "pair_coeff 1 1 0 1 0", + "pair_coeff 1 2 18003.7572 0.20520 133.5381", + "pair_coeff 2 2 1388.7730 0.36232 175.0000", + "kspace_style ewald 1.0e-12", + "set type 1 charge 2.4", + "set type 2 charge -1.2"] + +mends = ["dynamical_matrix all eskm 0.000001 file dynmat.dat binary no", + "neigh_modify delay 0"] + + +lammps = LAMMPSlib(lmpcmds=cmds, lammps_header=header, amendments=mends, log_file='lammps.log') + +quartz.set_calculator(lammps) +quartz.get_potential_energy() + +if rank == 0: + dynmat = np.loadtxt("dynmat.dat") + dynmat = dynmat.reshape(([int(3*(len(dynmat)/3)**0.5), int(3*(len(dynmat)/3)**0.5)])) + eigv = np.linalg.eigvals(dynmat) + eigv.sort() + plt.hist(33*np.sqrt(np.abs(eigv))/(2*np.pi), 80) + plt.xlabel('Frequency (cm-1)') + plt.show() + diff --git a/examples/USER/phonon/dynamical_matrix_command/README.md b/examples/USER/phonon/dynamical_matrix_command/Silicon/README.md similarity index 77% rename from examples/USER/phonon/dynamical_matrix_command/README.md rename to examples/USER/phonon/dynamical_matrix_command/Silicon/README.md index 8981c1e63a..15ae158c62 100755 --- a/examples/USER/phonon/dynamical_matrix_command/README.md +++ b/examples/USER/phonon/dynamical_matrix_command/Silicon/README.md @@ -7,7 +7,7 @@ This directory contains the ingredients to calculate a dynamical matrix. Example: ``` NP=4 #number of processors -mpirun -np $NP lmp_mpi < in.silicon > out.silicon +mpirun -np $NP lmp_mpi -in in.silicon -out out.silicon ``` To test out a different silicon example: @@ -15,7 +15,7 @@ To test out a different silicon example: LMP_FILE=amorphous_silicon.lmp cp lmp_bank/$LMP_FILE ./silicon_input_file.lmp NP=4 #number of processors -mpirun -np $NP lmp_mpi < in.silicon > out.silicon +mpirun -np $NP lmp_mpi -in in.silicon -out out.silicon ``` ## Requires: MANYBODY and MOLECULE packages diff --git a/examples/USER/phonon/dynamical_matrix_command/Si.opt.tersoff b/examples/USER/phonon/dynamical_matrix_command/Silicon/Si.opt.tersoff similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/Si.opt.tersoff rename to examples/USER/phonon/dynamical_matrix_command/Silicon/Si.opt.tersoff diff --git a/examples/USER/phonon/dynamical_matrix_command/ff-silicon.lmp b/examples/USER/phonon/dynamical_matrix_command/Silicon/ff-silicon.lmp similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/ff-silicon.lmp rename to examples/USER/phonon/dynamical_matrix_command/Silicon/ff-silicon.lmp diff --git a/examples/USER/phonon/dynamical_matrix_command/in.silicon b/examples/USER/phonon/dynamical_matrix_command/Silicon/in.silicon similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/in.silicon rename to examples/USER/phonon/dynamical_matrix_command/Silicon/in.silicon diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/amorphous_silicon.lmp b/examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/amorphous_silicon.lmp similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/lmp_bank/amorphous_silicon.lmp rename to examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/amorphous_silicon.lmp diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_216.lmp b/examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/silicon_216.lmp similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_216.lmp rename to examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/silicon_216.lmp diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_512.lmp b/examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/silicon_512.lmp similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_512.lmp rename to examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/silicon_512.lmp diff --git a/examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_8.lmp b/examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/silicon_8.lmp similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/lmp_bank/silicon_8.lmp rename to examples/USER/phonon/dynamical_matrix_command/Silicon/lmp_bank/silicon_8.lmp diff --git a/examples/USER/phonon/dynamical_matrix_command/results/dynmat.dat b/examples/USER/phonon/dynamical_matrix_command/Silicon/results/dynmat.dat similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/results/dynmat.dat rename to examples/USER/phonon/dynamical_matrix_command/Silicon/results/dynmat.dat diff --git a/examples/USER/phonon/dynamical_matrix_command/results/out.silicon b/examples/USER/phonon/dynamical_matrix_command/Silicon/results/out.silicon similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/results/out.silicon rename to examples/USER/phonon/dynamical_matrix_command/Silicon/results/out.silicon diff --git a/examples/USER/phonon/dynamical_matrix_command/silicon_input_file.lmp b/examples/USER/phonon/dynamical_matrix_command/Silicon/silicon_input_file.lmp similarity index 100% rename from examples/USER/phonon/dynamical_matrix_command/silicon_input_file.lmp rename to examples/USER/phonon/dynamical_matrix_command/Silicon/silicon_input_file.lmp diff --git a/examples/USER/phonon/third_order_command/Manual.md b/examples/USER/phonon/third_order_command/silicon/Manual.md similarity index 100% rename from examples/USER/phonon/third_order_command/Manual.md rename to examples/USER/phonon/third_order_command/silicon/Manual.md diff --git a/examples/USER/phonon/third_order_command/README.md b/examples/USER/phonon/third_order_command/silicon/README.md similarity index 82% rename from examples/USER/phonon/third_order_command/README.md rename to examples/USER/phonon/third_order_command/silicon/README.md index a9604e4575..c938734393 100755 --- a/examples/USER/phonon/third_order_command/README.md +++ b/examples/USER/phonon/third_order_command/silicon/README.md @@ -8,7 +8,7 @@ Example: ``` $THIRD_ORDER=third_order #tensor output file NP=4 #number of processors -mpirun -np $NP lmp_mpi < in.silicon > out.silicon +mpirun -np $NP lmp_mpi -in in.silicon -out out.silicon combine.sh third_order ``` @@ -18,7 +18,7 @@ $THIRD_ORDER=third_order $LMP_FILE=amorphous_silicon.lmp cp lmp_bank/$LMP_FILE ./silicon_input_file.lmp NP=4 #number of processors -mpirun -np $NP lmp_mpi < in.silicon > out.silicon +mpirun -np $NP lmp_mpi -in in.silicon -out out.silicon bash combine.sh $THIRD_ORDER ``` diff --git a/examples/USER/phonon/third_order_command/Si.opt.tersoff b/examples/USER/phonon/third_order_command/silicon/Si.opt.tersoff similarity index 100% rename from examples/USER/phonon/third_order_command/Si.opt.tersoff rename to examples/USER/phonon/third_order_command/silicon/Si.opt.tersoff diff --git a/examples/USER/phonon/third_order_command/combine.sh b/examples/USER/phonon/third_order_command/silicon/combine.sh similarity index 100% rename from examples/USER/phonon/third_order_command/combine.sh rename to examples/USER/phonon/third_order_command/silicon/combine.sh diff --git a/examples/USER/phonon/third_order_command/ff-silicon.lmp b/examples/USER/phonon/third_order_command/silicon/ff-silicon.lmp similarity index 100% rename from examples/USER/phonon/third_order_command/ff-silicon.lmp rename to examples/USER/phonon/third_order_command/silicon/ff-silicon.lmp diff --git a/examples/USER/phonon/third_order_command/in.silicon b/examples/USER/phonon/third_order_command/silicon/in.silicon similarity index 100% rename from examples/USER/phonon/third_order_command/in.silicon rename to examples/USER/phonon/third_order_command/silicon/in.silicon diff --git a/examples/USER/phonon/third_order_command/lmp_bank/silicon_216.lmp b/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_216.lmp similarity index 100% rename from examples/USER/phonon/third_order_command/lmp_bank/silicon_216.lmp rename to examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_216.lmp diff --git a/examples/USER/phonon/third_order_command/lmp_bank/silicon_512.lmp b/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_512.lmp similarity index 100% rename from examples/USER/phonon/third_order_command/lmp_bank/silicon_512.lmp rename to examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_512.lmp diff --git a/examples/USER/phonon/third_order_command/lmp_bank/silicon_8.lmp b/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_8.lmp similarity index 100% rename from examples/USER/phonon/third_order_command/lmp_bank/silicon_8.lmp rename to examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_8.lmp diff --git a/examples/USER/phonon/third_order_command/results/out.silicon b/examples/USER/phonon/third_order_command/silicon/results/out.silicon similarity index 100% rename from examples/USER/phonon/third_order_command/results/out.silicon rename to examples/USER/phonon/third_order_command/silicon/results/out.silicon diff --git a/examples/USER/phonon/third_order_command/results/third_order b/examples/USER/phonon/third_order_command/silicon/results/third_order similarity index 100% rename from examples/USER/phonon/third_order_command/results/third_order rename to examples/USER/phonon/third_order_command/silicon/results/third_order diff --git a/examples/USER/phonon/third_order_command/silicon_input_file.lmp b/examples/USER/phonon/third_order_command/silicon/silicon_input_file.lmp similarity index 100% rename from examples/USER/phonon/third_order_command/silicon_input_file.lmp rename to examples/USER/phonon/third_order_command/silicon/silicon_input_file.lmp diff --git a/src/USER-PHONON/third_order.cpp b/src/USER-PHONON/third_order.cpp index b2a684e6da..41382e64cb 100644 --- a/src/USER-PHONON/third_order.cpp +++ b/src/USER-PHONON/third_order.cpp @@ -168,13 +168,11 @@ void ThirdOrder::options(int narg, char **arg) if (narg < 0) error->all(FLERR,"Illegal dynamical_matrix command"); int iarg = 0; const char *filename = "third_order.txt"; - std::stringstream fss; while (iarg < narg) { if (strcmp(arg[iarg],"file") == 0) { if (iarg+2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); - fss << arg[iarg + 1] << me; - filename = fss.str().c_str(); + filename = arg[iarg + 1]; file_flag = 1; iarg += 2; } @@ -189,7 +187,7 @@ void ThirdOrder::options(int narg, char **arg) iarg += 2; } else error->all(FLERR,"Illegal dynamical_matrix command"); } - if (file_flag == 1 and me == 0) { + if (file_flag == 1 && me == 0) { openfile(filename); } } @@ -338,10 +336,9 @@ void ThirdOrder::writeMatrix(double *dynmat, int i, int a, int j, int b) if (!binaryflag && fp) { clearerr(fp); for (int k = 0; k < gcount; k++){ - double norm = pow(dynmat[k*3], 2) - + pow(dynmat[k*3+1], 2) - + pow(dynmat[k+3+2], 2); - if (norm > 1.0e-16) + if (dynmat[k*3] > 1.0e-16 + && dynmat[k*3+1] > 1.0e-16 + && dynmat[k*3+2] > 1.0e-16) fprintf(fp, "%d %d %d %d %d %7.8f %7.8f %7.8f\n", i+1, a + 1, j+1, b + 1, groupmap[k]+1, -- GitLab From b7413226e0a42db8fa5030a3aecb944760a05bcf Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Mon, 11 Feb 2019 21:37:06 -0700 Subject: [PATCH 0117/1243] Several changes to new consolidated granular code: - Normal contact models take Young's modulus and Poisson's ratio (instead of Young's and shear modulus) - Mixing of Young's moduli corrected - Changes to cutoffs corrected for JKR pulloff distance - Renamed 'mindlin' to 'linear_history' - Progress on doc page --- doc/src/pair_granular.txt | 435 +++--- doc/src/pairs.txt | 1 + src/GRANULAR/pair_granular.cpp | 1168 ++++------------ src/GRANULAR/pair_granular.h | 53 +- src/pair_granular.cpp | 2337 ++++++++++++++++++++++++++++++++ src/pair_granular.h | 120 ++ 6 files changed, 2874 insertions(+), 1240 deletions(-) create mode 100644 src/pair_granular.cpp create mode 100644 src/pair_granular.h diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 35b64bf29d..8bf4f20d5d 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -1,3 +1,10 @@ + + + "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c :link(lws,http://lammps.sandia.gov) @@ -14,323 +21,185 @@ pair_style granular/multi command :h3 pair_style style cutoff :pre style = {granular} or {granular/multi} :ulb,l -cutoff = global cutoff (optional). See discussion below. +cutoff = global cutoff (optional). See discussion below. :l +:ule [Examples:] pair_style granular -pair coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair coeff 2 2 hertz 200.0 20.0 tangential mindlin 300.0 50.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall +pair_coeff * * hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.4 :pre + +pair_style granular +pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 2 2 hertz 200.0 20.0 tangential mindlin 300.0 50.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre pair_style granular/multi -pair coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair coeff 2 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall -pair coeff 1 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall +pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 2 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall +pair_coeff 1 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre [Description:] The {granular} styles support a variety of options for the normal, tangential, rolling and twisting -forces resulting from contact between two granular particles. The computed force depends on the combination -of choices for these models. +forces resulting from contact between two granular particles. This expands on the options offered +by the "pair gran/*"_pair_gran.html options. The total computed forces and torques depend on the combination +of choices for these various modes of motion. All model options and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. Unlike e.g. "pair gran/hooke"_pair_gran.html, coefficient values are not global, but can be set to different values for various combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. -In the case of {granular}, coefficients -can vary between particle types, but model choices cannot. For instance, in the first -example above, the stiffness, damping, and tangential friction are different for type 1 - type 1 and type 2 - type 2 interactions, but -both 1-1 and 2-2 interactions must have the same model form, hence all keywords are identical between the two types. Cross-coefficients -for 1-2 interactions for the case of the {hertz} model above are set via simple geometric mixing rules. The {granular/multi} +For {pair_style granular}, coefficients can vary between particle types, but model choices +cannot. For instance, in the first +example above, the stiffness, damping, and tangential friction are different for +type 1 - type 1 and type 2 - type 2 interactions, but +both 1-1 and 2-2 interactions must have the same model form, hence all keywords are +identical between the two types. Cross-coefficients +for 1-2 interactions for the case of the {hertz} model above are set via simple +geometric mixing rules. The {granular/multi} style removes this restriction at a small cost in computational efficiency, so that different particle types can potentially interact via different model forms. As shown in the second example, 1-1 interactions are based on a Hertzian contact model and 2-2 interactions are based on a {dmt} model (see below). In the case that 1-1 and 2-2 interactions have different model forms, mixing of coefficients cannot be determined, so 1-2 interactions must be explicitly defined via the pair coeff command, otherwise an error results. -The first required keyword for the pair coeff command is the normal contact model. Currently supported options and -the required arguments are: +:line + +The first required keyword for the {pair_coeff} command is the normal contact model. Currently supported options +for normal contact models and their required arguments are: -{hooke} : k_n, damping -{hertz} : k_n, damping +{hooke} : \(k_n\), damping +{hertz} : \(k_n\), damping {hertz/material} : E, damping, G {dmt} : E, damping, G, cohesion -{jkr} : E, damping, G, cohesion +{jkr} : E, damping, G, cohesion :ol -Here, k_n is spring stiffness, damping is a damping constant or a coefficient of restitution, depending on +Here, \(k_n\) is spring stiffness, damping is a damping constant or a coefficient of restitution, depending on the choice of damping model (see below), E and G are Young's modulus and shear modulus, in units of pressure, and cohesion is a surface energy density, in units of energy/length^2. -For the {hooke} model, the normal component of force is given by: -:c,image(Eqs/hooke_normal.jpg) - -For {hertz}, the normal force is given by: -:c,image{Eqs/hertz_normal.jpg} +For the {hooke} model, the normal (elastic) component of force between two particles {i} and {j} is given by: +\begin\{equation\} +\mathbf\{F\}_\{ne, Hooke\} = k_N \delta_\{ij\} \mathbf\{n\} +\end\{equation\} + +Where \(\delta = R_i + R_j - \|\mathbf\{r\}_\{ij\}\|\) is the particle overlap, +\(R_i, R_j\) are the particle radii, +\(\mathbf\{r\}_\{ij\} = \mathbf\{r\}_j - \mathbf\{r\}_i\) is the vector separating the +two particle centers +and \(\mathbf\{n\} = \frac\{\mathbf\{r\}_\{ij\}\}\{\|\mathbf\{r\}_\{ij\}\|\}\). + +For the {hertz} model, the normal component of force is given by: +\begin\{equation\} +\mathbf\{F\}_\{ne, Hertz\} = k_N R_\{eff\}^\{1/2\}\delta_\{ij\}^\{3/2\} \mathbf\{n\} +\end\{equation\} + +Here, \(R_\{eff\} = \frac\{R_i R_j\}\{R_i + R_j\}\) is the effective radius, denoted for simplicity as {R} from here on. + +For the {hertz/material} model, the force is given by: +\begin\{equation\} +\mathbf\{F\}_\{ne, Hertz/material\} = \frac\{4\}\{3\} E_\{eff\} R_\{eff\}^\{1/2\}\delta_\{ij\}^\{3/2\} \mathbf\{n\} +\end\{equation\} + +Here, \(E_\{eff\} = E = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\}\) +is the effectve Young's modulus, +with \(\nu_i, \nu_j \) the Poisson ratios of the particles, which are related to the +input shear and Young's moduli by \(\nu_i = E_i/2G_i - 1\). Thus, if the elastic and shear moduli of the +two particles are the same, the {hertz/material} +model is equivalent to the {hertz} model with \(k_N = 4/3 E_\{eff\}\) + +The {dmt} model corresponds to the Derjaguin-Muller-Toporov model, +where the force is simply Hertz with an additional attractive cohesion term: +\begin\{equation\} +\mathbf\{F\}_\{ne, dmt\} = \left(\frac\{4\}\{3\} E R^\{1/2\}\delta_\{ij\}^\{3/2\} - 4\pi\gamma R\right)\mathbf\{n\} +\end\{equation\} + +The {jkr} model is the Johnson-Kendall-Roberts model, where the force is computed as: +\begin\{equation\} +\label\{eq:force_jkr\} +\mathbf\{F\}_\{ne, jkr\} = \left(\frac\{4Ea^3\}\{3R\} - 2\pi a^2\sqrt\{\frac\{4\gamma E\}\{\pi a\}\}\right)\mathbf\{n\} +\end\{equation\} + +Here, {a} is the radius of the contact zone, related to the overlap \(\delta\) according to: +\begin\{equation\} +\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\} +\end\{equation\} + +LAMMPS internally inverts the equation above to solve for {a} in terms of \(\delta\), then solves for +the force in the previous equation. Additionally, note that the JKR model allows for a tensile force beyond +contact (i.e. for \(\delta < 0\)), up to a maximum tensile force of \(-3\pi\gamma R\) (also known as +the 'pull-off' force). +Note that this is a hysteretic effect, where particles that are not contacting initially +will not experience force until they come into contact \(\delta \geq 0\); as they move apart +and (\(\delta < 0\)), they experience a tensile force up to \(-3\pi\gamma R\), +at which point they will lose contact. + +In addition to the above options, the normal force is augmented by a damping term. The optional +{damping} keyword to the {pair_coeff} command followed by the model choice determines the form of the damping. +The damping coefficient that was specified for the normal model +settings is used in computing the damping term, as described below. Note this damping parameter +may be interpreted differently depending on the model choice. +The options for the damping model currently supported are: + +{velocity} +{viscoelastic} +{tsuji} :ol + +If the {damping} keyword is not specified, the {viscoelastic} model is used by default. + +For {damping velocity}, the normal damping is simply proportional to the velocity: +\begin\{equation\} +F_\{N,damp\} = -\gamma_N\mathbf\{v\}_\{N,rel\} +\end\{equation\} + +Here, \(\gamma_N\) is the damping coefficient, in units of {mass}/{time}, +\(\mathbf\{v\}_\{N,rel\} = (\mathbf\{v\}_i - \mathbf\{v\}_j) \cdot \mathbf\{n\}\) +is the component of relative velocity along the direction of the vector \(\mathbf\{n\}\) that connects the centers of +particles {i} and {j}. + +The {damping viscoelastic} model is based on the viscoelastic treatment of "(Brilliantov et al)"_#Brill1996, +where the normal damping is given by: +\begin\{equation\} +F_\{N,damp\} = -\gamma_N a m_\{eff\} \mathbf\{v\}_\{N,rel\} +\end\{equation\} + +Here, \(m_\{eff\} = m_i m_j/(m_i + m_j)\) is the effective mass, {a} is the contact radius, given by \(a =\sqrt\{R\delta\}\) +for all models except {jkr}, for which it is given implicitly according to \(delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\). +In this case, \(\gamma_N\) is the damping coefficient, in units of 1/({time}*{distance}). + +The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the + + :line + +Following the normal contact model settings, the {pair_coeff} command requires specification +of the tangential contact model. The required keyword {tangential} is expected, followed by the model choice and associated +parameters. Currently supported tangential model choices and their expected parameters are as follows: + +{nohistory} : \(\gamma_t\), \(\mu_s\) +{history} : \(k_t\), \(\gamma_t\), \(\mu_s\) :ol -For both [hooke] and [hertz], stiffness for unspecified cross-terms is given by simple geometric mixing -(e.g. if stiffness is specified for type 1 and type 2 particles as k_n_1 and k_n_2, respectively, -type 1 - type 2 contacts use a stiffness given by k_n_{12} = sqrt(k_n_1*k_n_2)) +Here, \(\gamma_t\) is the tangential damping coefficient, \(\mu_s\) is the tangential (or sliding) friction +coefficient, and \(k_t\) is the tangential stiffness. -For {hertz/material}, the form is the same as above, but coefficients are computed differently, and mixing follows -a different rule based on shear modulus: -:c,image{Eqs/hertz_material_normal.jpg} +For {nohistory}, a simple velocity-dependent Coulomb friction criterion is used, which reproduces the behavior +of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: -For {dmt}, the normal force is given by: -:c,image{Eqs/dmt_normal.jpg} +\begin\{equation\} +\mathbf\{F\}_t = -min(\mu_s \|\mathbf\{F\}_n\|, \gamma_t m_\{eff\}\|\mathbf\{v\}_\{t, rel\}\|) \mathbf\{t\} +\end\{equation\} -Where gamma is cohesion. +Where \(\|\mathbf\{F\}_n\) is the magnitude of the normal force, +\(\mathbf\{v\}_\{t, rel\} = \mathbf\{v\}_\{t\} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf\{n\}\) is the relative tangential +velocity at the point of contact, \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_n - \) -For {jkr}, the normal force is given by: -:c,image{Eqs/jkr_normal.jpg} -The same mixing rule for stiffness as for {hertz/material} is used by both the {dmt} and {jkr} models. + :link(Brill1996) +[(Brilliantov et al, 1996)] Brilliantov, N. V., Spahn, F., Hertzsch, J. M., & Poschel, T. (1996). +Model for collisions in granular gases. Physical review E, 53(5), 5382. -The tangential contact model must also be specified, which follows -the required {tangential} keyword. Currently supported options -and their required arguments are: - -{no_history}: k_t, tangential_damping, friction coefficient -{mindlin}: k_t, tangential_damping, friction coefficient + :link(Tsuji1992) + [(Tsuji et al, 1992)] Tsuji, Y., Tanaka, T., & Ishida, T. (1992). Lagrangian numerical simulation of plug flow of + cohesionless particles in a horizontal pipe. Powder technology, 71(3), 239-250. -For {no_history}, the tangential force is computed according to: -:c,image{Eqs/tangential_nohistory.jpg} - -For {mindlin}, tangential force is: -:c,image{Eqs/tangential_mindlin.jpg} - -The total force on a particle is the sum of the normal and tangential forces from all interactions. The tangential -force also induces a torque on both particles in a contacting pair. Additionally, rolling and twisting friction -models can also be applied, which may induce additional torques (but no force). The following options are -supported for the rolling friction model - - -The first required keyword -in the pair coeff command is the choice -of normal force contact model, for which current opitons are {hooke}, {hertz} -The {gran} styles use the following formulas for the frictional force -between two granular particles, as described in -"(Brilliantov)"_#Brilliantov, "(Silbert)"_#Silbert, and -"(Zhang)"_#Zhang3, when the distance r between two particles of radii -Ri and Rj is less than their contact distance d = Ri + Rj. There is -no force between the particles when r > d. - -The two Hookean styles use this formula: - -:c,image(Eqs/pair_gran_hooke.jpg) - -The Hertzian style uses this formula: - -:c,image(Eqs/pair_gran_hertz.jpg) - -In both equations the first parenthesized term is the normal force -between the two particles and the second parenthesized term is the -tangential force. The normal force has 2 terms, a contact force and a -damping force. The tangential force also has 2 terms: a shear force -and a damping force. The shear force is a "history" effect that -accounts for the tangential displacement between the particles for the -duration of the time they are in contact. This term is included in -pair styles {hooke/history} and {hertz/history}, but is not included -in pair style {hooke}. The tangential damping force term is included -in all three pair styles if {dampflag} is set to 1; it is not included -if {dampflag} is set to 0. - -The other quantities in the equations are as follows: - -delta = d - r = overlap distance of 2 particles -Kn = elastic constant for normal contact -Kt = elastic constant for tangential contact -gamma_n = viscoelastic damping constant for normal contact -gamma_t = viscoelastic damping constant for tangential contact -m_eff = Mi Mj / (Mi + Mj) = effective mass of 2 particles of mass Mi and Mj -Delta St = tangential displacement vector between 2 particles \ - which is truncated to satisfy a frictional yield criterion -n_ij = unit vector along the line connecting the centers of the 2 particles -Vn = normal component of the relative velocity of the 2 particles -Vt = tangential component of the relative velocity of the 2 particles :ul - -The Kn, Kt, gamma_n, and gamma_t coefficients are specified as -parameters to the pair_style command. If a NULL is used for Kt, then -a default value is used where Kt = 2/7 Kn. If a NULL is used for -gamma_t, then a default value is used where gamma_t = 1/2 gamma_n. - -The interpretation and units for these 4 coefficients are different in -the Hookean versus Hertzian equations. - -The Hookean model is one where the normal push-back force for two -overlapping particles is a linear function of the overlap distance. -Thus the specified Kn is in units of (force/distance). Note that this -push-back force is independent of absolute particle size (in the -monodisperse case) and of the relative sizes of the two particles (in -the polydisperse case). This model also applies to the other terms in -the force equation so that the specified gamma_n is in units of -(1/time), Kt is in units of (force/distance), and gamma_t is in units -of (1/time). - -The Hertzian model is one where the normal push-back force for two -overlapping particles is proportional to the area of overlap of the -two particles, and is thus a non-linear function of overlap distance. -Thus Kn has units of force per area and is thus specified in units of -(pressure). The effects of absolute particle size (monodispersity) -and relative size (polydispersity) are captured in the radii-dependent -pre-factors. When these pre-factors are carried through to the other -terms in the force equation it means that the specified gamma_n is in -units of (1/(time*distance)), Kt is in units of (pressure), and -gamma_t is in units of (1/(time*distance)). - -Note that in the Hookean case, Kn can be thought of as a linear spring -constant with units of force/distance. In the Hertzian case, Kn is -like a non-linear spring constant with units of force/area or -pressure, and as shown in the "(Zhang)"_#Zhang3 paper, Kn = 4G / -(3(1-nu)) where nu = the Poisson ratio, G = shear modulus = E / -(2(1+nu)), and E = Young's modulus. Similarly, Kt = 4G / (2-nu). -(NOTE: in an earlier version of the manual, we incorrectly stated that -Kt = 8G / (2-nu).) - -Thus in the Hertzian case Kn and Kt can be set to values that -corresponds to properties of the material being modeled. This is also -true in the Hookean case, except that a spring constant must be chosen -that is appropriate for the absolute size of particles in the model. -Since relative particle sizes are not accounted for, the Hookean -styles may not be a suitable model for polydisperse systems. - -NOTE: In versions of LAMMPS before 9Jan09, the equation for Hertzian -interactions did not include the sqrt(RiRj/Ri+Rj) term and thus was -not as accurate for polydisperse systems. For monodisperse systems, -sqrt(RiRj/Ri+Rj) is a constant factor that effectively scales all 4 -coefficients: Kn, Kt, gamma_n, gamma_t. Thus you can set the values -of these 4 coefficients appropriately in the current code to reproduce -the results of a previous Hertzian monodisperse calculation. For -example, for the common case of a monodisperse system with particles -of diameter 1, all 4 of these coefficients should now be set 2x larger -than they were previously. - -Xmu is also specified in the pair_style command and is the upper limit -of the tangential force through the Coulomb criterion Ft = xmu*Fn, -where Ft and Fn are the total tangential and normal force components -in the formulas above. Thus in the Hookean case, the tangential force -between 2 particles grows according to a tangential spring and -dash-pot model until Ft/Fn = xmu and is then held at Ft = Fn*xmu until -the particles lose contact. In the Hertzian case, a similar analogy -holds, though the spring is no longer linear. - -NOTE: Normally, xmu should be specified as a fractional value between -0.0 and 1.0, however LAMMPS allows large values (up to 1.0e4) to allow -for modeling of systems which can sustain very large tangential -forces. - -The effective mass {m_eff} is given by the formula above for two -isolated particles. If either particle is part of a rigid body, its -mass is replaced by the mass of the rigid body in the formula above. -This is determined by searching for a "fix rigid"_fix_rigid.html -command (or its variants). - -For granular styles there are no additional coefficients to set for -each pair of atom types via the "pair_coeff"_pair_coeff.html command. -All settings are global and are made via the pair_style command. -However you must still use the "pair_coeff"_pair_coeff.html for all -pairs of granular atom types. For example the command - -pair_coeff * * :pre - -should be used if all atoms in the simulation interact via a granular -potential (i.e. one of the pair styles above is used). If a granular -potential is used as a sub-style of "pair_style -hybrid"_pair_hybrid.html, then specific atom types can be used in the -pair_coeff command to determine which atoms interact via a granular -potential. - -:line - -Styles with a {gpu}, {intel}, {kk}, {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 on the "Speed packages"_Speed_packages.html doc -page. 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 GPU, USER-INTEL, KOKKOS, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the "Build -package"_Build_package.html doc page 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"_Run_options.html when you invoke LAMMPS, or you can use the -"suffix"_suffix.html command in your input script. - -See the "Speed packages"_Speed_packages.html doc page for more -instructions on how to use the accelerated styles effectively. - -:line - -[Mixing, shift, table, tail correction, restart, rRESPA info]: - -The "pair_modify"_pair_modify.html mix, shift, table, and tail options -are not relevant for granular pair styles. - -These pair styles write their information to "binary restart -files"_restart.html, so a pair_style command does not need to be -specified in an input script that reads a restart file. - -These pair styles can only be used via the {pair} keyword of the -"run_style respa"_run_style.html command. They do not support the -{inner}, {middle}, {outer} keywords. - -The single() function of these pair styles returns 0.0 for the energy -of a pairwise interaction, since energy is not conserved in these -dissipative potentials. It also returns only the normal component of -the pairwise interaction force. However, the single() function also -calculates 10 extra pairwise quantities. The first 3 are the -components of the tangential force between particles I and J, acting -on particle I. The 4th is the magnitude of this tangential force. -The next 3 (5-7) are the components of the relative velocity in the -normal direction (along the line joining the 2 sphere centers). The -last 3 (8-10) the components of the relative velocity in the -tangential direction. - -These extra quantities can be accessed by the "compute -pair/local"_compute_pair_local.html command, as {p1}, {p2}, ..., -{p10}. - -:line - -[Restrictions:] - -All the granular pair styles are part of the GRANULAR package. It is -only enabled if LAMMPS was built with that package. See the "Build -package"_Build_package.html doc page for more info. - -These pair styles require that atoms store torque and angular velocity -(omega) as defined by the "atom_style"_atom_style.html. They also -require a per-particle radius is stored. The {sphere} atom style does -all of this. - -This pair style requires you to use the "comm_modify vel -yes"_comm_modify.html command so that velocities are stored by ghost -atoms. - -These pair styles will not restart exactly when using the -"read_restart"_read_restart.html command, though they should provide -statistically similar results. This is because the forces they -compute depend on atom velocities. See the -"read_restart"_read_restart.html command for more details. - -[Related commands:] - -"pair_coeff"_pair_coeff.html - -[Default:] none - -:line - -:link(Brilliantov) -[(Brilliantov)] Brilliantov, Spahn, Hertzsch, Poschel, Phys Rev E, 53, -p 5382-5392 (1996). - -:link(Silbert) -[(Silbert)] Silbert, Ertas, Grest, Halsey, Levine, Plimpton, Phys Rev -E, 64, p 051302 (2001). - -:link(Zhang3) -[(Zhang)] Zhang and Makse, Phys Rev E, 72, p 011301 (2005). + \ No newline at end of file diff --git a/doc/src/pairs.txt b/doc/src/pairs.txt index ca79051053..3cd20c728d 100644 --- a/doc/src/pairs.txt +++ b/doc/src/pairs.txt @@ -41,6 +41,7 @@ Pair Styles :h1 pair_gauss pair_gayberne pair_gran + pair_granular pair_gromacs pair_gw pair_hbond_dreiding diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 82a470f83b..3713b9251c 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -11,8 +11,9 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- -Contributing authors: Leo Silbert (SNL), Gary Grest (SNL), - Jeremy Lechman (SNL), Dan Bolintineanu (SNL), Ishan Srivastava (SNL) +Contributing authors: +Dan Bolintineanu (SNL), Ishan Srivastava (SNL), Jeremy Lechman(SNL) +Leo Silbert (SNL), Gary Grest (SNL) ----------------------------------------------------------------------- */ #include @@ -50,7 +51,7 @@ using namespace MathConst; enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {TANGENTIAL_NOHISTORY, TANGENTIAL_MINDLIN}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN}; enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; @@ -98,13 +99,24 @@ PairGranular::~PairGranular() if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); - memory->destroy(cut); + memory->destroy(cutoff_type); memory->destroy(normal_coeffs); memory->destroy(tangential_coeffs); memory->destroy(roll_coeffs); memory->destroy(twist_coeffs); + memory->destroy(Emod); + memory->destroy(poiss); + + memory->destroy(normal_model); + memory->destroy(damping_model); + memory->destroy(tangential_model); + memory->destroy(roll_model); + memory->destroy(twist_model); + + + delete [] onerad_dynamic; delete [] onerad_frozen; delete [] maxrad_dynamic; @@ -113,725 +125,7 @@ PairGranular::~PairGranular() memory->destroy(mass_rigid); } -void PairGranular::compute(int eflag, int vflag){ -#ifdef TEMPLATED_PAIR_GRANULAR - if (normal == HOOKE){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == HERTZ){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == HERTZ_MATERIAL){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == DMT){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == JKR){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,3,2>(eflag, vflag); - } - } - } - } - -#else - compute_untemplated(Tp_normal, Tp_damping, Tp_tangential, - Tp_roll, Tp_twist, - eflag, vflag); -#endif -} - -#ifdef TEMPLATED_PAIR_GRANULAR -template < int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_twist, int Tp_roll > -void PairGranular::compute_templated(int eflag, int vflag) -#else -void PairGranular::compute_untemplated - (int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_twist, int Tp_roll, int eflag, int vflag) -#endif +void PairGranular::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; @@ -847,14 +141,14 @@ void PairGranular::compute_untemplated double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; double fs, fs1, fs2, fs3; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + //For JKR double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; double t0, t1, t2, t3, t4, t5, t6; double sqrt1, sqrt2, sqrt3, sqrt4; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - //Rolling double k_roll, damp_roll; double roll1, roll2, roll3, torroll1, torroll2, torroll3; @@ -947,7 +241,7 @@ void PairGranular::compute_untemplated Reff = radi*radj/(radi+radj); touchflag = false; - if (Tp_normal == JKR){ + if (normal_model[itype][jtype] == JKR){ if (touch[jj]){ R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; @@ -1008,7 +302,7 @@ void PairGranular::compute_untemplated delta = radsum - r; dR = delta*Reff; - if (Tp_normal == JKR){ + if (normal_model[itype][jtype] == JKR){ touch[jj] = 1; R2=Reff*Reff; coh = normal_coeffs[itype][jtype][3]; @@ -1031,22 +325,21 @@ void PairGranular::compute_untemplated else{ knfac = E; //Hooke Fne = knfac*delta; - if (Tp_normal != HOOKE) - a = sqrt(dR); + a = sqrt(dR); + if (normal_model[itype][jtype] != HOOKE) Fne *= a; - if (Tp_normal == DMT) + if (normal_model[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (Tp_damping == VELOCITY){ + if (damping_model[itype][jtype] == VELOCITY){ damp_normal = 1; } - else if (Tp_damping == VISCOELASTIC){ - if (Tp_normal == HOOKE) a = sqrt(dR); + else if (damping_model[itype][jtype] == VISCOELASTIC){ damp_normal = a*meff; } - else if (Tp_damping == TSUJI){ + else if (damping_model[itype][jtype] == TSUJI){ damp_normal = sqrt(meff*knfac); } @@ -1081,8 +374,7 @@ void PairGranular::compute_untemplated history = &allhistory[size_history*jj]; } - - if (Tp_normal == JKR){ + if (normal_model[itype][jtype] == JKR){ F_pulloff = 3*M_PI*coh*Reff; Fcrit = fabs(Fne + 2*F_pulloff); } @@ -1096,7 +388,7 @@ void PairGranular::compute_untemplated k_tangential = tangential_coeffs[itype][jtype][0]; damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - if (Tp_tangential > 0){ + if (tangential_history){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -1153,7 +445,7 @@ void PairGranular::compute_untemplated // Rolling resistance //**************************************** - if (Tp_roll != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -1168,7 +460,7 @@ void PairGranular::compute_untemplated if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; else vrlmaginv = 0.0; - if (Tp_roll > 1){ + if (roll_history){ int rhist0 = roll_history_index; int rhist1 = rhist0 + 1; int rhist2 = rhist1 + 1; @@ -1197,6 +489,7 @@ void PairGranular::compute_untemplated history[rhist2] += vrl3*dt; } + k_roll = roll_coeffs[itype][jtype][0]; damp_roll = roll_coeffs[itype][jtype][1]; fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; @@ -1231,9 +524,9 @@ void PairGranular::compute_untemplated //**************************************** // Twisting torque, including history effects //**************************************** - if (Tp_twist != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (Tp_twist == TWIST_MARSHALL){ + if (twist_model[itype][jtype] == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a; @@ -1243,7 +536,7 @@ void PairGranular::compute_untemplated damp_twist = twist_coeffs[itype][jtype][1]; mu_twist = twist_coeffs[itype][jtype][2]; } - if (Tp_twist > 1){ + if (twist_model[itype][jtype] > 1){ if (historyupdate){ history[twist_history_index] += magtwist*dt; } @@ -1278,7 +571,7 @@ void PairGranular::compute_untemplated torque[i][1] -= radi*tor2; torque[i][2] -= radi*tor3; - if (Tp_twist != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE){ tortwist1 = magtortwist * nx; tortwist2 = magtortwist * ny; tortwist3 = magtortwist * nz; @@ -1288,7 +581,7 @@ void PairGranular::compute_untemplated torque[i][2] += tortwist3; } - if (Tp_roll != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE){ torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr torroll2 = Reff*(nz*fr1 - nx*fr3); torroll3 = Reff*(nx*fr2 - ny*fr1); @@ -1307,12 +600,12 @@ void PairGranular::compute_untemplated torque[j][1] -= radj*tor2; torque[j][2] -= radj*tor3; - if (Tp_twist != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE){ torque[j][0] -= tortwist1; torque[j][1] -= tortwist2; torque[j][2] -= tortwist3; } - if (Tp_roll != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE){ torque[j][0] -= torroll1; torque[j][1] -= torroll2; torque[j][2] -= torroll3; @@ -1341,12 +634,21 @@ void PairGranular::allocate() setflag[i][j] = 0; memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(cut,n+1,n+1,"pair:cut"); + memory->create(cutoff_type,n+1,n+1,"pair:cutoff_type"); memory->create(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); + memory->create(Emod,n+1,n+1,"pair:Emod"); + memory->create(poiss,n+1,n+1,"pair:poiss"); + + memory->create(normal_model,n+1,n+1,"pair:normal_model"); + memory->create(damping_model,n+1,n+1,"pair:damping_model"); + memory->create(tangential_model,n+1,n+1,"pair:tangential_model"); + memory->create(roll_model,n+1,n+1,"pair:roll_model"); + memory->create(twist_model,n+1,n+1,"pair:twist_model"); + onerad_dynamic = new double[n+1]; onerad_frozen = new double[n+1]; maxrad_dynamic = new double[n+1]; @@ -1365,9 +667,9 @@ void PairGranular::settings(int narg, char **arg) else{ cutoff_global = -1; //Will be set based on particle sizes, model choice } - tangential_history = 0; + + normal_history = tangential_history = 0; roll_history = twist_history = 0; - normal_set = tangential_set = damping_set = roll_set = twist_set = 0; } /* ---------------------------------------------------------------------- @@ -1376,10 +678,15 @@ void PairGranular::settings(int narg, char **arg) void PairGranular::coeff(int narg, char **arg) { - double normal_coeffs_local[4]; - double tangential_coeffs_local[4]; - double roll_coeffs_local[4]; - double twist_coeffs_local[4]; + int normal_model_one, damping_model_one; + int tangential_model_one, roll_model_one, twist_model_one; + + double normal_coeffs_one[4]; + double tangential_coeffs_one[4]; + double roll_coeffs_one[4]; + double twist_coeffs_one[4]; + + double cutoff_one = -1; if (narg < 2) error->all(FLERR,"Incorrect args for pair coefficients"); @@ -1390,209 +697,200 @@ void PairGranular::coeff(int narg, char **arg) force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + //Defaults + normal_model_one = tangential_model_one = -1; + roll_model_one = twist_model_one = 0; + damping_model_one = VISCOELASTIC; + int iarg = 2; while (iarg < narg){ if (strcmp(arg[iarg], "hooke") == 0){ if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); - if (!normal_set) normal = HOOKE; - else if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_set = 1; + normal_model_one = HOOKE; + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += 3; } else if (strcmp(arg[iarg], "hertz") == 0){ int num_coeffs = 2; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = HERTZ; - else if (normal_set && normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_set = 1; + normal_model_one = HERTZ; + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "hertz/material") == 0){ int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = HERTZ_MATERIAL; - else if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_set = 1; + normal_model_one = HERTZ; + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio iarg += num_coeffs+1; } else if (strcmp(arg[iarg], "dmt") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = DMT; - else if (normal != DMT) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion - normal_set = 1; + normal_model_one = DMT; + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio + normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion iarg += 5; } else if (strcmp(arg[iarg], "jkr") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); beyond_contact = 1; - if (!normal_set) normal = JKR; - else if (normal != JKR) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion - normal_set = 1; + normal_model_one = JKR; + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio + normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; } else if (strcmp(arg[iarg], "damp") == 0){ if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); if (strcmp(arg[iarg+1], "velocity") == 0){ - if (!damping_set) damping = VELOCITY; - else if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + damping_model_one = VELOCITY; + iarg += 1; } else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ - if (!damping_set) damping = VISCOELASTIC; - else if (damping != VISCOELASTIC) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + damping_model_one = VISCOELASTIC; + iarg += 1; } - else if (strcmp(arg[iarg+1], "tsuji") == 0){ - if (!damping_set) damping = TSUJI; - if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + else if (strcmp(arg[iarg], "tsuji") == 0){ + damping_model_one = TSUJI; + iarg += 1; } - damping_set = 1; - iarg += 2; } else if (strcmp(arg[iarg], "tangential") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - if (!tangential_set) tangential = TANGENTIAL_NOHISTORY; - else if (tangential != TANGENTIAL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types"); + if (strcmp(arg[iarg+1], "linear_nohistory") == 0){ + tangential_model_one = TANGENTIAL_NOHISTORY; } - else if (strcmp(arg[iarg+1], "mindlin") == 0){ - if (!tangential_set) tangential = TANGENTIAL_MINDLIN; - else if (tangential != TANGENTIAL_MINDLIN) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types");; + else if (strcmp(arg[iarg+1], "linear_history") == 0){ + tangential_model_one = TANGENTIAL_HISTORY; tangential_history = 1; } else{ error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); } - tangential_set = 1; - tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; } else if (strcmp(arg[iarg], "rolling") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); if (strcmp(arg[iarg+1], "none") == 0){ - if (!roll_set) roll = ROLL_NONE; - else if (roll != ROLL_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); + roll_model_one = ROLL_NONE; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); if (strcmp(arg[iarg+1], "nohistory") == 0){ - if (!roll_set) roll = ROLL_NOHISTORY; - else if (roll != ROLL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); + roll_model_one = ROLL_NOHISTORY; } else if (strcmp(arg[iarg+1], "sds") == 0){ - if (!roll_set) roll = ROLL_SDS; - else if (roll != ROLL_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); + roll_model_one = ROLL_SDS; roll_history = 1; } else{ error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); } - roll_set =1 ; - roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kR - roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR - roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. + roll_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. iarg += 5; } } else if (strcmp(arg[iarg], "twisting") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); if (strcmp(arg[iarg+1], "none") == 0){ - if (!twist_set) twist = TWIST_NONE; - else if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + twist_model_one = TWIST_NONE; iarg += 2; } else if (strcmp(arg[iarg+1], "marshall") == 0){ - if (!twist_set) twist = TWIST_MARSHALL; - else if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + twist_model_one = TWIST_MARSHALL; twist_history = 1; - twist_set = 1; iarg += 2; } else{ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - else if (strcmp(arg[iarg+1], "nohistory") == 0){ - if (!twist_set) twist = TWIST_NOHISTORY; - if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + if (strcmp(arg[iarg+1], "nohistory") == 0){ + twist_model_one = TWIST_NOHISTORY; } else if (strcmp(arg[iarg+1], "sds") == 0){ - if (!twist_set) twist = TWIST_SDS; - else if (twist != TWIST_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + twist_model_one = TWIST_SDS; twist_history = 1; } else{ error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); } - twist_set = 1; - twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + twist_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt + twist_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + twist_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; } } + else if (strcmp(arg[iarg], "cutoff") == 0){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + cutoff_one = force->numeric(FLERR,arg[iarg+1]); + } else error->all(FLERR, "Illegal pair coeff command"); } //It is an error not to specify normal or tangential model - if (!normal_set) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); - if (!tangential_set) error->all(FLERR, "Illegal pair coeff command, must specify tangential contact model"); - - //If unspecified, set damping to VISCOELASTIC, twist/roll to NONE (cannot be changed by subsequent pair_coeff commands) - if (!damping_set) damping = VISCOELASTIC; - if (!roll_set) roll = ROLL_NONE; - if (!twist_set) twist = TWIST_NONE; - damping_set = roll_set = twist_set = 1; + if ((normal_model_one < 0) || (tangential_model_one < 0)) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); int count = 0; double damp; - if (damping == TSUJI){ + if (damping_model_one == TSUJI){ double cor; - cor = normal_coeffs_local[1]; + cor = normal_coeffs_one[1]; damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ 27.467*pow(cor,4)-18.022*pow(cor,5)+ 4.8218*pow(cor,6); } - else damp = normal_coeffs_local[1]; + else damp = normal_coeffs_one[1]; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_local[0]; + normal_model[i][j] = normal_model[j][i] = normal_model_one; normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; - if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_local[3]; + if (normal_model_one != HERTZ && normal_model_one != HOOKE){ + Emod[i][j] = Emod[j][i] = normal_coeffs_one[0]; + poiss[i][j] = poiss[j][i] = normal_coeffs_one[2]; + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(Emod[i][j], Emod[i][j], poiss[i][j], poiss[i][j]); + } + else{ + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_one[0]; + } + if ((normal_model_one == JKR) || (normal_model_one == DMT)) + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_one[3]; + damping_model[i][j] = damping_model[j][i] = damping_model_one; + + tangential_model[i][j] = tangential_model[j][i] = tangential_model_one; for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_local[k]; + tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_one[k]; - if (roll != ROLL_NONE) + roll_model[i][j] = roll_model[j][i] = roll_model_one; + if (roll_model_one != ROLL_NONE) for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_local[k]; + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_one[k]; - if (twist != TWIST_NONE && twist != TWIST_MARSHALL) + twist_model[i][j] = twist_model[j][i] = twist_model_one; + if (twist_model_one != TWIST_NONE && twist_model_one != TWIST_MARSHALL) for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_local[k]; + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_one[k]; + + + cutoff_type[i][j] = cutoff_type[j][i] = cutoff_one; setflag[i][j] = 1; count++; } } - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); } @@ -1615,7 +913,9 @@ void PairGranular::init_style() use_history = tangential_history || roll_history || twist_history; //For JKR, will need fix/neigh/history to keep track of touch arrays - if (normal == JKR) use_history = 1; + for (int i = 1; i <= atom->ntypes; i++) + for (int j = 1; j <= atom->ntypes; j++) + if (normal_model[i][j] == JKR) use_history = 1; size_history = 3*tangential_history + 3*roll_history + twist_history; @@ -1693,13 +993,11 @@ void PairGranular::init_style() if (ipour >= 0) { itype = i; double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); - if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); onerad_dynamic[i] = radmax; } if (idep >= 0) { itype = i; double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); - if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); onerad_dynamic[i] = radmax; } } @@ -1711,9 +1009,6 @@ void PairGranular::init_style() for (i = 0; i < nlocal; i++){ double radius_cut = radius[i]; - if (normal == JKR){ - radius_cut = radius[i] - 0.5*pulloff_distance(radius[i], type[i]); - } if (mask[i] & freeze_group_bit){ onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); } @@ -1743,32 +1038,38 @@ void PairGranular::init_style() double PairGranular::init_one(int i, int j) { double cutoff; - if (setflag[i][j] == 0) { - if (normal != HOOKE && normal != HERTZ){ - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], - normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - normal_coeffs[i][j][2] = normal_coeffs[j][i][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], - normal_coeffs[i][i][2], normal_coeffs[j][j][2]); + if (setflag[i][j] == 0){ + if ((normal_model[i][i] != normal_model[j][j]) || + (damping_model[i][i] != damping_model[j][j]) || + (tangential_model[i][i] != tangential_model[j][j]) || + (roll_model[i][i] != roll_model[j][j]) || + (twist_model[i][i] != twist_model[j][j])){ + + char str[512]; + sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); + error->one(FLERR,str); } - else{ + + if (normal_model[i][j] == HERTZ || normal_model[i][j] == HOOKE) normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); - } + else + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(Emod[i][i], Emod[j][j], poiss[i][i], poiss[j][j]); normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); - if ((normal == JKR) || (normal == DMT)) + if ((normal_model[i][j] == JKR) || (normal_model[i][j] == DMT)) normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - if (roll != ROLL_NONE){ + if (roll_model[i][j] != ROLL_NONE){ for (int k = 0; k < 3; k++) roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } - if (twist != TWIST_NONE && twist != TWIST_MARSHALL){ + if (twist_model[i][j] != TWIST_NONE && twist_model[i][j] != TWIST_MARSHALL){ for (int k = 0; k < 3; k++) twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } @@ -1780,22 +1081,40 @@ double PairGranular::init_one(int i, int j) // To avoid this issue, for cases involving cut[i][j] = 0.0 (possible only // if there is no current information about radius/cutoff of type i and j). // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. - + double pulloff; if (cutoff_global < 0){ - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || - ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + if (cutoff_type[i][j] < 0){ + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + if (normal_model[i][j] == JKR){ + pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_dynamic[j], i, j); + cutoff += pulloff; + } + else{ + pulloff = 0; + } + + if (normal_model[i][j] == JKR) + pulloff = pulloff_distance(maxrad_frozen[i], maxrad_dynamic[j], i, j); + cutoff = MAX(cutoff, maxrad_frozen[i]+maxrad_dynamic[j]+pulloff); + + if (normal_model[i][j] == JKR) + pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_frozen[j], i, j); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]+pulloff); } - cutoff = cutmax; + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; + } + } + else{ + cutoff = cutoff_type[i][j]; } } else{ @@ -1804,7 +1123,6 @@ double PairGranular::init_one(int i, int j) return cutoff; } - /* ---------------------------------------------------------------------- proc 0 writes to restart file ------------------------------------------------------------------------- */ @@ -1812,15 +1130,15 @@ double PairGranular::init_one(int i, int j) void PairGranular::write_restart(FILE *fp) { int i,j; - fwrite(&normal,sizeof(int),1,fp); - fwrite(&damping,sizeof(int),1,fp); - fwrite(&tangential,sizeof(int),1,fp); - fwrite(&roll,sizeof(int),1,fp); - fwrite(&twist,sizeof(int),1,fp); 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(&normal_model[i][j],sizeof(int),1,fp); + fwrite(&damping_model[i][j],sizeof(int),1,fp); + fwrite(&tangential_model[i][j],sizeof(int),1,fp); + fwrite(&roll_model[i][j],sizeof(int),1,fp); + fwrite(&twist_model[i][j],sizeof(int),1,fp); fwrite(&normal_coeffs[i][j],sizeof(double),4,fp); fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); @@ -1840,30 +1158,28 @@ void PairGranular::read_restart(FILE *fp) allocate(); int i,j; int me = comm->me; - if (me == 0){ - fread(&normal,sizeof(int),1,fp); - fread(&damping,sizeof(int),1,fp); - fread(&tangential,sizeof(int),1,fp); - fread(&roll,sizeof(int),1,fp); - fread(&twist,sizeof(int),1,fp); - } - MPI_Bcast(&normal,1,MPI_INT,0,world); - MPI_Bcast(&damping,1,MPI_INT,0,world); - MPI_Bcast(&tangential,1,MPI_INT,0,world); - MPI_Bcast(&roll,1,MPI_INT,0,world); - MPI_Bcast(&twist,1,MPI_INT,0,world); 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(&normal_model[i][j],sizeof(int),1,fp); + fread(&damping_model[i][j],sizeof(int),1,fp); + fread(&tangential_model[i][j],sizeof(int),1,fp); + fread(&roll_model[i][j],sizeof(int),1,fp); + fread(&twist_model[i][j],sizeof(int),1,fp); fread(&normal_coeffs[i][j],sizeof(double),4,fp); fread(&tangential_coeffs[i][j],sizeof(double),3,fp); fread(&roll_coeffs[i][j],sizeof(double),3,fp); fread(&twist_coeffs[i][j],sizeof(double),3,fp); fread(&cut[i][j],sizeof(double),1,fp); } + MPI_Bcast(&normal_model[i][j],1,MPI_INT,0,world); + MPI_Bcast(&damping_model[i][j],1,MPI_INT,0,world); + MPI_Bcast(&tangential_model[i][j],1,MPI_INT,0,world); + MPI_Bcast(&roll_model[i][j],1,MPI_INT,0,world); + MPI_Bcast(&twist_model[i][j],1,MPI_INT,0,world); MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); @@ -1930,7 +1246,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, Reff = radi*radj/(radi+radj); bool touchflag; - if (normal == JKR){ + if (normal_model[itype][jtype] == JKR){ R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); @@ -2022,7 +1338,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, delta = radsum - r; dR = delta*Reff; - if (normal == JKR){ + if (normal_model[itype][jtype] == JKR){ dR2 = dR*dR; t0 = coh*coh*R2*R2*E; t1 = PI27SQ*t0; @@ -2042,22 +1358,21 @@ double PairGranular::single(int i, int j, int itype, int jtype, else{ knfac = E; Fne = knfac*delta; - if (normal != HOOKE) - a = sqrt(dR); + a = sqrt(dR); + if (normal_model[itype][jtype] != HOOKE) Fne *= a; - if (normal == DMT) + if (normal_model[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping == VELOCITY){ + if (damping_model[itype][jtype] == VELOCITY){ damp_normal = normal_coeffs[itype][jtype][1]; } - else if (damping == VISCOELASTIC){ - if (normal == HOOKE) a = sqrt(dR); + else if (damping_model[itype][jtype] == VISCOELASTIC){ damp_normal = normal_coeffs[itype][jtype][1]*a*meff; } - else if (damping == TSUJI){ + else if (damping_model[itype][jtype] == TSUJI){ damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); } @@ -2099,17 +1414,19 @@ double PairGranular::single(int i, int j, int itype, int jtype, vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); - Fcrit = fabs(Fne); - if (normal == JKR){ + if (normal_model[itype][jtype] == JKR){ F_pulloff = 3*M_PI*coh*Reff; Fcrit = fabs(Fne + 2*F_pulloff); } + else{ + Fcrit = fabs(Fne); + } //------------------------------ //Tangential forces //------------------------------ k_tangential = tangential_coeffs[itype][jtype][0]; - if (normal != HOOKE){ + if (normal_model[itype][jtype] != HOOKE){ k_tangential *= a; } damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; @@ -2150,7 +1467,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, // Rolling resistance //**************************************** - if (roll != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE){ relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -2211,9 +1528,9 @@ double PairGranular::single(int i, int j, int itype, int jtype, //**************************************** // Twisting torque, including history effects //**************************************** - if (twist != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist == TWIST_MARSHALL){ + if (twist_model[itype][jtype] == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a; @@ -2293,22 +1610,18 @@ double PairGranular::memory_usage() mixing of Young's modulus (E) ------------------------------------------------------------------------- */ -double PairGranular::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) +double PairGranular::mix_stiffnessE(double Eii, double Ejj, double poisii, double poisjj) { - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); + return 1/((1-poisii*poisii)/Eii+(1-poisjj*poisjj)/Ejj); } /* ---------------------------------------------------------------------- mixing of shear modulus (G) - ------------------------------------------------------------------------- */ +------------------------------------------------------------------------ */ -double PairGranular::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) +double PairGranular::mix_stiffnessG(double Gii, double Gjj, double poisii, double poisjj) { - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); + return 1/((2.0 -poisii)/Gii+(2.0-poisjj)/Gjj); } /* ---------------------------------------------------------------------- @@ -2325,13 +1638,14 @@ double PairGranular::mix_geom(double valii, double valjj) Compute pull-off distance (beyond contact) for a given radius and atom type ------------------------------------------------------------------------- */ -double PairGranular::pulloff_distance(double radius, int itype) +double PairGranular::pulloff_distance(double radi, double radj, int itype, int jtype) { - double E, coh, a, delta_pulloff; + double E, coh, a, delta_pulloff, Reff; + Reff = radi*radj/(radi+radj); + if (Reff <= 0) return 0; coh = normal_coeffs[itype][itype][3]; - E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], - normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); - a = cbrt(9*M_PI*coh*radius*radius/(4*E)); - return a*a/radius - 2*sqrt(M_PI*coh*a/E); + E = normal_coeffs[itype][jtype][0]; + a = cbrt(9*M_PI*coh*Reff/(4*E)); + return a*a/Reff - 2*sqrt(M_PI*coh*a/E); } diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index f39f31e4cb..625ff17c72 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -21,40 +21,28 @@ PairStyle(granular,PairGranular) #define LMP_PAIR_GRANULAR_H #include "pair.h" +#include "pair_granular.h" namespace LAMMPS_NS { -class PairGranular : public Pair { +class PairGranular : public Pair{ public: PairGranular(class LAMMPS *); - virtual ~PairGranular(); - + ~PairGranular(); void compute(int, int); - // comment next line to turn off templating -#define TEMPLATED_PAIR_GRANULAR -#ifdef TEMPLATED_PAIR_GRANULAR - template < int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_roll, int Tp_twist> - void compute_templated(int, int); -#else - void compute_untemplated(int, int, int, int, int, - int, int); -#endif - - virtual void settings(int, char **); - virtual void coeff(int, char **); + void settings(int, char **); + void coeff(int, char **); void init_style(); double init_one(int, int); void write_restart(FILE *); void read_restart(FILE *); void reset_dt(); - virtual double single(int, int, int, int, double, double, double, double &); + double single(int, int, int, int, double, double, double, double &); int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); double memory_usage(); protected: - double cut_global; double dt; int freeze_group_bit; int use_history; @@ -72,22 +60,26 @@ public: double *mass_rigid; // rigid mass for owned+ghost atoms int nmax; // allocated size of mass_rigid - virtual void allocate(); + void allocate(); private: int size_history; - //Models - int normal, damping, tangential, roll, twist; + //Models choices + int **normal_model, **damping_model; + double **tangential_model, **roll_model, **twist_model; //History flags - int tangential_history, roll_history, twist_history; + int normal_history, tangential_history, roll_history, twist_history; //Indices of history entries - int tangential_history_index, roll_history_index, twist_history_index; + int normal_history_index; + int tangential_history_index; + int roll_history_index; + int twist_history_index; - //Flags for whether model choices have been set - int normal_set, tangential_set, damping_set, roll_set, twist_set; + //Per-type material coefficients + double **Emod, **poiss, **Gmod; //Per-type coefficients, set in pair coeff command double ***normal_coeffs; @@ -95,13 +87,14 @@ private: double ***roll_coeffs; double ***twist_coeffs; - //Optional user-specified global cutoff + //Optional user-specified global cutoff, per-type user-specified cutoffs + double **cutoff_type; double cutoff_global; - double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); - double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); - double mix_geom(double valii, double valjj); - double pulloff_distance(double radius, int itype); + double mix_stiffnessE(double, double, double, double); + double mix_stiffnessG(double, double, double, double); + double mix_geom(double, double); + double pulloff_distance(double, double, int, int); }; } diff --git a/src/pair_granular.cpp b/src/pair_granular.cpp new file mode 100644 index 0000000000..82a470f83b --- /dev/null +++ b/src/pair_granular.cpp @@ -0,0 +1,2337 @@ +/* ---------------------------------------------------------------------- +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: Leo Silbert (SNL), Gary Grest (SNL), + Jeremy Lechman (SNL), Dan Bolintineanu (SNL), Ishan Srivastava (SNL) +----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include "pair_granular.h" +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "force.h" +#include "update.h" +#include "modify.h" +#include "fix.h" +#include "fix_neigh_history.h" +#include "comm.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "memory.h" +#include "error.h" +#include "math_const.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +#define PI27SQ 266.47931882941264802866 // 27*PI**2 +#define THREEROOT3 5.19615242270663202362 // 3*sqrt(3) +#define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) +#define INVROOT6 0.40824829046386307274 // 1/sqrt(6) +#define FOURTHIRDS 1.333333333333333 // 4/3 +#define TWOPI 6.28318530717959 // 2*PI + +#define EPSILON 1e-10 + +enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; +enum {VELOCITY, VISCOELASTIC, TSUJI}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_MINDLIN}; +enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; +enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; + +/* ---------------------------------------------------------------------- */ + +PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) +{ + single_enable = 1; + no_virial_fdotr_compute = 1; + fix_history = NULL; + + single_extra = 9; + svector = new double[single_extra]; + + neighprev = 0; + + nmax = 0; + mass_rigid = NULL; + + onerad_dynamic = NULL; + onerad_frozen = NULL; + maxrad_dynamic = NULL; + maxrad_frozen = NULL; + + dt = update->dt; + + // set comm size needed by this Pair if used with fix rigid + + comm_forward = 1; + + use_history = 0; + beyond_contact = 0; + nondefault_history_transfer = 0; + tangential_history_index = 0; + roll_history_index = twist_history_index = 0; + +} + +/* ---------------------------------------------------------------------- */ +PairGranular::~PairGranular() +{ + delete [] svector; + if (fix_history) modify->delete_fix("NEIGH_HISTORY"); + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(cut); + + memory->destroy(normal_coeffs); + memory->destroy(tangential_coeffs); + memory->destroy(roll_coeffs); + memory->destroy(twist_coeffs); + + delete [] onerad_dynamic; + delete [] onerad_frozen; + delete [] maxrad_dynamic; + delete [] maxrad_frozen; + } + memory->destroy(mass_rigid); +} + +void PairGranular::compute(int eflag, int vflag){ +#ifdef TEMPLATED_PAIR_GRANULAR + if (normal == HOOKE){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<0,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<0,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<0,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<0,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<0,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == HERTZ){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<1,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<1,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<1,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<1,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<1,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == HERTZ_MATERIAL){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<2,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<2,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<2,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<2,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<2,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == DMT){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<3,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<3,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<3,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<3,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<3,2,1,3,2>(eflag, vflag); + } + } + } + } + else if (normal == JKR){ + if (damping == VELOCITY){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,0,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,0,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,0,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,0,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,0,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,0,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,0,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,0,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,0,1,3,2>(eflag, vflag); + } + } + } + else if (damping == VISCOELASTIC){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,1,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,1,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,1,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,1,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,1,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,1,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,1,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,1,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,1,1,3,2>(eflag, vflag); + } + } + } + else if (damping == TSUJI){ + if (tangential == TANGENTIAL_NOHISTORY){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,2,0,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,2,0,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,2,0,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,2,0,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,0,3,2>(eflag, vflag); + } + } + else if (tangential == TANGENTIAL_MINDLIN){ + if (twist == TWIST_NONE){ + if (roll == ROLL_NONE) compute_templated<4,2,1,0,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,0,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,0,2>(eflag, vflag); + } + else if (twist == TWIST_NOHISTORY){ + if (roll == ROLL_NONE) compute_templated<4,2,1,1,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,1,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,1,2>(eflag, vflag); + } + else if (twist == TWIST_SDS){ + if (roll == ROLL_NONE) compute_templated<4,2,1,2,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,2,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,2,2>(eflag, vflag); + } + else if (twist == TWIST_MARSHALL){ + if (roll == ROLL_NONE) compute_templated<4,2,1,3,0>(eflag, vflag); + else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,3,1>(eflag, vflag); + else if (roll == ROLL_SDS) compute_templated<4,2,1,3,2>(eflag, vflag); + } + } + } + } + +#else + compute_untemplated(Tp_normal, Tp_damping, Tp_tangential, + Tp_roll, Tp_twist, + eflag, vflag); +#endif +} + +#ifdef TEMPLATED_PAIR_GRANULAR +template < int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_twist, int Tp_roll > +void PairGranular::compute_templated(int eflag, int vflag) +#else +void PairGranular::compute_untemplated + (int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_twist, int Tp_roll, int eflag, int vflag) +#endif +{ + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,rsq,r,rinv,rsqinv; + double Reff, delta, dR, dR2; + + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + + double knfac, damp_normal; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; + + //For JKR + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; + + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + + //Twisting + double k_twist, damp_twist, mu_twist; + double signtwist, magtwist, magtortwist, Mtcrit; + double tortwist1, tortwist2, tortwist3; + + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *history,*allhistory,**firsthistory; + + bool touchflag; + + if (eflag || vflag) ev_setup(eflag,vflag); + else evflag = vflag_fdotr = 0; + + int historyupdate = 1; + if (update->setupflag) historyupdate = 0; + + // update rigid body info for owned & ghost atoms if using FixRigid masses + // body[i] = which body atom I is in, -1 if none + // mass_body = mass of each rigid body + + if (fix_rigid && neighbor->ago == 0){ + int tmp; + int *body = (int *) fix_rigid->extract("body",tmp); + double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); + if (atom->nmax > nmax) { + memory->destroy(mass_rigid); + nmax = atom->nmax; + memory->create(mass_rigid,nmax,"pair:mass_rigid"); + } + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; + else mass_rigid[i] = 0.0; + comm->forward_comm_pair(this); + } + + double **x = atom->x; + double **v = atom->v; + double **f = atom->f; + int *type = atom->type; + 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 newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + firsttouch = fix_history->firstflag; + firsthistory = fix_history->firstvalue; + + for (ii = 0; ii < inum; ii++) { + i = ilist[ii]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + radi = radius[i]; + touch = firsttouch[i]; + allhistory = firsthistory[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]; + jtype = type[j]; + rsq = delx*delx + dely*dely + delz*delz; + radj = radius[j]; + radsum = radi + radj; + + E = normal_coeffs[itype][jtype][0]; + Reff = radi*radj/(radi+radj); + touchflag = false; + + if (Tp_normal == JKR){ + if (touch[jj]){ + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum-delta_pulloff; + touchflag = (rsq < dist_pulloff*dist_pulloff); + } + else{ + touchflag = (rsq < radsum*radsum); + } + } + else{ + touchflag = (rsq < radsum*radsum); + } + + if (!touchflag){ + // unset non-touching neighbors + touch[jj] = 0; + history = &allhistory[size_history*jj]; + for (int k = 0; k < size_history; k++) history[k] = 0.0; + } + else{ + r = sqrt(rsq); + rinv = 1.0/r; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // 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*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + if (Tp_normal == JKR){ + touch[jj] = 1; + R2=Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = FOURTHIRDS*E*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + else{ + knfac = E; //Hooke + Fne = knfac*delta; + if (Tp_normal != HOOKE) + a = sqrt(dR); + Fne *= a; + if (Tp_normal == DMT) + Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; + } + + //Consider restricting Hooke to only have 'velocity' as an option for damping? + if (Tp_damping == VELOCITY){ + damp_normal = 1; + } + else if (Tp_damping == VISCOELASTIC){ + if (Tp_normal == HOOKE) a = sqrt(dR); + damp_normal = a*meff; + } + else if (Tp_damping == TSUJI){ + damp_normal = sqrt(meff*knfac); + } + + Fdamp = -normal_coeffs[itype][jtype][1]*damp_normal*vnnr; + + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + // If any history is needed: + if (use_history){ + touch[jj] = 1; + history = &allhistory[size_history*jj]; + } + + + if (Tp_normal == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*F_pulloff); + } + else{ + Fcrit = fabs(Fne); + } + + //------------------------------ + //Tangential forces + //------------------------------ + k_tangential = tangential_coeffs[itype][jtype][0]; + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + + if (Tp_tangential > 0){ + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // Rotate and update displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (historyupdate) { + rsht = history[0]*nx + history[1]*ny + history[2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + history[0] -= rsht*nx; + history[1] -= rsht*ny; + history[2] -= rsht*nz; + //Also rescale to preserve magnitude + history[0] *= scalefac; + history[1] *= scalefac; + history[2] *= scalefac; + } + //Update history + history[0] += vtr1*dt; + history[1] += vtr2*dt; + history[2] += vtr3*dt; + } + + // tangential forces = history + tangential velocity damping + fs1 = -k_tangential*history[0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[2] - damp_tangential*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; + } + + //**************************************** + // Rolling resistance + //**************************************** + + if (Tp_roll != ROLL_NONE){ + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + if (Tp_roll > 1){ + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + if (historyupdate){ + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + history[rhist0] -= rolldotn*nx; + history[rhist1] -= rolldotn*ny; + history[rhist2] -= rolldotn*nz; + //Also rescale to preserve magnitude + history[rhist0] *= scalefac; + history[rhist1] *= scalefac; + history[rhist2] *= scalefac; + } + history[rhist0] += vrl1*dt; + history[rhist1] += vrl2*dt; + history[rhist2] += vrl3*dt; + } + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; + } + } + + //**************************************** + // Twisting torque, including history effects + //**************************************** + if (Tp_twist != TWIST_NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (Tp_twist == TWIST_MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a; + } + else{ + k_twist = twist_coeffs[itype][jtype][0]; + damp_twist = twist_coeffs[itype][jtype][1]; + mu_twist = twist_coeffs[itype][jtype][2]; + } + if (Tp_twist > 1){ + if (historyupdate){ + history[twist_history_index] += magtwist*dt; + } + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; + } + } + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[i][0] -= radi*tor1; + torque[i][1] -= radi*tor2; + torque[i][2] -= radi*tor3; + + if (Tp_twist != TWIST_NONE){ + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[i][0] += tortwist1; + torque[i][1] += tortwist2; + torque[i][2] += tortwist3; + } + + if (Tp_roll != ROLL_NONE){ + torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = Reff*(nz*fr1 - nx*fr3); + torroll3 = Reff*(nx*fr2 - ny*fr1); + + torque[i][0] += torroll1; + torque[i][1] += torroll2; + torque[i][2] += torroll3; + } + + if (force->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 (Tp_twist != TWIST_NONE){ + torque[j][0] -= tortwist1; + torque[j][1] -= tortwist2; + torque[j][2] -= tortwist3; + } + if (Tp_roll != ROLL_NONE){ + torque[j][0] -= torroll1; + torque[j][1] -= torroll2; + torque[j][2] -= torroll3; + } + } + if (evflag) ev_tally_xyz(i,j,nlocal,0, + 0.0,0.0,fx,fy,fz,delx,dely,delz); + } + } + } +} + + +/* ---------------------------------------------------------------------- +allocate all arrays +------------------------------------------------------------------------- */ + +void PairGranular::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(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); + memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); + memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); + memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); + + onerad_dynamic = new double[n+1]; + onerad_frozen = new double[n+1]; + maxrad_dynamic = new double[n+1]; + maxrad_frozen = new double[n+1]; +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairGranular::settings(int narg, char **arg) +{ + if (narg == 1){ + cutoff_global = force->numeric(FLERR,arg[0]); + } + else{ + cutoff_global = -1; //Will be set based on particle sizes, model choice + } + tangential_history = 0; + roll_history = twist_history = 0; + normal_set = tangential_set = damping_set = roll_set = twist_set = 0; +} + +/* ---------------------------------------------------------------------- + set coeffs for one or more type pairs +------------------------------------------------------------------------- */ + +void PairGranular::coeff(int narg, char **arg) +{ + double normal_coeffs_local[4]; + double tangential_coeffs_local[4]; + double roll_coeffs_local[4]; + double twist_coeffs_local[4]; + + if (narg < 2) + error->all(FLERR,"Incorrect args for pair coefficients"); + + if (!allocated) allocate(); + + int ilo,ihi,jlo,jhi; + force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); + force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); + + int iarg = 2; + while (iarg < narg){ + if (strcmp(arg[iarg], "hooke") == 0){ + if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); + if (!normal_set) normal = HOOKE; + else if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_set = 1; + iarg += 3; + } + else if (strcmp(arg[iarg], "hertz") == 0){ + int num_coeffs = 2; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + if (!normal_set) normal = HERTZ; + else if (normal_set && normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_set = 1; + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "hertz/material") == 0){ + int num_coeffs = 3; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + if (!normal_set) normal = HERTZ_MATERIAL; + else if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_set = 1; + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "dmt") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); + if (!normal_set) normal = DMT; + else if (normal != DMT) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + normal_set = 1; + iarg += 5; + } + else if (strcmp(arg[iarg], "jkr") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); + beyond_contact = 1; + if (!normal_set) normal = JKR; + else if (normal != JKR) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); + normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping + normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G + normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + normal_set = 1; + iarg += 5; + } + else if (strcmp(arg[iarg], "damp") == 0){ + if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); + if (strcmp(arg[iarg+1], "velocity") == 0){ + if (!damping_set) damping = VELOCITY; + else if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ + if (!damping_set) damping = VISCOELASTIC; + else if (damping != VISCOELASTIC) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "tsuji") == 0){ + if (!damping_set) damping = TSUJI; + if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); + } + damping_set = 1; + iarg += 2; + } + else if (strcmp(arg[iarg], "tangential") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (!tangential_set) tangential = TANGENTIAL_NOHISTORY; + else if (tangential != TANGENTIAL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "mindlin") == 0){ + if (!tangential_set) tangential = TANGENTIAL_MINDLIN; + else if (tangential != TANGENTIAL_MINDLIN) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types");; + tangential_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); + } + tangential_set = 1; + tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + else if (strcmp(arg[iarg], "rolling") == 0){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + if (strcmp(arg[iarg+1], "none") == 0){ + if (!roll_set) roll = ROLL_NONE; + else if (roll != ROLL_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); + iarg += 2; + } + else{ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); + if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (!roll_set) roll = ROLL_NOHISTORY; + else if (roll != ROLL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "sds") == 0){ + if (!roll_set) roll = ROLL_SDS; + else if (roll != ROLL_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); + roll_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); + } + roll_set =1 ; + roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. + iarg += 5; + } + } + else if (strcmp(arg[iarg], "twisting") == 0){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); + if (strcmp(arg[iarg+1], "none") == 0){ + if (!twist_set) twist = TWIST_NONE; + else if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + iarg += 2; + } + else if (strcmp(arg[iarg+1], "marshall") == 0){ + if (!twist_set) twist = TWIST_MARSHALL; + else if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + twist_history = 1; + twist_set = 1; + iarg += 2; + } + else{ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); + else if (strcmp(arg[iarg+1], "nohistory") == 0){ + if (!twist_set) twist = TWIST_NOHISTORY; + if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + } + else if (strcmp(arg[iarg+1], "sds") == 0){ + if (!twist_set) twist = TWIST_SDS; + else if (twist != TWIST_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); + twist_history = 1; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); + } + twist_set = 1; + twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt + twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + } + else error->all(FLERR, "Illegal pair coeff command"); + } + + //It is an error not to specify normal or tangential model + if (!normal_set) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); + if (!tangential_set) error->all(FLERR, "Illegal pair coeff command, must specify tangential contact model"); + + //If unspecified, set damping to VISCOELASTIC, twist/roll to NONE (cannot be changed by subsequent pair_coeff commands) + if (!damping_set) damping = VISCOELASTIC; + if (!roll_set) roll = ROLL_NONE; + if (!twist_set) twist = TWIST_NONE; + damping_set = roll_set = twist_set = 1; + + int count = 0; + double damp; + if (damping == TSUJI){ + double cor; + cor = normal_coeffs_local[1]; + damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } + else damp = normal_coeffs_local[1]; + + for (int i = ilo; i <= ihi; i++) { + for (int j = MAX(jlo,i); j <= jhi; j++) { + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_local[0]; + normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; + if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; + if ((normal == JKR) || (normal == DMT)) + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_local[3]; + + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_local[k]; + + if (roll != ROLL_NONE) + for (int k = 0; k < 3; k++) + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_local[k]; + + if (twist != TWIST_NONE && twist != TWIST_MARSHALL) + for (int k = 0; k < 3; k++) + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_local[k]; + + setflag[i][j] = 1; + count++; + } + } + + if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +void PairGranular::init_style() +{ + int i; + + // error and warning checks + + if (!atom->radius_flag || !atom->rmass_flag) + error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); + if (comm->ghost_velocity == 0) + error->all(FLERR,"Pair granular requires ghost atoms store velocity"); + + // Determine whether we need a granular neigh list, how large it needs to be + use_history = tangential_history || roll_history || twist_history; + + //For JKR, will need fix/neigh/history to keep track of touch arrays + if (normal == JKR) use_history = 1; + + size_history = 3*tangential_history + 3*roll_history + twist_history; + + //Determine location of tangential/roll/twist histories in array + if (roll_history){ + if (tangential_history) roll_history_index = 3; + else roll_history_index = 0; + } + if (twist_history){ + if (tangential_history){ + if (roll_history) twist_history_index = 6; + else twist_history_index = 3; + } + else{ + if (roll_history) twist_history_index = 3; + else twist_history_index = 0; + } + } + + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->size = 1; + if (use_history) neighbor->requests[irequest]->history = 1; + + dt = update->dt; + + // if history is stored: + // if first init, create Fix needed for storing history + + if (use_history && fix_history == NULL) { + char dnumstr[16]; + sprintf(dnumstr,"%d",size_history); + char **fixarg = new char*[4]; + fixarg[0] = (char *) "NEIGH_HISTORY"; + fixarg[1] = (char *) "all"; + fixarg[2] = (char *) "NEIGH_HISTORY"; + fixarg[3] = dnumstr; + modify->add_fix(4,fixarg,1); + delete [] fixarg; + fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; + fix_history->pair = this; + } + + // check for FixFreeze and set freeze_group_bit + + for (i = 0; i < modify->nfix; i++) + if (strcmp(modify->fix[i]->style,"freeze") == 0) break; + if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; + else freeze_group_bit = 0; + + // check for FixRigid so can extract rigid body masses + + fix_rigid = NULL; + for (i = 0; i < modify->nfix; i++) + if (modify->fix[i]->rigid_flag) break; + if (i < modify->nfix) fix_rigid = modify->fix[i]; + + // check for FixPour and FixDeposit so can extract particle radii + + int ipour; + for (ipour = 0; ipour < modify->nfix; ipour++) + if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; + if (ipour == modify->nfix) ipour = -1; + + int idep; + for (idep = 0; idep < modify->nfix; idep++) + if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; + if (idep == modify->nfix) idep = -1; + + // set maxrad_dynamic and maxrad_frozen for each type + // include future FixPour and FixDeposit particles as dynamic + + int itype; + for (i = 1; i <= atom->ntypes; i++) { + onerad_dynamic[i] = onerad_frozen[i] = 0.0; + if (ipour >= 0) { + itype = i; + double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); + if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); + onerad_dynamic[i] = radmax; + } + if (idep >= 0) { + itype = i; + double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); + if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); + onerad_dynamic[i] = radmax; + } + } + + double *radius = atom->radius; + int *mask = atom->mask; + int *type = atom->type; + int nlocal = atom->nlocal; + + for (i = 0; i < nlocal; i++){ + double radius_cut = radius[i]; + if (normal == JKR){ + radius_cut = radius[i] - 0.5*pulloff_distance(radius[i], type[i]); + } + if (mask[i] & freeze_group_bit){ + onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); + } + else{ + onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius_cut); + } + } + + MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, + MPI_DOUBLE,MPI_MAX,world); + + // set fix which stores history info + + if (size_history > 0){ + int ifix = modify->find_fix("NEIGH_HISTORY"); + if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); + fix_history = (FixNeighHistory *) modify->fix[ifix]; + } +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ + +double PairGranular::init_one(int i, int j) +{ + double cutoff; + if (setflag[i][j] == 0) { + + if (normal != HOOKE && normal != HERTZ){ + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][i][2], normal_coeffs[j][j][2]); + normal_coeffs[i][j][2] = normal_coeffs[j][i][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], + normal_coeffs[i][i][2], normal_coeffs[j][j][2]); + } + else{ + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); + } + + normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); + if ((normal == JKR) || (normal == DMT)) + normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); + + for (int k = 0; k < 3; k++) + tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); + + + if (roll != ROLL_NONE){ + for (int k = 0; k < 3; k++) + roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); + } + + if (twist != TWIST_NONE && twist != TWIST_MARSHALL){ + for (int k = 0; k < 3; k++) + twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); + } + } + + // It is possible that cut[i][j] at this point is still 0.0. This can happen when + // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates + // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size + // To avoid this issue, for cases involving cut[i][j] = 0.0 (possible only + // if there is no current information about radius/cutoff of type i and j). + // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. + + if (cutoff_global < 0){ + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); + } + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; + } + } + else{ + cutoff = cutoff_global; + } + return cutoff; +} + + +/* ---------------------------------------------------------------------- + proc 0 writes to restart file + ------------------------------------------------------------------------- */ + +void PairGranular::write_restart(FILE *fp) +{ + int i,j; + fwrite(&normal,sizeof(int),1,fp); + fwrite(&damping,sizeof(int),1,fp); + fwrite(&tangential,sizeof(int),1,fp); + fwrite(&roll,sizeof(int),1,fp); + fwrite(&twist,sizeof(int),1,fp); + 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(&normal_coeffs[i][j],sizeof(double),4,fp); + fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); + fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); + fwrite(&twist_coeffs[i][j],sizeof(double),3,fp); + fwrite(&cut[i][j],sizeof(double),1,fp); + } + } + } +} + +/* ---------------------------------------------------------------------- + proc 0 reads from restart file, bcasts + ------------------------------------------------------------------------- */ + +void PairGranular::read_restart(FILE *fp) +{ + allocate(); + int i,j; + int me = comm->me; + if (me == 0){ + fread(&normal,sizeof(int),1,fp); + fread(&damping,sizeof(int),1,fp); + fread(&tangential,sizeof(int),1,fp); + fread(&roll,sizeof(int),1,fp); + fread(&twist,sizeof(int),1,fp); + } + MPI_Bcast(&normal,1,MPI_INT,0,world); + MPI_Bcast(&damping,1,MPI_INT,0,world); + MPI_Bcast(&tangential,1,MPI_INT,0,world); + MPI_Bcast(&roll,1,MPI_INT,0,world); + MPI_Bcast(&twist,1,MPI_INT,0,world); + 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(&normal_coeffs[i][j],sizeof(double),4,fp); + fread(&tangential_coeffs[i][j],sizeof(double),3,fp); + fread(&roll_coeffs[i][j],sizeof(double),3,fp); + fread(&twist_coeffs[i][j],sizeof(double),3,fp); + fread(&cut[i][j],sizeof(double),1,fp); + } + MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); + MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&twist_coeffs[i][j],3,MPI_DOUBLE,0,world); + MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); + } + } + } +} + + +/* ---------------------------------------------------------------------- */ + +void PairGranular::reset_dt() +{ + dt = update->dt; +} + +/* ---------------------------------------------------------------------- */ + +double PairGranular::single(int i, int j, int itype, int jtype, + double rsq, double factor_coul, double factor_lj, double &fforce) +{ + double radi,radj,radsum; + double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; + double dR, dR2; + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + double mi,mj,meff,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + double knfac, damp_normal; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; + + //For JKR + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double delta, t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; + + + //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + + //Twisting + double k_twist, damp_twist, mu_twist; + double signtwist, magtwist, magtortwist, Mtcrit; + double tortwist1, tortwist2, tortwist3; + + double shrmag,rsht; + int jnum; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *history,*allhistory,**firsthistory; + + double *radius = atom->radius; + radi = radius[i]; + radj = radius[j]; + radsum = radi + radj; + Reff = radi*radj/(radi+radj); + + bool touchflag; + if (normal == JKR){ + R2 = Reff*Reff; + coh = normal_coeffs[itype][jtype][3]; + a = cbrt(9.0*M_PI*coh*R2/(4*E)); + delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); + dist_pulloff = radsum+delta_pulloff; + touchflag = (rsq <= dist_pulloff*dist_pulloff); + } + else{ + touchflag = (rsq <= radsum*radsum); + } + + if (touchflag){ + fforce = 0.0; + for (int m = 0; m < single_extra; m++) svector[m] = 0.0; + return 0.0; + } + + double **x = atom->x; + delx = x[i][0] - x[j][0]; + dely = x[i][1] - x[j][1]; + delz = x[i][2] - x[j][2]; + r = sqrt(rsq); + rinv = 1.0/r; + + nx = delx*rinv; + ny = dely*rinv; + nz = delz*rinv; + + // relative translational velocity + + double **v = atom->v; + 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*nx + vr2*ny + vr3*nz; + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + double *rmass = atom->rmass; + int *mask = atom->mask; + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + + // tangential component + + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + + double **omega = atom->omega; + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // meff = effective mass of pair of particles + // if I or J part of rigid body, use body mass + // if I or J is frozen, meff is other particle + + int *type = atom->type; + + mi = rmass[i]; + mj = rmass[j]; + if (fix_rigid) { + // NOTE: ensure mass_rigid is current for owned+ghost atoms? + if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; + if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; + } + + meff = mi*mj / (mi+mj); + if (mask[i] & freeze_group_bit) meff = mj; + if (mask[j] & freeze_group_bit) meff = mi; + + delta = radsum - r; + dR = delta*Reff; + if (normal == JKR){ + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = FOURTHIRDS*E*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + else{ + knfac = E; + Fne = knfac*delta; + if (normal != HOOKE) + a = sqrt(dR); + Fne *= a; + if (normal == DMT) + Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; + } + + //Consider restricting Hooke to only have 'velocity' as an option for damping? + if (damping == VELOCITY){ + damp_normal = normal_coeffs[itype][jtype][1]; + } + else if (damping == VISCOELASTIC){ + if (normal == HOOKE) a = sqrt(dR); + damp_normal = normal_coeffs[itype][jtype][1]*a*meff; + } + else if (damping == TSUJI){ + damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); + } + + Fdamp = -damp_normal*vnnr; + + Fntot = Fne + Fdamp; + + jnum = list->numneigh[i]; + jlist = list->firstneigh[i]; + + if (use_history){ + allhistory = fix_history->firstvalue[i]; + for (int jj = 0; jj < jnum; jj++) { + neighprev++; + if (neighprev >= jnum) neighprev = 0; + if (jlist[neighprev] == j) break; + } + history = &allhistory[size_history*neighprev]; + } + + //**************************************** + //Tangential force, including history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + wr1 = (radi*omega[i][0] + radj*omega[j][0]); + wr2 = (radi*omega[i][1] + radj*omega[j][1]); + wr3 = (radi*omega[i][2] + radj*omega[j][2]); + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + Fcrit = fabs(Fne); + if (normal == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fcrit = fabs(Fne + 2*F_pulloff); + } + + //------------------------------ + //Tangential forces + //------------------------------ + k_tangential = tangential_coeffs[itype][jtype][0]; + if (normal != HOOKE){ + k_tangential *= a; + } + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + + if (tangential_history){ + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + + // tangential forces = history + tangential velocity damping + fs1 = -k_tangential*history[0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[2] - damp_tangential*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; + } + + //**************************************** + // Rolling resistance + //**************************************** + + if (roll != ROLL_NONE){ + relrot1 = omega[i][0] - omega[j][0]; + relrot2 = omega[i][1] - omega[j][1]; + relrot3 = omega[i][2] - omega[j][2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + if (roll_history){ + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + else{ // + fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; + if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; + else fr = 0.0; + fr1 = -fr*vrl1; + fr2 = -fr*vrl2; + fr3 = -fr*vrl3; + } + } + + //**************************************** + // Twisting torque, including history effects + //**************************************** + if (twist != TWIST_NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (twist == TWIST_MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a; + } + else{ + k_twist = twist_coeffs[itype][jtype][0]; + damp_twist = twist_coeffs[itype][jtype][1]; + mu_twist = twist_coeffs[itype][jtype][2]; + } + if (twist_history){ + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + else{ + if (magtwist > 0) magtortwist = -damp_twist*magtwist; + else magtortwist = 0; + } + } + + // set single_extra quantities + + svector[0] = fs1; + svector[1] = fs2; + svector[2] = fs3; + svector[3] = fs; + svector[4] = fr1; + svector[5] = fr2; + svector[6] = fr3; + svector[7] = fr; + svector[8] = magtortwist; + return 0.0; +} + +/* ---------------------------------------------------------------------- */ + +int PairGranular::pack_forward_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++] = mass_rigid[j]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void PairGranular::unpack_forward_comm(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + mass_rigid[i] = buf[m++]; +} + +/* ---------------------------------------------------------------------- + memory usage of local atom-based arrays + ------------------------------------------------------------------------- */ + +double PairGranular::memory_usage() +{ + double bytes = nmax * sizeof(double); + return bytes; +} + +/* ---------------------------------------------------------------------- + mixing of Young's modulus (E) +------------------------------------------------------------------------- */ + +double PairGranular::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); +} + +/* ---------------------------------------------------------------------- + mixing of shear modulus (G) + ------------------------------------------------------------------------- */ + +double PairGranular::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) +{ + double poisii = Eii/(2.0*Gii) - 1.0; + double poisjj = Ejj/(2.0*Gjj) - 1.0; + return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); +} + +/* ---------------------------------------------------------------------- + mixing of everything else +------------------------------------------------------------------------- */ + +double PairGranular::mix_geom(double valii, double valjj) +{ + return sqrt(valii*valjj); +} + + +/* ---------------------------------------------------------------------- + Compute pull-off distance (beyond contact) for a given radius and atom type +------------------------------------------------------------------------- */ + +double PairGranular::pulloff_distance(double radius, int itype) +{ + double E, coh, a, delta_pulloff; + coh = normal_coeffs[itype][itype][3]; + E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], + normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); + a = cbrt(9*M_PI*coh*radius*radius/(4*E)); + return a*a/radius - 2*sqrt(M_PI*coh*a/E); +} + diff --git a/src/pair_granular.h b/src/pair_granular.h new file mode 100644 index 0000000000..f39f31e4cb --- /dev/null +++ b/src/pair_granular.h @@ -0,0 +1,120 @@ +/* ---------------------------------------------------------- + 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(granular,PairGranular) + +#else + +#ifndef LMP_PAIR_GRANULAR_H +#define LMP_PAIR_GRANULAR_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairGranular : public Pair { +public: + PairGranular(class LAMMPS *); + virtual ~PairGranular(); + + void compute(int, int); + // comment next line to turn off templating +#define TEMPLATED_PAIR_GRANULAR +#ifdef TEMPLATED_PAIR_GRANULAR + template < int Tp_normal, int Tp_damping, int Tp_tangential, + int Tp_roll, int Tp_twist> + void compute_templated(int, int); +#else + void compute_untemplated(int, int, int, int, int, + int, int); +#endif + + virtual void settings(int, char **); + virtual void coeff(int, char **); + void init_style(); + double init_one(int, int); + void write_restart(FILE *); + void read_restart(FILE *); + void reset_dt(); + virtual double single(int, int, int, int, double, double, double, double &); + int pack_forward_comm(int, int *, double *, int, int *); + void unpack_forward_comm(int, int, double *); + double memory_usage(); + + protected: + double cut_global; + double dt; + int freeze_group_bit; + int use_history; + + int neighprev; + double *onerad_dynamic,*onerad_frozen; + double *maxrad_dynamic,*maxrad_frozen; + double **cut; + + class FixNeighHistory *fix_history; + + // storage of rigid body masses for use in granular interactions + + class Fix *fix_rigid; // ptr to rigid body fix, NULL if none + double *mass_rigid; // rigid mass for owned+ghost atoms + int nmax; // allocated size of mass_rigid + + virtual void allocate(); + +private: + int size_history; + + //Models + int normal, damping, tangential, roll, twist; + + //History flags + int tangential_history, roll_history, twist_history; + + //Indices of history entries + int tangential_history_index, roll_history_index, twist_history_index; + + //Flags for whether model choices have been set + int normal_set, tangential_set, damping_set, roll_set, twist_set; + + //Per-type coefficients, set in pair coeff command + double ***normal_coeffs; + double ***tangential_coeffs; + double ***roll_coeffs; + double ***twist_coeffs; + + //Optional user-specified global cutoff + double cutoff_global; + + double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); + double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); + double mix_geom(double valii, double valjj); + double pulloff_distance(double radius, int itype); +}; + +} + +#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. + + */ -- GitLab From e7c1ca1fca7ac8b91c9ce4fc3b1036f2eca0b3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 12 Feb 2019 08:07:28 +0100 Subject: [PATCH 0118/1243] Revert changes --- python/install.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/python/install.py b/python/install.py index 5a97b6106d..feb6527352 100644 --- a/python/install.py +++ b/python/install.py @@ -22,11 +22,6 @@ else: pydir = "" # copy lammps.py to pydir if it exists # if pydir not specified, install in site-packages via distutils setup() -if 'liblammps.dylib' in os.listdir('../src/'): - lib_ext = ".dylib" -else: - lib_ext = ".so" - if pydir: if not os.path.isdir(pydir): print( "ERROR: pydir %s does not exist" % pydir) @@ -41,7 +36,7 @@ if pydir: str = "cp ../src/liblammps.so %s" % pydir print(str) try: - shutil.copyfile("../src/liblammps" + lib_ext, os.path.join(pydir,"liblammps" + lib_ext) ) + shutil.copyfile("../src/liblammps.so", os.path.join(pydir,"liblammps.so") ) except shutil.Error: pass # source and destination are identical sys.exit() @@ -70,7 +65,7 @@ try: url = "http://lammps.sandia.gov", description = "LAMMPS molecular dynamics library", py_modules = ["lammps"], - data_files = [(get_python_lib(), ["../src/liblammps" + lib_ext])]) + data_files = [(get_python_lib(), ["../src/liblammps.so"])]) except: tryuser=True print ("Installation into global site-packages dir failed.\nTrying user site dir %s now." % site.USER_SITE) @@ -86,9 +81,8 @@ if tryuser: url = "http://lammps.sandia.gov", description = "LAMMPS molecular dynamics library", py_modules = ["lammps"], - data_files = [(site.USER_SITE, ["../src/liblammps" + lib_ext])]) + data_files = [(site.USER_SITE, ["../src/liblammps.so"])]) except: print("Installation into user site package dir failed.\nGo to ../python and install manually.") - -- GitLab From f5e3c538802d4504b074d46c4da142724f1842c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 12 Feb 2019 08:08:22 +0100 Subject: [PATCH 0119/1243] Update install.py --- python/install.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/install.py b/python/install.py index feb6527352..9308506fd2 100644 --- a/python/install.py +++ b/python/install.py @@ -86,3 +86,4 @@ if tryuser: print("Installation into user site package dir failed.\nGo to ../python and install manually.") + -- GitLab From e582c0d4e5eec1b5e22954e3249719e69827deb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Jan=C3=9Fen?= Date: Tue, 12 Feb 2019 08:20:54 +0100 Subject: [PATCH 0120/1243] Update lammps.py --- python/lammps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/lammps.py b/python/lammps.py index c5c7dca33d..9b3790f2db 100644 --- a/python/lammps.py +++ b/python/lammps.py @@ -85,7 +85,7 @@ class lammps(object): # fall back to loading with a relative path, # typically requires LD_LIBRARY_PATH to be set appropriately - if 'liblammps.dylib' in os.listdir(modpath): + if any([f.startswith('liblammps') and f.endswith('.dylib') for f in os.listdir(modpath)]): lib_ext = ".dylib" else: lib_ext = ".so" -- GitLab From 6ff1557af8c03becc5615ccebcd41334a0cf082b Mon Sep 17 00:00:00 2001 From: dsbolin Date: Tue, 12 Feb 2019 07:42:26 -0700 Subject: [PATCH 0121/1243] More progress on doc page --- doc/src/pair_granular.txt | 101 +++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 8bf4f20d5d..d6b18217d8 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -14,7 +14,6 @@ :line pair_style granular command :h3 -pair_style granular/multi command :h3 [Syntax:] @@ -33,7 +32,7 @@ pair_style granular pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall pair_coeff 2 2 hertz 200.0 20.0 tangential mindlin 300.0 50.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre -pair_style granular/multi +pair_style granular pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall pair_coeff 2 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall pair_coeff 1 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre @@ -44,24 +43,17 @@ pair_coeff 1 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll The {granular} styles support a variety of options for the normal, tangential, rolling and twisting forces resulting from contact between two granular particles. This expands on the options offered by the "pair gran/*"_pair_gran.html options. The total computed forces and torques depend on the combination -of choices for these various modes of motion. +of models selected for these various modes of motion. All model options and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. Unlike e.g. "pair gran/hooke"_pair_gran.html, coefficient values are not global, but can be set to different values for various combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. -For {pair_style granular}, coefficients can vary between particle types, but model choices -cannot. For instance, in the first -example above, the stiffness, damping, and tangential friction are different for -type 1 - type 1 and type 2 - type 2 interactions, but -both 1-1 and 2-2 interactions must have the same model form, hence all keywords are -identical between the two types. Cross-coefficients -for 1-2 interactions for the case of the {hertz} model above are set via simple -geometric mixing rules. The {granular/multi} -style removes this restriction at a small cost in computational efficiency, so that different particle types -can potentially interact via different model forms. As shown in the second example, -1-1 interactions are based on a Hertzian contact model and 2-2 interactions are based on a {dmt} model (see below). -In the case that 1-1 and 2-2 interactions have different model forms, mixing of coefficients cannot be -determined, so 1-2 interactions must be explicitly defined via the pair coeff command, otherwise an error results. +For {pair_style granular}, coefficients as well as model options can vary between particle types. +As shown in the second example, +type 1- type 1 interactions are based on a Hertzian normal contact model and 2-2 interactions are based on a {dmt} model (see below). +In that example, 1-1 and 2-2 interactions have different model forms, in which case +mixing of coefficients cannot be determined, so 1-2 interactions must be explicitly defined via the +pair coeff command, otherwise an error would result. :line @@ -70,12 +62,13 @@ for normal contact models and their required arguments are: {hooke} : \(k_n\), damping {hertz} : \(k_n\), damping -{hertz/material} : E, damping, G -{dmt} : E, damping, G, cohesion -{jkr} : E, damping, G, cohesion :ol +{hertz/material} : E, damping, \(\nu\) +{dmt} : E, damping, \(\nu\), cohesion +{jkr} : E, damping, \(\nu\), cohesion :ol -Here, \(k_n\) is spring stiffness, damping is a damping constant or a coefficient of restitution, depending on -the choice of damping model (see below), E and G are Young's modulus and shear modulus, in units of pressure, +Here, \(k_n\) is spring stiffness (with units that depend on model choice, see below); +damping is a damping constant or a coefficient of restitution, depending on +the choice of damping model; E is Young's modulus in units of force/length^2; \(\nu\) is Poisson's ratio and cohesion is a surface energy density, in units of energy/length^2. For the {hooke} model, the normal (elastic) component of force between two particles {i} and {j} is given by: @@ -88,6 +81,8 @@ Where \(\delta = R_i + R_j - \|\mathbf\{r\}_\{ij\}\|\) is the particle overlap, \(\mathbf\{r\}_\{ij\} = \mathbf\{r\}_j - \mathbf\{r\}_i\) is the vector separating the two particle centers and \(\mathbf\{n\} = \frac\{\mathbf\{r\}_\{ij\}\}\{\|\mathbf\{r\}_\{ij\}\|\}\). +Therefore, for {hooke}, the units of the spring constant \(k_n\) are {force}/{distance}, +or equivalently {mass}/{time^2}. For the {hertz} model, the normal component of force is given by: \begin\{equation\} @@ -95,6 +90,8 @@ For the {hertz} model, the normal component of force is given by: \end\{equation\} Here, \(R_\{eff\} = \frac\{R_i R_j\}\{R_i + R_j\}\) is the effective radius, denoted for simplicity as {R} from here on. +For {hertz}, the units of the spring constant \(k_n\) are {force}/{distance}^2, or equivalently +{pressure}. For the {hertz/material} model, the force is given by: \begin\{equation\} @@ -102,9 +99,9 @@ For the {hertz/material} model, the force is given by: \end\{equation\} Here, \(E_\{eff\} = E = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\}\) -is the effectve Young's modulus, -with \(\nu_i, \nu_j \) the Poisson ratios of the particles, which are related to the -input shear and Young's moduli by \(\nu_i = E_i/2G_i - 1\). Thus, if the elastic and shear moduli of the +is the effective Young's modulus, +with \(\nu_i, \nu_j \) the Poisson ratios of the particles of types {i} and {j}. Note that + if the elastic and shear moduli of the two particles are the same, the {hertz/material} model is equivalent to the {hertz} model with \(k_N = 4/3 E_\{eff\}\) @@ -127,12 +124,12 @@ Here, {a} is the radius of the contact zone, related to the overlap \(\delta\) a LAMMPS internally inverts the equation above to solve for {a} in terms of \(\delta\), then solves for the force in the previous equation. Additionally, note that the JKR model allows for a tensile force beyond -contact (i.e. for \(\delta < 0\)), up to a maximum tensile force of \(-3\pi\gamma R\) (also known as +contact (i.e. for \(\delta < 0\)), up to a maximum of \(3\pi\gamma R\) (also known as the 'pull-off' force). Note that this is a hysteretic effect, where particles that are not contacting initially will not experience force until they come into contact \(\delta \geq 0\); as they move apart -and (\(\delta < 0\)), they experience a tensile force up to \(-3\pi\gamma R\), -at which point they will lose contact. +and (\(\delta < 0\)), they experience a tensile force up to \(3\pi\gamma R\), +at which point they lose contact. In addition to the above options, the normal force is augmented by a damping term. The optional {damping} keyword to the {pair_coeff} command followed by the model choice determines the form of the damping. @@ -167,7 +164,19 @@ Here, \(m_\{eff\} = m_i m_j/(m_i + m_j)\) is the effective mass, {a} is the cont for all models except {jkr}, for which it is given implicitly according to \(delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\). In this case, \(\gamma_N\) is the damping coefficient, in units of 1/({time}*{distance}). -The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the +The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the +damping term is given by: +\begin\{equation\} +F_\{N,damp\} = -\alpha (m_\{eff\}k_N)^\{l/2\} \mathbf\{v\}_\{N,rel\} +\end\{equation\} + +For normal contact models based on material parameters, \(k_N = 4/3Ea\). +The parameter \(\alpha\) is related to the restitution coefficient {e} according to: +\begin{equation} +\alpha = 1.2728-4.2783e+11.087e^2-22.348e^3+27.467e^4-18.022e^5+4.8218e^6 +\end{equation} + +For further details, see "(Tsuji et al)"_#Tsuji1992. :line @@ -175,13 +184,13 @@ Following the normal contact model settings, the {pair_coeff} command requires s of the tangential contact model. The required keyword {tangential} is expected, followed by the model choice and associated parameters. Currently supported tangential model choices and their expected parameters are as follows: -{nohistory} : \(\gamma_t\), \(\mu_s\) -{history} : \(k_t\), \(\gamma_t\), \(\mu_s\) :ol +{linear_nohistory} : \(\gamma_t\), \(\mu_s\) +{linear_history} : \(k_t\), \(\gamma_t\), \(\mu_s\) :ol Here, \(\gamma_t\) is the tangential damping coefficient, \(\mu_s\) is the tangential (or sliding) friction -coefficient, and \(k_t\) is the tangential stiffness. +coefficient, and \(k_t\) is the tangential stiffness coefficient. -For {nohistory}, a simple velocity-dependent Coulomb friction criterion is used, which reproduces the behavior +For {linear_nohistory}, a simple velocity-dependent Coulomb friction criterion is used, which reproduces the behavior of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: \begin\{equation\} @@ -190,7 +199,33 @@ of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given Where \(\|\mathbf\{F\}_n\) is the magnitude of the normal force, \(\mathbf\{v\}_\{t, rel\} = \mathbf\{v\}_\{t\} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf\{n\}\) is the relative tangential -velocity at the point of contact, \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_n - \) +velocity at the point of contact, \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_R - \mathbf\{v\}_R\cdot\mathbf\{n\}\), +\(\mathbf\{v\}_R = \mathbf\{v\}_i - \mathbf\{v\}_j. + +For {linear_history}, the total tangential displacement \(\mathbf\{\xi\}\) is accumulated during the entire +duration of the contact: + +\begin\{equation\} +\mathbf\{\xi\} = \int_\{t0\}^t \mathbf\{v\}_\{t,rel\}(\tau) \mathrm\{d\}\tau +\end\{equation\} + +The tangential displacement must in the frame of reference of the contacting pair of particles, + +\begin\{equation\} +\mathbf\{\xi\} = \mathbf\{\xi'\} - \mathbf\{n\}(\mathbf\{n\} \cdot \mathbf\{\xi'\}) +\end\{equation\} + +\noindent Since the goal here is a `rotation', the equation above should be accompanied by a rescaling, so that at each step, +the displacement is first rotated into the current frame of reference $\mathbf\{\xi\}$, then updated: + +\begin\{equation\} +\mathbf\{\xi\} = \left(\mathbf\{\xi'\} - (\mathbf\{n\} \cdot \mathbf\{\xi'\})\mathbf\{n\}\right) \frac\{\|\mathbf\{\xi'\}\|\}\{\|\mathbf\{\xi'\}\| - \mathbf\{n\}\cdot\mathbf\{\xi'\}\} +\label\{eq:rotate_displacements\} +\end\{equation\} + + +a simple velocity-dependent Coulomb friction criterion is used, which reproduces the behavior +of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: :link(Brill1996) -- GitLab From 88b62fa6bdf80f1b3ed5db4d807fadfc376f2742 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 13 Feb 2019 12:43:35 -0500 Subject: [PATCH 0122/1243] add old style PDF build to "make old" target. this will create the old style Manual.pdf in the old folder and put Developer.pdf there, too. --- doc/Makefile | 14 +++++++++++++- doc/src/lammps.book | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index a38186666a..044e358bd5 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -39,7 +39,7 @@ help: @echo "Please use \`make ' where is one of" @echo " html create HTML doc pages in html dir" @echo " pdf create Developer.pdf and Manual.pdf in this dir" - @echo " old create old-style HTML doc pages in old dir" + @echo " old create old-style HTML doc pages and Manual.pdf in old dir" @echo " fetch fetch HTML and PDF files from LAMMPS web site" @echo " epub create ePUB format manual for e-book readers" @echo " mobi convert ePUB to MOBI format manual for e-book readers (e.g. Kindle)" @@ -162,6 +162,18 @@ old: utils/txt2html/txt2html.exe cp Eqs/*.jpg ../old/Eqs; \ cp JPG/* ../old/JPG; \ cp PDF/* ../old/PDF; + @( set -e;\ + cd src/Developer; \ + pdflatex developer; \ + pdflatex developer; \ + mv developer.pdf ../../old/Developer.pdf; \ + cd ../../old; \ + for s in `echo ../src/*.txt | sed -e 's,\.\./src/,,g' -e 's/ \(pairs\|bonds\|angles\|dihedrals\|impropers\|commands_list\|fixes\|computes\).txt/ /g' | sed -e 's,\.txt,\.html,g'` ; \ + do grep -q ^$$s ../src/lammps.book || \ + echo WARNING: doc file $$s missing in src/lammps.book; done; \ + htmldoc --batch ../src/lammps.book; \ + ) + fetch: @rm -rf html_www Manual_www.pdf Developer_www.pdf diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 02a55e3810..4c24719870 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -1,5 +1,5 @@ #HTMLDOC 1.8.28 --t pdf14 -f "../Manual.pdf" --book --toclevels 4 --no-numbered --toctitle "Table of Contents" --title --textcolor #000000 --linkcolor #0000ff --linkstyle plain --bodycolor #ffffff --size Universal --left 1.00in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --header1 ... --footer ..1 --nup 1 --tocheader .t. --tocfooter ..i --portrait --color --no-pscommands --no-xrxcomments --compression=9 --jpeg=0 --fontsize 11.0 --fontspacing 1.2 --headingfont Sans --bodyfont Serif --headfootsize 11.0 --headfootfont Sans-Bold --charset iso-8859-15 --links --embedfonts --pagemode document --pagelayout single --firstpage c1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password "" --user-password "" --browserwidth 680 --no-strict --no-overflow +-t pdf14 -f "Manual.pdf" --book --toclevels 4 --no-numbered --toctitle "Table of Contents" --title --textcolor #000000 --linkcolor #0000ff --linkstyle plain --bodycolor #ffffff --size Universal --left 1.00in --right 0.50in --top 0.50in --bottom 0.50in --header .t. --header1 ... --footer ..1 --nup 1 --tocheader .t. --tocfooter ..i --portrait --color --no-pscommands --no-xrxcomments --compression=9 --jpeg=0 --fontsize 11.0 --fontspacing 1.2 --headingfont Sans --bodyfont Serif --headfootsize 11.0 --headfootfont Sans-Bold --charset iso-8859-15 --links --embedfonts --pagemode document --pagelayout single --firstpage c1 --pageeffect none --pageduration 10 --effectduration 1.0 --no-encryption --permissions all --owner-password "" --user-password "" --browserwidth 680 --no-strict --no-overflow Manual.html Intro.html Intro_overview.html -- GitLab From 01088559308210647ef8a604f8cd023c64e3f663 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 14 Feb 2019 02:54:02 -0500 Subject: [PATCH 0123/1243] update .gitignore for the doc folder --- doc/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/.gitignore b/doc/.gitignore index 920c5b9830..88679898a8 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,4 @@ -/latex +/old /html /latex /spelling -- GitLab From b3a7a534a99b85c97b863f46c13684bf1422fbf2 Mon Sep 17 00:00:00 2001 From: Donatas Surblys Date: Thu, 14 Feb 2019 18:54:59 +0900 Subject: [PATCH 0124/1243] make fix langevin correctly account for energy with 'zero yes' --- src/fix_langevin.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp index d829982274..d49ad61371 100644 --- a/src/fix_langevin.cpp +++ b/src/fix_langevin.cpp @@ -605,6 +605,11 @@ void FixLangevin::post_force_untemplated f[i][0] -= fsumall[0]; f[i][1] -= fsumall[1]; f[i][2] -= fsumall[2]; + if (Tp_TALLY) { + flangevin[i][0] -= fsumall[0]; + flangevin[i][1] -= fsumall[1]; + flangevin[i][2] -= fsumall[2]; + } } } } -- GitLab From 8020f5b9650f078c8aad2ec0c83cf67a02bd0901 Mon Sep 17 00:00:00 2001 From: Donatas Surblys Date: Thu, 14 Feb 2019 18:54:59 +0900 Subject: [PATCH 0125/1243] remove warning messages when using 'tally yes zero yes' with fix langevin --- src/fix_langevin.cpp | 2 -- src/fix_langevin.h | 6 ------ 2 files changed, 8 deletions(-) diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp index d49ad61371..36ea47daf6 100644 --- a/src/fix_langevin.cpp +++ b/src/fix_langevin.cpp @@ -177,8 +177,6 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) : } } - if (tallyflag && zeroflag && comm->me == 0) - error->warning(FLERR,"Energy tally does not account for 'zero yes'"); } /* ---------------------------------------------------------------------- */ diff --git a/src/fix_langevin.h b/src/fix_langevin.h index 2883ac9ea2..024e7a9539 100644 --- a/src/fix_langevin.h +++ b/src/fix_langevin.h @@ -104,12 +104,6 @@ E: Fix langevin period must be > 0.0 The time window for temperature relaxation must be > 0 -W: Energy tally does not account for 'zero yes' - -The energy removed by using the 'zero yes' flag is not accounted -for in the energy tally and thus energy conservation cannot be -monitored in this case. - E: Fix langevin omega requires atom style sphere Self-explanatory. -- GitLab From d0ed6f2bf54354cbaf8ee6e915542b51eb272fb3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 14 Feb 2019 05:45:52 -0500 Subject: [PATCH 0126/1243] reflect changes to fix langevin also in the manual --- doc/src/Errors_warnings.txt | 6 ------ doc/src/fix_langevin.txt | 4 ---- 2 files changed, 10 deletions(-) diff --git a/doc/src/Errors_warnings.txt b/doc/src/Errors_warnings.txt index 079688c639..47dd597af8 100644 --- a/doc/src/Errors_warnings.txt +++ b/doc/src/Errors_warnings.txt @@ -178,12 +178,6 @@ When using fixes like box/relax, the potential energy used by the minimizer is augmented by an additional energy provided by the fix. Thus the printed converged energy may be different from the total potential energy. :dd -{Energy tally does not account for 'zero yes'} :dt - -The energy removed by using the 'zero yes' flag is not accounted -for in the energy tally and thus energy conservation cannot be -monitored in this case. :dd - {Estimated error in splitting of dispersion coeffs is %g} :dt Error is greater than 0.0001 percent. :dd diff --git a/doc/src/fix_langevin.txt b/doc/src/fix_langevin.txt index 85c97a3436..861eed4a6f 100644 --- a/doc/src/fix_langevin.txt +++ b/doc/src/fix_langevin.txt @@ -217,10 +217,6 @@ the particles. As described below, this energy can then be printed out or added to the potential energy of the system to monitor energy conservation. -NOTE: this accumulated energy does NOT include kinetic energy removed -by the {zero} flag. LAMMPS will print a warning when both options are -active. - The keyword {zero} can be used to eliminate drift due to the thermostat. Because the random forces on different atoms are independent, they do not sum exactly to zero. As a result, this fix -- GitLab From e95cf4e9176ca92b769e250e2c02f069a8b790d3 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Thu, 14 Feb 2019 13:38:28 -0600 Subject: [PATCH 0127/1243] Some various doc updates for kim-api support --- cmake/Modules/FindKIM-API-V2.cmake | 5 ----- doc/src/pair_kim.txt | 6 +++--- lib/kim/README | 16 ++++++++-------- src/KIM/pair_kim.cpp | 2 +- src/KIM/pair_kim.h | 2 +- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/cmake/Modules/FindKIM-API-V2.cmake b/cmake/Modules/FindKIM-API-V2.cmake index 0cc947e139..6ca6e068df 100644 --- a/cmake/Modules/FindKIM-API-V2.cmake +++ b/cmake/Modules/FindKIM-API-V2.cmake @@ -28,11 +28,6 @@ # Ryan S. Elliott # -# -# Release: This file is part of the kim-api.git repository. -# - - # - Find KIM-API-V2 # # sets standard pkg_check_modules variables plus: diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index 0c05913117..67ab0b6c07 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -48,8 +48,8 @@ building LAMMPS. See the examples/kim dir for an input script that uses a KIM model (potential) for Lennard-Jones. Note, for this example input script, the example models -shipped with with kim-api package must be installed. See the "Making -LAMMPS"_Section_start.html#start_3 section and the ./lib/kim/README for details +shipped with with kim-api package must be installed. See the "Build +package"_Build_package.html section and the ./lib/kim/README for details on how to build LAMMSPS with the kim-api and how to install the example models. :line @@ -115,7 +115,7 @@ LAMMPS was built with that package. See the "Build package"_Build_package.html doc page for more info. This current version of pair_style kim is compatible with the -kim-api package version 2.0.0-beta.2 and higher. +kim-api package version 2.0.0 and higher. [Related commands:] diff --git a/lib/kim/README b/lib/kim/README index 7cf8f9bb7d..0e51a30870 100644 --- a/lib/kim/README +++ b/lib/kim/README @@ -20,17 +20,17 @@ Instructions: 1. Configure lammps for use with the kim-api library installed in this directory # replace X.Y.Z as appropriate here and below -$ printf "${PWD}/installed-kim-api-vX.Y.Z" > ./kim-prefix.txt +$ printf "${PWD}/installed-kim-api-vX-X.Y.Z" > ./kim-prefix.txt 2. Download and unpack the kim-api -$ wget http://s3.openkim.org/kim-api/kim-api-vX.Y.Z.txz -$ tar zxvf kim-api-vX.Y.Z.txz +$ wget http://s3.openkim.org/kim-api/kim-api-vX-X.Y.Z.txz +$ tar zxvf kim-api-vX-X.Y.Z.txz # configure the kim-api -$ cd kim-api-vX.Y.Z +$ cd kim-api-vX-X.Y.Z $ mkdir build && cd build -$ cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../../installed-kim-api-vX.Y.Z +$ cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../../installed-kim-api-vX-X.Y.Z 3. Build and install the kim-api and model @@ -40,13 +40,13 @@ $ make install 4. Remove source and build files $ cd ../../ -$ rm -rf kim-api-vX.Y.Z -$ rm -rf kim-api-vX.Y.Z.txz +$ rm -rf kim-api-vX-X.Y.Z +$ rm -rf kim-api-vX-X.Y.Z.txz 5. To add items do the following (replace the kim item name with your desired value) -$ source ${PWD}/kim-api-vX.Y.Z/bin/kim-api-vX-activate +$ source ${PWD}/kim-api-vX-X.Y.Z/bin/kim-api-vX-activate $ kim-api-vX-collections-management install system Pair_Johnson_Fe__MO_857282754307_002 diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 6981b028b2..a4517b848c 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -50,7 +50,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v2.0.0-beta.2 (and newer) package + Designed for use with the kim-api-v2-2.0.0 (and newer) package ------------------------------------------------------------------------- */ #include diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index a23d5cd317..a6f882347d 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -50,7 +50,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v2.0.0-beta.2 (and newer) package + Designed for use with the kim-api-v2-2.0.0 (and newer) package ------------------------------------------------------------------------- */ #ifdef PAIR_CLASS -- GitLab From c193a9aee902a8a5f7eac683d04be3051fb377fe Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Thu, 14 Feb 2019 19:28:18 -0600 Subject: [PATCH 0128/1243] Updated Errors_messages.txt & false_positives.txt --- doc/src/Errors_messages.txt | 2 -- doc/utils/sphinx-config/false_positives.txt | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/src/Errors_messages.txt b/doc/src/Errors_messages.txt index dab46874fb..fb5003e602 100644 --- a/doc/src/Errors_messages.txt +++ b/doc/src/Errors_messages.txt @@ -10179,8 +10179,6 @@ valid. :dd Self-explanatory. :dd -{Unrecognized virial argument in pair_style command} :dt - {Unsupported mixing rule in kspace_style ewald/disp} :dt Only geometric mixing is supported. :dd diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 5844dd3454..b76ec11f8d 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1384,6 +1384,7 @@ libfftw libgcc libgpu libjpeg +libkim liblammps Liblammps liblink -- GitLab From afa50ab61a4fc4511dd3bce2ab8b955c20f6e27c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Feb 2019 02:21:07 -0500 Subject: [PATCH 0129/1243] update pathspec when linking KIM API from downloaded archive --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index b40c9aaeb2..c49dcfae71 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -674,7 +674,7 @@ if(PKG_KIM) ) ExternalProject_get_property(kim_build INSTALL_DIR) set(KIM-API-V2_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) - set(KIM-API-V2_LDFLAGS ${INSTALL_DIR}/lib/libkim-api-v2.2${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(KIM-API-V2_LDFLAGS ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/libkim-api-v2${CMAKE_SHARED_LIBRARY_SUFFIX}) list(APPEND LAMMPS_DEPS kim_build) else() find_package(KIM-API-V2) -- GitLab From c2725f5a49a3368885a467ac9bbbba8c278a4c53 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Feb 2019 03:53:09 -0500 Subject: [PATCH 0130/1243] forward build type setting to compiling downloaded KIM API --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index c49dcfae71..30c8171f28 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -670,7 +670,7 @@ if(PKG_KIM) -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER} -DCMAKE_INSTALL_PREFIX= - -DCMAKE_BUILD_TYPE=Release + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ) ExternalProject_get_property(kim_build INSTALL_DIR) set(KIM-API-V2_INCLUDE_DIRS ${INSTALL_DIR}/include/kim-api-v2) -- GitLab From 318dd347379085ed6ce38c89f5af57cb03338727 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 15:00:04 -0500 Subject: [PATCH 0131/1243] correct cut-n-paste error --- src/atom_vec_body.cpp | 2 +- src/atom_vec_ellipsoid.cpp | 2 +- src/atom_vec_line.cpp | 2 +- src/atom_vec_tri.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atom_vec_body.cpp b/src/atom_vec_body.cpp index 5a277627ee..893a4c7dc4 100644 --- a/src/atom_vec_body.cpp +++ b/src/atom_vec_body.cpp @@ -1286,7 +1286,7 @@ void AtomVecBody::data_atom(double *coord, imageint imagetmp, char **values) body[nlocal] = atoi(values[2]); if (body[nlocal] == 0) body[nlocal] = -1; else if (body[nlocal] == 1) body[nlocal] = 0; - else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + else error->one(FLERR,"Invalid bodyflag in Atoms section of data file"); rmass[nlocal] = atof(values[3]); if (rmass[nlocal] <= 0.0) diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index c569f89a09..2bf3f683d0 100644 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -1148,7 +1148,7 @@ void AtomVecEllipsoid::data_atom(double *coord, imageint imagetmp, ellipsoid[nlocal] = atoi(values[2]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else if (ellipsoid[nlocal] == 1) ellipsoid[nlocal] = 0; - else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + else error->one(FLERR,"Invalid ellipsoidflag in Atoms section of data file"); rmass[nlocal] = atof(values[3]); if (rmass[nlocal] <= 0.0) diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp index 9babfe3735..020b622c93 100644 --- a/src/atom_vec_line.cpp +++ b/src/atom_vec_line.cpp @@ -1044,7 +1044,7 @@ void AtomVecLine::data_atom(double *coord, imageint imagetmp, char **values) 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"); + else error->one(FLERR,"Invalid lineflag in Atoms section of data file"); rmass[nlocal] = atof(values[4]); if (rmass[nlocal] <= 0.0) diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp index 2c31b95cfe..8fbe0a92dc 100644 --- a/src/atom_vec_tri.cpp +++ b/src/atom_vec_tri.cpp @@ -1443,7 +1443,7 @@ void AtomVecTri::data_atom(double *coord, imageint imagetmp, char **values) 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"); + else error->one(FLERR,"Invalid triflag in Atoms section of data file"); rmass[nlocal] = atof(values[4]); if (rmass[nlocal] <= 0.0) -- GitLab From 09de4fb9536d21939a952c23b734aaa344c17f10 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 15:01:13 -0500 Subject: [PATCH 0132/1243] add support for checking consistency of atom bonus data --- src/atom.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/atom.h | 6 ++++++ 2 files changed, 46 insertions(+) diff --git a/src/atom.cpp b/src/atom.cpp index be4d12d52e..a149268767 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -58,6 +58,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) natoms = 0; nlocal = nghost = nmax = 0; ntypes = 0; + nellipsoids = nlines = ntris = nbodies = 0; nbondtypes = nangletypes = ndihedraltypes = nimpropertypes = 0; nbonds = nangles = ndihedrals = nimpropers = 0; @@ -738,6 +739,45 @@ int Atom::tag_consecutive() return 1; } +/* ---------------------------------------------------------------------- + check that bonus data settings are valid + error if number of atoms with ellipsoid/line/tri/body flags + are consistent with global setting. +------------------------------------------------------------------------- */ + +void Atom::bonus_check() +{ + bigint local_ellipsoids = 0, local_lines = 0, local_tris = 0; + bigint local_bodies = 0, num_global; + + for (int i = 0; i < nlocal; ++i) { + if (ellipsoid && (ellipsoid[i] >=0)) ++local_ellipsoids; + if (line && (line[i] >=0)) ++local_lines; + if (tri && (tri[i] >=0)) ++local_tris; + if (body && (body[i] >=0)) ++local_bodies; + } + + MPI_Allreduce(&local_ellipsoids,&num_global,1,MPI_LMP_BIGINT,MPI_MIN,world); + if (nellipsoids != num_global) + error->all(FLERR,"Inconsistent 'ellipsoids' header value and number of " + "atoms with enabled ellipsoid flags"); + + MPI_Allreduce(&local_lines,&num_global,1,MPI_LMP_BIGINT,MPI_MIN,world); + if (nlines != num_global) + error->all(FLERR,"Inconsistent 'lines' header value and number of " + "atoms with enabled line flags"); + + MPI_Allreduce(&local_tris,&num_global,1,MPI_LMP_BIGINT,MPI_MIN,world); + if (ntris != num_global) + error->all(FLERR,"Inconsistent 'tris' header value and number of " + "atoms with enabled tri flags"); + + MPI_Allreduce(&local_bodies,&num_global,1,MPI_LMP_BIGINT,MPI_MIN,world); + if (nbodies != num_global) + error->all(FLERR,"Inconsistent 'bodies' header value and number of " + "atoms with enabled body flags"); +} + /* ---------------------------------------------------------------------- count and return words in a single line make copy of line before using strtok so as not to change line diff --git a/src/atom.h b/src/atom.h index 324ad0f2d2..b2a657cf1a 100644 --- a/src/atom.h +++ b/src/atom.h @@ -34,6 +34,10 @@ class Atom : protected Pointers { int tag_enable; // 0/1 if atom ID tags are defined int molecular; // 0 = atomic, 1 = standard molecular system, // 2 = molecule template system + bigint nellipsoids; // number of ellipsoids + bigint nlines; // number of lines + bigint ntris; // number of triangles + bigint nbodies; // number of bodies bigint nbonds,nangles,ndihedrals,nimpropers; int ntypes,nbondtypes,nangletypes,ndihedraltypes,nimpropertypes; @@ -233,6 +237,8 @@ class Atom : protected Pointers { void tag_extend(); int tag_consecutive(); + void bonus_check(); + int parse_data(const char *); int count_words(const char *); int count_words(const char *, char *); -- GitLab From d89084841285547b3be999c297124bcf85c460c2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 15:03:59 -0500 Subject: [PATCH 0133/1243] add a check for consistent bonus data --- src/read_data.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/read_data.cpp b/src/read_data.cpp index a640368fb0..2f4484010b 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -396,7 +396,8 @@ void ReadData::command(int narg, char **arg) // values in this data file - natoms = ntypes = 0; + natoms = 0; + ntypes = 0; nbonds = nangles = ndihedrals = nimpropers = 0; nbondtypes = nangletypes = ndihedraltypes = nimpropertypes = 0; @@ -993,18 +994,29 @@ void ReadData::header(int firstpass) if (!avec_ellipsoid) error->all(FLERR,"No ellipsoids allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nellipsoids); + if (addflag == NONE) atom->nellipsoids = nellipsoids; + else if (firstpass) atom->nellipsoids += nellipsoids; + } else if (strstr(line,"lines")) { if (!avec_line) error->all(FLERR,"No lines allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nlines); + if (addflag == NONE) atom->nlines = nlines; + else if (firstpass) atom->nlines += nlines; + } else if (strstr(line,"triangles")) { if (!avec_tri) error->all(FLERR,"No triangles allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&ntris); + if (addflag == NONE) atom->ntris = ntris; + else if (firstpass) atom->ntris += ntris; + } else if (strstr(line,"bodies")) { if (!avec_body) error->all(FLERR,"No bodies allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nbodies); + if (addflag == NONE) atom->nbodies = nbodies; + else if (firstpass) atom->nbodies += nbodies; } else if (strstr(line,"bonds")) { sscanf(line,BIGINT_FORMAT,&nbonds); @@ -1084,6 +1096,10 @@ void ReadData::header(int firstpass) // error check on total system size if (atom->natoms < 0 || atom->natoms >= MAXBIGINT || + atom->nellipsoids < 0 || atom->nellipsoids >= MAXBIGINT || + atom->nlines < 0 || atom->nlines >= MAXBIGINT || + atom->ntris < 0 || atom->ntris >= MAXBIGINT || + atom->nbodies < 0 || atom->nbodies >= MAXBIGINT || atom->nbonds < 0 || atom->nbonds >= MAXBIGINT || atom->nangles < 0 || atom->nangles >= MAXBIGINT || atom->ndihedrals < 0 || atom->ndihedrals >= MAXBIGINT || @@ -1174,6 +1190,10 @@ void ReadData::atoms() atom->tag_check(); + // check that bonus data has been reserved as needed + + atom->bonus_check(); + // create global mapping of atoms if (atom->map_style) { -- GitLab From 7d0c0bc9849ec95d3cd7fdfa3fc3c170010bfee5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 17:14:01 -0500 Subject: [PATCH 0134/1243] make nlocal_bonus accessible --- src/atom_vec_body.h | 4 +++- src/atom_vec_ellipsoid.h | 4 +++- src/atom_vec_line.h | 4 +++- src/atom_vec_tri.h | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/atom_vec_body.h b/src/atom_vec_body.h index 3244b0f64d..7cc052b6c5 100644 --- a/src/atom_vec_body.h +++ b/src/atom_vec_body.h @@ -92,6 +92,8 @@ class AtomVecBody : public AtomVec { double radius_body(int, int, int *, double *); void set_quat(int, double *); + int nlocal_bonus; + private: tagint *tag; int *type,*mask; @@ -102,7 +104,7 @@ class AtomVecBody : public AtomVec { double **angmom,**torque; int *body; - int nlocal_bonus,nghost_bonus,nmax_bonus; + int nghost_bonus,nmax_bonus; int intdoubleratio; // sizeof(double) / sizeof(int) MyPoolChunk *icp; diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h index 6beb68b176..d71859624e 100644 --- a/src/atom_vec_ellipsoid.h +++ b/src/atom_vec_ellipsoid.h @@ -83,6 +83,8 @@ class AtomVecEllipsoid : public AtomVec { void set_shape(int, double, double, double); + int nlocal_bonus; + private: tagint *tag; int *type,*mask; @@ -92,7 +94,7 @@ class AtomVecEllipsoid : public AtomVec { double **angmom,**torque; int *ellipsoid; - int nlocal_bonus,nghost_bonus,nmax_bonus; + int nghost_bonus,nmax_bonus; void grow_bonus(); void copy_bonus(int, int); diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h index 7f07532fa4..6c8701cfc2 100644 --- a/src/atom_vec_line.h +++ b/src/atom_vec_line.h @@ -83,6 +83,8 @@ class AtomVecLine : public AtomVec { void set_length(int, double); + int nlocal_bonus; + private: tagint *tag; int *type,*mask; @@ -93,7 +95,7 @@ class AtomVecLine : public AtomVec { double **omega,**torque; int *line; - int nlocal_bonus,nghost_bonus,nmax_bonus; + int nghost_bonus,nmax_bonus; void grow_bonus(); void copy_bonus(int, int); diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h index 390efc7c10..81b4c1ada9 100644 --- a/src/atom_vec_tri.h +++ b/src/atom_vec_tri.h @@ -85,6 +85,8 @@ class AtomVecTri : public AtomVec { void set_equilateral(int, double); + int nlocal_bonus; + private: tagint *tag; int *type,*mask; @@ -95,7 +97,7 @@ class AtomVecTri : public AtomVec { double **omega,**angmom,**torque; int *tri; - int nlocal_bonus,nghost_bonus,nmax_bonus; + int nghost_bonus,nmax_bonus; void grow_bonus(); void copy_bonus(int, int); -- GitLab From 07c1942b1396fe965552aba0cc81e603e500cc7c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 17:14:45 -0500 Subject: [PATCH 0135/1243] update global bonus data counters after deleting atoms --- src/delete_atoms.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index ec713b8b84..9259ca4f4b 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -16,6 +16,10 @@ #include "delete_atoms.h" #include "atom.h" #include "atom_vec.h" +#include "atom_vec_ellipsoid.h" +#include "atom_vec_line.h" +#include "atom_vec_tri.h" +#include "atom_vec_body.h" #include "molecule.h" #include "comm.h" #include "domain.h" @@ -121,11 +125,39 @@ void DeleteAtoms::command(int narg, char **arg) } // reset atom->natoms and also topology counts - // reset atom->map if it exists - // set nghost to 0 so old ghosts of deleted atoms won't be mapped bigint nblocal = atom->nlocal; MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world); + + // reset bonus data counts + + AtomVecEllipsoid *avec_ellipsoid = + (AtomVecEllipsoid *) atom->style_match("ellipsoid"); + AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line"); + AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri"); + AtomVecBody *avec_body = (AtomVecBody *) atom->style_match("body"); + bigint nlocal_bonus; + + if (atom->nellipsoids > 0) { + nlocal_bonus = avec_ellipsoid->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->nellipsoids,1,MPI_LMP_BIGINT,MPI_MIN,world); + } + if (atom->nlines > 0) { + nlocal_bonus = avec_line->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->nlines,1,MPI_LMP_BIGINT,MPI_MIN,world); + } + if (atom->ntris > 0) { + nlocal_bonus = avec_tri->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->ntris,1,MPI_LMP_BIGINT,MPI_MIN,world); + } + if (atom->nbodies > 0) { + nlocal_bonus = avec_body->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->nbodies,1,MPI_LMP_BIGINT,MPI_MIN,world); + } + + // reset atom->map if it exists + // set nghost to 0 so old ghosts of deleted atoms won't be mapped + if (atom->map_style) { atom->nghost = 0; atom->map_init(); -- GitLab From 7b47c82452d8de1629f51b830e2df71981c390ce Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 18:50:35 -0500 Subject: [PATCH 0136/1243] update global bonus data counters --- src/set.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/set.cpp b/src/set.cpp index 34b86ea328..00b2d8a9b0 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -964,6 +964,21 @@ void Set::set(int keyword) count++; } + // update bonus data numbers + if (keyword == SHAPE) { + bigint nlocal_bonus = avec_ellipsoid->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->nellipsoids,1, + MPI_LMP_BIGINT,MPI_SUM,world); + } + if (keyword == LENGTH) { + bigint nlocal_bonus = avec_line->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->nlines,1,MPI_LMP_BIGINT,MPI_SUM,world); + } + if (keyword == TRI) { + bigint nlocal_bonus = avec_tri->nlocal_bonus; + MPI_Allreduce(&nlocal_bonus,&atom->ntris,1,MPI_LMP_BIGINT,MPI_SUM,world); + } + // clear up per-atom memory if allocated memory->destroy(vec1); -- GitLab From a0450fbd2b411916aea033617ba275f31ea2ec26 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 17 Feb 2019 18:51:15 -0500 Subject: [PATCH 0137/1243] fix copy-n-modify error --- src/delete_atoms.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp index 9259ca4f4b..41df167f07 100644 --- a/src/delete_atoms.cpp +++ b/src/delete_atoms.cpp @@ -140,19 +140,19 @@ void DeleteAtoms::command(int narg, char **arg) if (atom->nellipsoids > 0) { nlocal_bonus = avec_ellipsoid->nlocal_bonus; - MPI_Allreduce(&nlocal_bonus,&atom->nellipsoids,1,MPI_LMP_BIGINT,MPI_MIN,world); + MPI_Allreduce(&nlocal_bonus,&atom->nellipsoids,1,MPI_LMP_BIGINT,MPI_SUM,world); } if (atom->nlines > 0) { nlocal_bonus = avec_line->nlocal_bonus; - MPI_Allreduce(&nlocal_bonus,&atom->nlines,1,MPI_LMP_BIGINT,MPI_MIN,world); + MPI_Allreduce(&nlocal_bonus,&atom->nlines,1,MPI_LMP_BIGINT,MPI_SUM,world); } if (atom->ntris > 0) { nlocal_bonus = avec_tri->nlocal_bonus; - MPI_Allreduce(&nlocal_bonus,&atom->ntris,1,MPI_LMP_BIGINT,MPI_MIN,world); + MPI_Allreduce(&nlocal_bonus,&atom->ntris,1,MPI_LMP_BIGINT,MPI_SUM,world); } if (atom->nbodies > 0) { nlocal_bonus = avec_body->nlocal_bonus; - MPI_Allreduce(&nlocal_bonus,&atom->nbodies,1,MPI_LMP_BIGINT,MPI_MIN,world); + MPI_Allreduce(&nlocal_bonus,&atom->nbodies,1,MPI_LMP_BIGINT,MPI_SUM,world); } // reset atom->map if it exists -- GitLab From d8e8a0d2d24fcbbf26b5b60fb876ea3d85ba023b Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Mon, 18 Feb 2019 09:58:34 -0700 Subject: [PATCH 0138/1243] More changes to pair granular: - tangential damping now set by scaling the normal damping - some fixes to the twisting coefficients for the Marshall twist model - progress (completion?) of doc page --- doc/src/pair_granular.txt | 523 ++++++++++++++++++++++++++++----- src/GRANULAR/pair_granular.cpp | 374 +++++++++++------------ 2 files changed, 621 insertions(+), 276 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index d6b18217d8..ff2ee94be0 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -17,69 +17,79 @@ pair_style granular command :h3 [Syntax:] -pair_style style cutoff :pre +pair_style granular cutoff :pre -style = {granular} or {granular/multi} :ulb,l cutoff = global cutoff (optional). See discussion below. :l :ule [Examples:] pair_style granular -pair_coeff * * hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.4 :pre +pair_coeff * * hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 :pre pair_style granular -pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair_coeff 2 2 hertz 200.0 20.0 tangential mindlin 300.0 50.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre +pair_coeff * * hertz 1000.0 50.0 tangential linear_history 800.0 1.0 0.4 :pre pair_style granular -pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 50.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair_coeff 2 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall -pair_coeff 1 2 dmt 1000.0 50.0 800.0 10.0 tangential mindlin 800.0 50.0 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre +pair_coeff * * hertz 1000.0 0.3 tangential linear_history 800.0 1.0 0.4 damping tsuji :pre +pair_style granular +pair_coeff 1 1 jkr 1000.0 50.0 tangential linear_history 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 2 2 hertz 200.0 20.0 tangential linear_history 300.0 1.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre + +pair_style granular +pair_coeff 1 1 hertz 1000.0 50.0 tangential linear_history 800.0 0.5 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 2 2 dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall +pair_coeff 1 2 dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre [Description:] The {granular} styles support a variety of options for the normal, tangential, rolling and twisting forces resulting from contact between two granular particles. This expands on the options offered -by the "pair gran/*"_pair_gran.html options. The total computed forces and torques depend on the combination -of models selected for these various modes of motion. +by the "pair gran/*"_pair_gran.html pair styles. The total computed forces and torques are the +sum of various models selected for the normal, tangential, rolling and twisting modes of motion. -All model options and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. +All model choices and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. Unlike e.g. "pair gran/hooke"_pair_gran.html, coefficient values are not global, but can be set to different values for -various combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. -For {pair_style granular}, coefficients as well as model options can vary between particle types. -As shown in the second example, -type 1- type 1 interactions are based on a Hertzian normal contact model and 2-2 interactions are based on a {dmt} model (see below). +different combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. +If the contact model choice is the same for two particle types, the mixing for the cross-coefficients can be carried out +automatically. This is shown in the second example, where model choices are the same for type 1 - type 1 as for type 2 - type2 +interactions, but coefficients are different. In this case, the coefficients for type 2 - type interactions can be +determined from mixing rules discussed below. +For additional flexibility, coefficients as well as model forms can vary between particle types, +as shown in the third example: +type 1- type 1 interactions are based on a Hertzian normal contact model and 2-2 interactions are based on a DMT cohesive model (see below). In that example, 1-1 and 2-2 interactions have different model forms, in which case mixing of coefficients cannot be determined, so 1-2 interactions must be explicitly defined via the -pair coeff command, otherwise an error would result. +{pair_coeff 1 2} command, otherwise an error would result. :line The first required keyword for the {pair_coeff} command is the normal contact model. Currently supported options for normal contact models and their required arguments are: -{hooke} : \(k_n\), damping -{hertz} : \(k_n\), damping -{hertz/material} : E, damping, \(\nu\) -{dmt} : E, damping, \(\nu\), cohesion -{jkr} : E, damping, \(\nu\), cohesion :ol +{hooke} : \(k_n\), \(\eta_\{n0\}\) (or \(e\)) +{hertz} : \(k_n\), \(\eta_\{n0\}\) (or \(e\)) +{hertz/material} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\) +{dmt} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\), \(\gamma\) +{jkr} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\), \(\gamma\) :ol Here, \(k_n\) is spring stiffness (with units that depend on model choice, see below); -damping is a damping constant or a coefficient of restitution, depending on -the choice of damping model; E is Young's modulus in units of force/length^2; \(\nu\) is Poisson's ratio -and cohesion is a surface energy density, in units of energy/length^2. +\(\eta_\{n0\}\) is a damping prefactor (or, in its place a coefficient of restitution +\(e\), depending on the choice of damping mode, see below); E is Young's modulus +in units of {force}/{length}^2, i.e. {pressure}; \(\nu\) is Poisson's ratio +and \(\gamma\) is a surface energy density, in units of {energy}/{length}^2. -For the {hooke} model, the normal (elastic) component of force between two particles {i} and {j} is given by: +For the {hooke} model, the normal, elastic component of force acting on particle {i} due to +contact with particle {j} is given by: \begin\{equation\} \mathbf\{F\}_\{ne, Hooke\} = k_N \delta_\{ij\} \mathbf\{n\} \end\{equation\} Where \(\delta = R_i + R_j - \|\mathbf\{r\}_\{ij\}\|\) is the particle overlap, \(R_i, R_j\) are the particle radii, -\(\mathbf\{r\}_\{ij\} = \mathbf\{r\}_j - \mathbf\{r\}_i\) is the vector separating the -two particle centers +\(\mathbf\{r\}_\{ij\} = \mathbf\{r\}_i - \mathbf\{r\}_j\) is the vector separating the +two particle centers (note the i-j ordering so that \(F_\{ne\}\) is positive for repulsion), and \(\mathbf\{n\} = \frac\{\mathbf\{r\}_\{ij\}\}\{\|\mathbf\{r\}_\{ij\}\|\}\). Therefore, for {hooke}, the units of the spring constant \(k_n\) are {force}/{distance}, or equivalently {mass}/{time^2}. @@ -90,7 +100,7 @@ For the {hertz} model, the normal component of force is given by: \end\{equation\} Here, \(R_\{eff\} = \frac\{R_i R_j\}\{R_i + R_j\}\) is the effective radius, denoted for simplicity as {R} from here on. -For {hertz}, the units of the spring constant \(k_n\) are {force}/{distance}^2, or equivalently +For {hertz}, the units of the spring constant \(k_n\) are {force}/{length}^2, or equivalently {pressure}. For the {hertz/material} model, the force is given by: @@ -101,17 +111,17 @@ For the {hertz/material} model, the force is given by: Here, \(E_\{eff\} = E = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\}\) is the effective Young's modulus, with \(\nu_i, \nu_j \) the Poisson ratios of the particles of types {i} and {j}. Note that - if the elastic and shear moduli of the +if the elastic and shear moduli of the two particles are the same, the {hertz/material} model is equivalent to the {hertz} model with \(k_N = 4/3 E_\{eff\}\) -The {dmt} model corresponds to the Derjaguin-Muller-Toporov model, +The {dmt} model corresponds to the "(Derjaguin-Muller-Toporov)"_#DMT1975 cohesive model, where the force is simply Hertz with an additional attractive cohesion term: \begin\{equation\} \mathbf\{F\}_\{ne, dmt\} = \left(\frac\{4\}\{3\} E R^\{1/2\}\delta_\{ij\}^\{3/2\} - 4\pi\gamma R\right)\mathbf\{n\} \end\{equation\} -The {jkr} model is the Johnson-Kendall-Roberts model, where the force is computed as: +The {jkr} model is the "(Johnson-Kendall-Roberts)"_#JKR1971 model, where the force is computed as: \begin\{equation\} \label\{eq:force_jkr\} \mathbf\{F\}_\{ne, jkr\} = \left(\frac\{4Ea^3\}\{3R\} - 2\pi a^2\sqrt\{\frac\{4\gamma E\}\{\pi a\}\}\right)\mathbf\{n\} @@ -131,11 +141,25 @@ will not experience force until they come into contact \(\delta \geq 0\); as the and (\(\delta < 0\)), they experience a tensile force up to \(3\pi\gamma R\), at which point they lose contact. -In addition to the above options, the normal force is augmented by a damping term. The optional -{damping} keyword to the {pair_coeff} command followed by the model choice determines the form of the damping. -The damping coefficient that was specified for the normal model -settings is used in computing the damping term, as described below. Note this damping parameter -may be interpreted differently depending on the model choice. +:line + +In addition, the normal force is augmented by a damping term of the following +general form: + +\begin\{equation\} +\mathbf\{F\}_\{n,damp\} = -\eta_n \mathbf\{v\}_\{n,rel\} +\end\{equation\} + +Here, \(\mathbf\{v\}_\{n,rel\} = (\mathbf\{v\}_j - \mathbf\{v\}_i) \cdot \mathbf\{n\}\) +is the component of relative velocity along \(\mathbf\{n\}\). + +The optional {damping} keyword to the {pair_coeff} command followed by a keyword +determines the model form of the damping factor \(\eta_n\), and the interpretation +of the \(\eta_\{n0\}\) or \(e\) coefficients specified as part of the normal contact +model settings. The {damping} keyword and corresponding +model form selection may be appended anywhere in the {pair coeff} command. +Note that the choice of damping model affects both the +normal and tangential damping (and depending on other settings, potentially also the twisting damping). The options for the damping model currently supported are: {velocity} @@ -144,91 +168,414 @@ The options for the damping model currently supported are: If the {damping} keyword is not specified, the {viscoelastic} model is used by default. -For {damping velocity}, the normal damping is simply proportional to the velocity: +For {damping velocity}, the normal damping is simply equal to the user-specified damping +coefficient in the {normal} model: + \begin\{equation\} -F_\{N,damp\} = -\gamma_N\mathbf\{v\}_\{N,rel\} +\eta_n = \eta_\{n0\}\ \end\{equation\} -Here, \(\gamma_N\) is the damping coefficient, in units of {mass}/{time}, -\(\mathbf\{v\}_\{N,rel\} = (\mathbf\{v\}_i - \mathbf\{v\}_j) \cdot \mathbf\{n\}\) -is the component of relative velocity along the direction of the vector \(\mathbf\{n\}\) that connects the centers of -particles {i} and {j}. +Here, \(\gamma_n\) is the damping coefficient specified for the normal contact model, in units of {mass}/{time}, The {damping viscoelastic} model is based on the viscoelastic treatment of "(Brilliantov et al)"_#Brill1996, where the normal damping is given by: \begin\{equation\} -F_\{N,damp\} = -\gamma_N a m_\{eff\} \mathbf\{v\}_\{N,rel\} +\eta_n = \eta_\{n0\}\ a m_\{eff\} \end\{equation\} Here, \(m_\{eff\} = m_i m_j/(m_i + m_j)\) is the effective mass, {a} is the contact radius, given by \(a =\sqrt\{R\delta\}\) for all models except {jkr}, for which it is given implicitly according to \(delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\). -In this case, \(\gamma_N\) is the damping coefficient, in units of 1/({time}*{distance}). +In this case, \eta_\{n0\}\ is in units of 1/({time}*{distance}). The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the -damping term is given by: +damping coefficient specified as part of the normal model is intepreted +as a restitution coefficient \(e\). The damping constant \(\eta_n\) is given by: + \begin\{equation\} -F_\{N,damp\} = -\alpha (m_\{eff\}k_N)^\{l/2\} \mathbf\{v\}_\{N,rel\} +\eta_n = \alpha (m_\{eff\}k_n)^\{1/2\} \end\{equation\} -For normal contact models based on material parameters, \(k_N = 4/3Ea\). +For normal contact models based on material parameters, \(k_n = 4/3Ea\). The parameter \(\alpha\) is related to the restitution coefficient {e} according to: -\begin{equation} + +\begin\{equation\} \alpha = 1.2728-4.2783e+11.087e^2-22.348e^3+27.467e^4-18.022e^5+4.8218e^6 -\end{equation} +\end\{equation\} + +The dimensionless coefficient of restitution \(e\) specified as part of the normal contact model +parameters should be between 0 and 1, but no error check is performed on this. -For further details, see "(Tsuji et al)"_#Tsuji1992. +The total normal force is computed as the sum of the elastic and damping components: + +\begin\{equation\} +\mathbf\{F\}_n = \mathbf\{F\}_\{ne\} + \mathbf\{F\}_\{n,damp\} +\end\{equation\} :line -Following the normal contact model settings, the {pair_coeff} command requires specification -of the tangential contact model. The required keyword {tangential} is expected, followed by the model choice and associated -parameters. Currently supported tangential model choices and their expected parameters are as follows: +The {pair_coeff} command also requires specification +of the tangential contact model. The required keyword {tangential} is expected, followed by the model +choice and associated parameters. Currently supported tangential model choices and their +expected parameters are as follows: -{linear_nohistory} : \(\gamma_t\), \(\mu_s\) -{linear_history} : \(k_t\), \(\gamma_t\), \(\mu_s\) :ol +{linear_nohistory} : \(x_\{\gamma,t\}\), \(\mu_s\) +{linear_history} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) :ol -Here, \(\gamma_t\) is the tangential damping coefficient, \(\mu_s\) is the tangential (or sliding) friction -coefficient, and \(k_t\) is the tangential stiffness coefficient. +Here, \(x_\{\gamma,t\}\) is a dimensionless multiplier for the normal damping \(\eta_n\) +that determines the magnitude of the +tangential damping, \(\mu_t\) is the tangential (or sliding) friction +coefficient, and \(k_t\) is the tangential stiffness coefficient. -For {linear_nohistory}, a simple velocity-dependent Coulomb friction criterion is used, which reproduces the behavior +For {tangential linear_nohistory}, a simple velocity-dependent Coulomb friction criterion is used, +which mimics the behavior of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: \begin\{equation\} -\mathbf\{F\}_t = -min(\mu_s \|\mathbf\{F\}_n\|, \gamma_t m_\{eff\}\|\mathbf\{v\}_\{t, rel\}\|) \mathbf\{t\} +\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|\mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} \end\{equation\} -Where \(\|\mathbf\{F\}_n\) is the magnitude of the normal force, -\(\mathbf\{v\}_\{t, rel\} = \mathbf\{v\}_\{t\} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf\{n\}\) is the relative tangential -velocity at the point of contact, \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_R - \mathbf\{v\}_R\cdot\mathbf\{n\}\), -\(\mathbf\{v\}_R = \mathbf\{v\}_i - \mathbf\{v\}_j. +The tangential damping force \(\mathbf\{F\}_\mathrm\{t,damp\}\) is given by: -For {linear_history}, the total tangential displacement \(\mathbf\{\xi\}\) is accumulated during the entire -duration of the contact: +\begin\{equation\} +\mathbf\{F\}_\mathrm\{t,damp\} = -\eta_t \mathbf\{v\}_\{t,rel\} +\end\{equation\} +The tangetial damping prefactor \(\eta_t\) is calculated by scaling the normal damping \(\eta_n\) (see above): \begin\{equation\} -\mathbf\{\xi\} = \int_\{t0\}^t \mathbf\{v\}_\{t,rel\}(\tau) \mathrm\{d\}\tau +\eta_t = -x_\{\gamma,t\} \eta_n +\end\{equation\} + +The normal damping prefactor \(\eta_n\) is determined by the choice of the {damping} keyword, as discussed above. +Thus, the {damping} keyword also affects the tangential damping. +The parameter \(x_\{\gamma,t\}\) is a scaling coefficient. Several works in the literature use +\(x_\{\gamma,t\} = 1\) ("Marshall"_#Marshall2009, "Tsuji et al"_#Tsuji1992, "Silbert et al"_#Silbert2001). +The relative tangential velocity at the point of contact is given by +\(\mathbf\{v\}_\{t, rel\} = \mathbf\{v\}_\{t\} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf\{n\}\), +where \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_r - \mathbf\{v\}_r\cdot\mathbf\{n\}\), +\(\mathbf\{v\}_r = \mathbf\{v\}_j - \mathbf\{v\}_i\). The direction of the applied force is +\(\mathbf\{t\} = \mathbf\{v_\{t,rel\}\}/\|\mathbf\{v_\{t,rel\}\}\|\). + +The normal force value \(F_\{n0\}\) used to compute the critical force +depends on the form of the contact model. For non-cohesive models +({hertz}, {hertz/material}, {hooke}), it is given by the magnitude of the normal force: + +\begin\{equation\} +F_\{n0\} = \|\mathbf\{F\}_n\| +\end\{equation\} + +For cohesive models such as {jkr} and {dmt}, the critical force is adjusted so that the critical tangential +force approaches \(\mu_t F_\{pulloff\}\), see "Marshall"_#Marshall2009, equation 43, and "Thornton"_#. +For both models, \(F_\{n0\}\) takes the form: + +\begin\{equation\} +F_\{n0\} = \|\mathbf\{F\}_ne + 2 F_\{pulloff\}\| \end\{equation\} -The tangential displacement must in the frame of reference of the contacting pair of particles, +Where \(F_\{pulloff\} = 3\pi \gamma R \) for {jkr}, and \(F_\{pulloff\} = 4\pi \gamma R \) for {dmt}. + +For {tangential linear_history}, the tangential force is given by: \begin\{equation\} -\mathbf\{\xi\} = \mathbf\{\xi'\} - \mathbf\{n\}(\mathbf\{n\} \cdot \mathbf\{\xi'\}) +\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|-k_t\mathbf\{\xi\} + \mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} \end\{equation\} -\noindent Since the goal here is a `rotation', the equation above should be accompanied by a rescaling, so that at each step, -the displacement is first rotated into the current frame of reference $\mathbf\{\xi\}$, then updated: +Here, \(\mathbf\{\xi\}\) is the tangential displacement accumulated during the entire +duration of the contact: + +\begin\{equation\} +\mathbf\{\xi\} = \int_\{t0\}^t \mathbf\{v\}_\{t,rel\}(\tau) \mathrm\{d\}\tau +\end\{equation\} + +This accumlated tangential displacement must be adjusted to account for changes +in the frame of reference +of the contacting pair of particles during contact. This occurs due to the overall motion of the contacting particles +in a rigid-body-like fashion during the duration of the contact. There are two modes of motion +that are relevant: the 'tumbling' rotation of the contacting pair, which changes the orientation of the +plane in which tangential displacement occurs; and 'spinning' rotation of the contacting pair +about the vector connecting their centers of mass (\(\mathbf\{n\}\)). +Corrections due to the former mode of motion are +made by rotating the accumulated displacement into the plane that is tangential +to the contact vector at each step, +or equivalently removing any component of the tangential displacement +that lies along \(\mathbf\{n\}\), and rescaling to preserve the magnitude. +This folllows the discussion in "Luding"_#Luding2008, see equation 17 and +relevant discussion in that work: \begin\{equation\} \mathbf\{\xi\} = \left(\mathbf\{\xi'\} - (\mathbf\{n\} \cdot \mathbf\{\xi'\})\mathbf\{n\}\right) \frac\{\|\mathbf\{\xi'\}\|\}\{\|\mathbf\{\xi'\}\| - \mathbf\{n\}\cdot\mathbf\{\xi'\}\} \label\{eq:rotate_displacements\} \end\{equation\} +Here, \(\mathbf\{\xi'\}\) is the accumulated displacement prior to the current time step and +\(\mathbf\{\xi\}\) is the corrected displacement. Corrections to the displacement +due to the second mode of motion described above (rotations about \(\mathbf\{n\}\)) +are not currently implemented, but are expected to be minor for most simulations. -a simple velocity-dependent Coulomb friction criterion is used, which reproduces the behavior -of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: +Furthermore, when the tangential force exceeds the critical force, +the tangential displacement is re-scaled to match the value for the critical force (see "Luding"_#Luding2008, +equation 20 and related discussion): + +\begin\{equation\} +\mathbf\{\xi\} = -\frac\{1\}\{k_t\}\left(\mu_t F_\{n0\}\mathbf\{t\} + \mathbf\{F\}_\{t,damp\}\right) +\end\{equation\} + +The tangential force is added to the total normal force (elastic plus damping) to produce the total force +on the particle. The tangential force also acts at the contact point to induce a torque on each +particle according to: + +\begin\{equation\} +\mathbf\{\tau\}_i = -R_i \mathbf\{n\} \times \mathbf\{F\}_t +\end\{equation\} + +\begin\{equation\} +\mathbf\{\tau\}_j = -R_j \mathbf\{n\} \times \mathbf\{F\}_t +\end\{equation\} + +:line + +The optional {rolling} keyword enables rolling friction, which resists pure rolling +motion of particles. The options currently supported are: + +{none} +{sds} : \(k_\{roll\}\), \(\gamma_\{roll\}\), \(\mu_\{roll\}\) :ol + +If the {rolling} keyword is not specified, the model defaults to {none}. + +For {rolling sds}, rolling friction is computed via a spring-dashpot-slider, using a +'pseudo-force' formulation, as detailed by "Luding"_#Luding2008. Unlike the formulation +in "Marshall"_#Marshall2009, this allows for the required adjustment of +rolling displacement due to changes in the frame of referenece of the contacting pair. +The rolling pseudo-force is computed analogously to the tangential force: + +\begin\{equation\} +\mathbf\{F\}_\{roll,0\} = k_\{roll\} \mathbf\{\xi\}_\{roll\} - \gamma_\{roll\} \mathbf\{v\}_\{roll\} +\end\{equation\} + +Here, \(\mathbf\{v\}_\{roll\} = -R(\mathbf\{\Omega\}_i - \mathbf\{\Omega\}_j) \times \mathbf\{n\}\) is the +relative rolling velocity, as given in "Wang et al"_#Wang2015 and "Luding"_#Luding2008. This differs +from the expressions given by "Kuhn and Bagi"_#Kuhn2004 and used in "Marshall"_#Marshall2009; +see "Wang et al"_#Wang2015 for details. The rolling displacement is given by: + +\begin\{equation\} +\mathbf\{\xi\}_\{roll\} = \int_\{t_0\}^t \mathbf\{v\}_\{roll\} (\tau) \mathrm\{d\} \tau +\end\{equation\} + +A Coulomb friction criterion truncates the rolling pseudo-force if it exceeds a critical value: +\begin\{equation\} +\mathbf\{F\}_\{roll\} = min(\mu_\{roll\} F_\{n,0\}, \|\mathbf\{F\}_\{roll,0\}\|)\mathbf\{k\} +\end\{equation\} + +Here, \(\mathbf\{k\} = \mathbf\{v\}_\{roll\}/\|\mathbf\{v\}_\{roll\}\|\) is the direction of the pseudo-force. +As with tangential displacement, the rolling displacement is rescaled when the critical +force is exceeded, so that the spring length corresponds the critical force. Additionally, the +displacement is adjusted to account for rotations of the frame of reference of the two +contacting particles in a manner analogous to the tangential displacement. + +The rolling pseudo-force does not contribute to the total force on either particle (hence 'pseudo'), +but acts only to induce an equal and opposite torque on each particle, according to: + +\begin\{equation\} +\tau_\{roll,i\} = R_\{eff\} \mathbf\{n\} \times \mathbf\{F\}_\{roll\} +\end\{equation\} + +\begin\{equation\} +\tau_\{roll,j\} = -\tau_\{roll,i\} +\end\{equation\} + +:line + +The optional {twisting} keyword enables twisting friction, which resists +rotation of two contacting particles about the vector \(\mathbf\{n\}\) that connects their +centers. The options currently supported are: +{none} +{sds} : \(k_\{twist\}\), \(\gamma_\{twist\}\), \(\mu_\{twist\}\) +{marshall} :ol - :link(Brill1996) +If the {twisting} keyword is not specified, the model defaults to {none}. + +For both {twisting sds} and {twisting marshall}, a history-dependent spring-dashpot-slider is used to compute the twisting +torque. Because twisting displacement is a scalar, there is no need to adjust for changes +in the frame of reference due to rotations of the particle pair. The formulation in +"Marshall"_#Marshall2009 therefore provides the most straightforward treatment: + +\begin\{equation\} +\tau_\{twist,0\} = -k_\{twist\}\xi_\{twist\} - \gamma_\{twist\}\Omega_\{twist\} +\end\{equation\} + +Here \(\xi_\{twist\} = \int_\{t_0\}^t \Omega_\{twist\} (\tau) \mathrm\{d\}\tau\) is the twisting +angular displacement, and \(\Omega_\{twist\} = (\mathbf\{\Omega\}_i - \mathbf\{\Omega\}_j) \cdot \mathbf\{n\}\) +is the relative twisting angular velocity. The torque is then truncated according to: + +\begin\{equation\} +\tau_\{twist\} = min(\mu_\{twist\} F_\{n,0\}, \tau_\{twist,0\}) +\end\{equation\} + +Similar to the sliding and rolling displacement, the angular displacement is +rescaled so that it corresponds to the critical value if the twisting torque +exceeds this critical value: + +\begin\{equation\} +\xi_\{twist\} = \frac\{1\}\{k_\{twist\}\} (\mu_\{twist\} F_\{n,0\}sgn(\Omega_\{twist\}) - \gamma_\{twist\}\Omega_\{twist\}) +\end\{equation\} + +For {twisting sds}, the coefficients \(k_\{twist\}, \gamma_\{twist\}\) and \(\mu_\{twist\}\) are +simply the user input parameters that follow the {twisting sds} keywords in the {pair_coeff} command. + +For {twisting_marshall}, the coefficients are expressed in terms of sliding friction coefficients, +as discussed in "Marshall"_#Marshall2009 (see equations 32 and 33 of that work): + +\begin\{equation\} +k_\{twist\} = 0.5k_ta^2 +\end\{equation\} + +\begin\{equation\} +\eta_\{twist\} = 0.5\eta_ta^2 +\end\{equation\} + +\begin\{equation\} +\mu_\{twist\} = \frac\{2\}\{3\}a\mu_t +\end\{equation\} + +Finally, the twisting torque on each particle is given by: + +\begin\{equation\} +\mathbf\{\tau\}_\{twist,i\} = \tau_\{twist\}\mathbf\{n\} +\end\{equation\} + +\begin\{equation\} +\mathbf\{\tau\}_\{twist,j\} = -\mathbf\{\tau\}_\{twist,i\} +\end\{equation\} + +:line + +LAMMPS automatically sets pairwise cutoff values for {pair_style granular} based on particle radii (and in the case +of {jkr} pulloff distances). In the vast majority of situations, this is adequate. +However, a cutoff value can optionally be appended to the {pair_style granular} command to specify +a global cutoff (i.e. a cutoff for all atom types). Additionally, the optional {cutoff} keyword +can be passed to the {pair_coeff} command, followed by a cutoff value. +This will set a pairwise cutoff for the atom types in the {pair_coeff} command. +These options may be useful in some rare cases where the automatic cutoff determination is not sufficient, e.g. +if particle diameters are being modified via the {fix adapt} command. In that case, the global cutoff +specified as part of the {pair_style granular} command is applied to all atom types, unless it is +overridden for a given atom type combination by the {cutoff} value specified in the {pair coeff} command. +If {cutoff} is only specified in the {pair coeff} command and no global +cutoff is appended to the {pair_style granular} command, then LAMMPS will use that cutoff for the specified +atom type combination, and automatically set pairwise cutoffs for the remaining atom types. + +:line + +Styles with a {gpu}, {intel}, {kk}, {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 on the "Speed packages"_Speed_packages.html doc +page. 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 GPU, USER-INTEL, KOKKOS, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the "Build +package"_Build_package.html doc page 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"_Run_options.html when you invoke LAMMPS, or you can use the +"suffix"_suffix.html command in your input script. + +See the "Speed packages"_Speed_packages.html doc page for more +instructions on how to use the accelerated styles effectively. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +The "pair_modify"_pair_modify.html mix, shift, table, and tail options +are not relevant for granular pair styles. + +Mixing of coefficients is carried out using geometric averaging for +most quantities, e.g. if friction coefficient for type 1-type 1 interactions +is set to \(\mu_1\), and friction coefficient for type 2-type 2 interactions +is set to \(\mu_2\), the friction coefficient for type1-type2 interactions +is computed as \(\sqrt\{\mu_1\mu_2\}\) (unless explictly specified to +a different value by a {pair_coeff 1 2 ...} command. The exception to this is +elastic modulus, only applicable to {hertz/material}, {dmt} and {jkr} normal +contact models. In that case, the effective elastic modulus is computed as: + +\begin\{equation\} +E_\{eff,ij\} = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\} +\end\{equation\} + +If the {i-j} coefficients \(E_\{ij\}\) and \(\nu_\{ij\}\) are explictly specified, +the effective modulus is computed as: + +\begin\{equation\} +E_\{eff,ij\} = \left(\frac\{1-\nu_\{ij\}^2\}\{E_\{ij\}\} + \frac\{1-\nu_\{ij\}^2\}\{E_\{ij\}\}\right)^\{-1\} +\end\{equation\} + +or + +\begin\{equation\} +E_\{eff,ij\} = \frac\{E_\{ij\}\}\{2(1-\nu_\{ij\})\} +\end\{equation\} + +These pair styles write their information to "binary restart +files"_restart.html, so a pair_style command does not need to be +specified in an input script that reads a restart file. + +These pair styles can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. They do not support the +{inner}, {middle}, {outer} keywords. + +The single() function of these pair styles returns 0.0 for the energy +of a pairwise interaction, since energy is not conserved in these +dissipative potentials. It also returns only the normal component of +the pairwise interaction force. However, the single() function also +calculates 10 extra pairwise quantities. The first 3 are the +components of the tangential force between particles I and J, acting +on particle I. The 4th is the magnitude of this tangential force. +The next 3 (5-7) are the components of the relative velocity in the +normal direction (along the line joining the 2 sphere centers). The +last 3 (8-10) the components of the relative velocity in the +tangential direction. + +These extra quantities can be accessed by the "compute +pair/local"_compute_pair_local.html command, as {p1}, {p2}, ..., +{p10}. + +:line + +[Restrictions:] + +All the granular pair styles are part of the GRANULAR package. It is +only enabled if LAMMPS was built with that package. See the "Build +package"_Build_package.html doc page for more info. + +These pair styles require that atoms store torque and angular velocity +(omega) as defined by the "atom_style"_atom_style.html. They also +require a per-particle radius is stored. The {sphere} atom style does +all of this. + +This pair style requires you to use the "comm_modify vel +yes"_comm_modify.html command so that velocities are stored by ghost +atoms. + +These pair styles will not restart exactly when using the +"read_restart"_read_restart.html command, though they should provide +statistically similar results. This is because the forces they +compute depend on atom velocities. See the +"read_restart"_read_restart.html command for more details. + +[Related commands:] + +"pair_coeff"_pair_coeff.html + +[Default:] + +For the {pair_coeff} settings: {damping viscoelastic}, {rolling none}, {twisting none} + +[References:] + + :link(Brill1996) [(Brilliantov et al, 1996)] Brilliantov, N. V., Spahn, F., Hertzsch, J. M., & Poschel, T. (1996). Model for collisions in granular gases. Physical review E, 53(5), 5382. @@ -236,5 +583,33 @@ Model for collisions in granular gases. Physical review E, 53(5), 5382. [(Tsuji et al, 1992)] Tsuji, Y., Tanaka, T., & Ishida, T. (1992). Lagrangian numerical simulation of plug flow of cohesionless particles in a horizontal pipe. Powder technology, 71(3), 239-250. + :link(JKR1971) + [(Johnson et al, 1971)] Johnson, K. L., Kendall, K., & Roberts, A. D. (1971). + Surface energy and the contact of elastic solids. Proc. R. Soc. Lond. A, 324(1558), 301-313. + + :link(DMT1975) + [Derjaguin et al, 1975)] Derjaguin, B. V., Muller, V. M., & Toporov, Y. P. (1975). Effect of contact deformations on the + adhesion of particles. Journal of Colloid and interface science, 53(2), 314-326. + + :link(Luding2008) + [(Luding, 2008)] Luding, S. (2008). Cohesive, frictional powders: contact models for tension. Granular matter, 10(4), 235. + + :link(Marshall2009) + [(Marshall, 2009)] Marshall, J. S. (2009). Discrete-element modeling of particulate aerosol flows. + Journal of Computational Physics, 228(5), 1541-1561. + + :link(Silbert2001) + [(Silbert, 2001)] Silbert, L. E., Ertas, D., Grest, G. S., Halsey, T. C., Levine, D., & Plimpton, S. J. (2001). + Granular flow down an inclined plane: Bagnold scaling and rheology. Physical Review E, 64(5), 051302. + + :link(Kuhn2004) + [(Kuhn and Bagi, 2005)] Kuhn, M. R., & Bagi, K. (2004). Contact rolling and deformation in granular media. + International journal of solids and structures, 41(21), 5793-5820. + + :link(Wang2015) + [(Wang et al, 2015)] Wang, Y., Alonso-Marroquin, F., & Guo, W. W. (2015). + Rolling and sliding in 3-D discrete element models. Particuology, 23, 49-55. - \ No newline at end of file + :link(Thornton1991) + [(Thornton, 1991)] Thornton, C. (1991). Interparticle sliding in the presence of adhesion. + J. Phys. D: Appl. Phys. 24 1942 \ No newline at end of file diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 3713b9251c..5631240fea 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -52,8 +52,8 @@ using namespace MathConst; enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; enum {VELOCITY, VISCOELASTIC, TSUJI}; enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN}; -enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; -enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; +enum {TWIST_NONE, TWIST_SDS, TWIST_MARSHALL}; +enum {ROLL_NONE, ROLL_SDS}; /* ---------------------------------------------------------------------- */ @@ -136,9 +136,9 @@ void PairGranular::compute(int eflag, int vflag) double wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; - double knfac, damp_normal; + double knfac, damp_normal, damp_normal_prefactor; double k_tangential, damp_tangential; - double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double Fne, Ft, Fdamp, Fntot, Fncrit, Fscrit, Frcrit; double fs, fs1, fs2, fs3; double mi,mj,meff,damp,ccel,tor1,tor2,tor3; @@ -324,10 +324,12 @@ void PairGranular::compute(int eflag, int vflag) } else{ knfac = E; //Hooke - Fne = knfac*delta; a = sqrt(dR); - if (normal_model[itype][jtype] != HOOKE) + if (normal_model[itype][jtype] != HOOKE){ Fne *= a; + knfac *= a; + } + Fne = knfac*delta; if (normal_model[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } @@ -343,7 +345,8 @@ void PairGranular::compute(int eflag, int vflag) damp_normal = sqrt(meff*knfac); } - Fdamp = -normal_coeffs[itype][jtype][1]*damp_normal*vnnr; + damp_normal_prefactor = normal_coeffs[itype][jtype][1]*damp_normal; + Fdamp = -damp_normal_prefactor*vnnr; Fntot = Fne + Fdamp; @@ -376,17 +379,21 @@ void PairGranular::compute(int eflag, int vflag) if (normal_model[itype][jtype] == JKR){ F_pulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*F_pulloff); + Fncrit = fabs(Fne + 2*F_pulloff); + } + else if (normal_model[itype][jtype] == DMT){ + F_pulloff = 4*M_PI*coh*Reff; + Fncrit = fabs(Fne + 2*F_pulloff); } else{ - Fcrit = fabs(Fne); + Fncrit = fabs(Fntot); } //------------------------------ //Tangential forces //------------------------------ k_tangential = tangential_coeffs[itype][jtype][0]; - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor; if (tangential_history){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + @@ -419,7 +426,7 @@ void PairGranular::compute(int eflag, int vflag) fs3 = -k_tangential*history[2] - damp_tangential*vtr3; // rescale frictional displacements and forces if needed - Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + Fscrit = tangential_coeffs[itype][jtype][2] * Fncrit; fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); if (fs > Fscrit) { if (shrmag != 0.0) { @@ -460,64 +467,53 @@ void PairGranular::compute(int eflag, int vflag) if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; else vrlmaginv = 0.0; - if (roll_history){ - int rhist0 = roll_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - - if (historyupdate){ - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - history[rhist0] -= rolldotn*nx; - history[rhist1] -= rolldotn*ny; - history[rhist2] -= rolldotn*nz; - //Also rescale to preserve magnitude - history[rhist0] *= scalefac; - history[rhist1] *= scalefac; - history[rhist2] *= scalefac; - } - history[rhist0] += vrl1*dt; - history[rhist1] += vrl2*dt; - history[rhist2] += vrl3*dt; - } + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - k_roll = roll_coeffs[itype][jtype][0]; - damp_roll = roll_coeffs[itype][jtype][1]; - fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; - fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; - fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; + if (historyupdate){ + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + history[rhist0] -= rolldotn*nx; + history[rhist1] -= rolldotn*ny; + history[rhist2] -= rolldotn*nz; + //Also rescale to preserve magnitude + history[rhist0] *= scalefac; + history[rhist1] *= scalefac; + history[rhist2] *= scalefac; } + history[rhist0] += vrl1*dt; + history[rhist1] += vrl2*dt; + history[rhist2] += vrl3*dt; } - else{ // - fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fncrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; } } @@ -527,30 +523,24 @@ void PairGranular::compute(int eflag, int vflag) if (twist_model[itype][jtype] != TWIST_NONE){ magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) if (twist_model[itype][jtype] == TWIST_MARSHALL){ - k_twist = 0.5*k_tangential*a*a;; //eq 32 + k_twist = 0.5*k_tangential*a*a;; //eq 32 of Marshall paper damp_twist = 0.5*damp_tangential*a*a; - mu_twist = TWOTHIRDS*a; + mu_twist = TWOTHIRDS*a*tangential_coeffs[itype][jtype][2]; } else{ k_twist = twist_coeffs[itype][jtype][0]; damp_twist = twist_coeffs[itype][jtype][1]; mu_twist = twist_coeffs[itype][jtype][2]; } - if (twist_model[itype][jtype] > 1){ - if (historyupdate){ - history[twist_history_index] += magtwist*dt; - } - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } + if (historyupdate){ + history[twist_history_index] += magtwist*dt; } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = mu_twist*Fncrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 } } // Apply forces & torques @@ -747,7 +737,7 @@ void PairGranular::coeff(int narg, char **arg) normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; } - else if (strcmp(arg[iarg], "damp") == 0){ + else if (strcmp(arg[iarg], "damping") == 0){ if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); if (strcmp(arg[iarg+1], "velocity") == 0){ damping_model_one = VELOCITY; @@ -757,10 +747,12 @@ void PairGranular::coeff(int narg, char **arg) damping_model_one = VISCOELASTIC; iarg += 1; } - else if (strcmp(arg[iarg], "tsuji") == 0){ + else if (strcmp(arg[iarg+1], "tsuji") == 0){ damping_model_one = TSUJI; iarg += 1; } + else error->all(FLERR, "Illegal pair_coeff command, unrecognized damping model"); + iarg += 1; } else if (strcmp(arg[iarg], "tangential") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); @@ -785,23 +777,18 @@ void PairGranular::coeff(int narg, char **arg) roll_model_one = ROLL_NONE; iarg += 2; } - else{ + else if (strcmp(arg[iarg+1], "sds") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - roll_model_one = ROLL_NOHISTORY; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ - roll_model_one = ROLL_SDS; - roll_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); - } + roll_model_one = ROLL_SDS; + roll_history = 1; roll_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kR roll_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR roll_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. iarg += 5; } + else{ + error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); + } } else if (strcmp(arg[iarg], "twisting") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); @@ -814,22 +801,17 @@ void PairGranular::coeff(int narg, char **arg) twist_history = 1; iarg += 2; } - else{ + else if (strcmp(arg[iarg+1], "sds") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - twist_model_one = TWIST_NOHISTORY; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ twist_model_one = TWIST_SDS; twist_history = 1; - } - else{ + twist_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt + twist_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + twist_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + else{ error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); - } - twist_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt - twist_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - twist_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; } } else if (strcmp(arg[iarg], "cutoff") == 0){ @@ -1063,7 +1045,6 @@ double PairGranular::init_one(int i, int j) for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - if (roll_model[i][j] != ROLL_NONE){ for (int k = 0; k < 3; k++) roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); @@ -1082,44 +1063,44 @@ double PairGranular::init_one(int i, int j) // if there is no current information about radius/cutoff of type i and j). // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. double pulloff; - if (cutoff_global < 0){ - if (cutoff_type[i][j] < 0){ - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || - ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - if (normal_model[i][j] == JKR){ - pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_dynamic[j], i, j); - cutoff += pulloff; - } - else{ - pulloff = 0; - } - - if (normal_model[i][j] == JKR) - pulloff = pulloff_distance(maxrad_frozen[i], maxrad_dynamic[j], i, j); - cutoff = MAX(cutoff, maxrad_frozen[i]+maxrad_dynamic[j]+pulloff); - if (normal_model[i][j] == JKR) - pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_frozen[j], i, j); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]+pulloff); + if (cutoff_type[i][j] < 0 && cutoff_global < 0){ + if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || + ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || + ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + if (normal_model[i][j] == JKR){ + pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_dynamic[j], i, j); + cutoff += pulloff; } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); - } - cutoff = cutmax; + else{ + pulloff = 0; } + + if (normal_model[i][j] == JKR) + pulloff = pulloff_distance(maxrad_frozen[i], maxrad_dynamic[j], i, j); + cutoff = MAX(cutoff, maxrad_frozen[i]+maxrad_dynamic[j]+pulloff); + + if (normal_model[i][j] == JKR) + pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_frozen[j], i, j); + cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]+pulloff); } - else{ - cutoff = cutoff_type[i][j]; + else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + double cutmax = 0.0; + for (int k = 1; k <= atom->ntypes; k++) { + cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); + cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); + } + cutoff = cutmax; } } - else{ + else if (cutoff_type[i][j] > 0){ + cutoff = cutoff_type[i][j]; + } + else if (cutoff_global > 0){ cutoff = cutoff_global; } + return cutoff; } @@ -1211,9 +1192,9 @@ double PairGranular::single(int i, int j, int itype, int jtype, double mi,mj,meff,damp,ccel,tor1,tor2,tor3; double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double knfac, damp_normal; + double knfac, damp_normal, damp_normal_prefactor; double k_tangential, damp_tangential; - double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; + double Fne, Ft, Fdamp, Fntot, Fncrit, Fscrit, Frcrit; double fs, fs1, fs2, fs3; //For JKR @@ -1357,10 +1338,12 @@ double PairGranular::single(int i, int j, int itype, int jtype, } else{ knfac = E; - Fne = knfac*delta; a = sqrt(dR); - if (normal_model[itype][jtype] != HOOKE) + if (normal_model[itype][jtype] != HOOKE){ Fne *= a; + knfac *= a; + } + Fne = knfac*delta; if (normal_model[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } @@ -1376,7 +1359,8 @@ double PairGranular::single(int i, int j, int itype, int jtype, damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); } - Fdamp = -damp_normal*vnnr; + damp_normal_prefactor = normal_coeffs[itype][jtype][1]*damp_normal; + Fdamp = -damp_normal_prefactor*vnnr; Fntot = Fne + Fdamp; @@ -1416,20 +1400,21 @@ double PairGranular::single(int i, int j, int itype, int jtype, if (normal_model[itype][jtype] == JKR){ F_pulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*F_pulloff); + Fncrit = fabs(Fne + 2*F_pulloff); + } + else if (normal_model[itype][jtype] == DMT){ + F_pulloff = 4*M_PI*coh*Reff; + Fncrit = fabs(Fne + 2*F_pulloff); } else{ - Fcrit = fabs(Fne); + Fncrit = fabs(Fntot); } //------------------------------ //Tangential forces //------------------------------ k_tangential = tangential_coeffs[itype][jtype][0]; - if (normal_model[itype][jtype] != HOOKE){ - k_tangential *= a; - } - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; + damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor; if (tangential_history){ shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + @@ -1441,7 +1426,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, fs3 = -k_tangential*history[2] - damp_tangential*vtr3; // rescale frictional displacements and forces if needed - Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; + Fscrit = tangential_coeffs[itype][jtype][2] * Fncrit; fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); if (fs > Fscrit) { if (shrmag != 0.0) { @@ -1482,47 +1467,38 @@ double PairGranular::single(int i, int j, int itype, int jtype, if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; else vrlmaginv = 0.0; - if (roll_history){ - int rhist0 = roll_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - - k_roll = roll_coeffs[itype][jtype][0]; - damp_roll = roll_coeffs[itype][jtype][1]; - fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; - fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; - fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - } - else{ // - fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + k_roll = roll_coeffs[itype][jtype][0]; + damp_roll = roll_coeffs[itype][jtype][1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[itype][jtype][2] * Fncrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; } + } //**************************************** @@ -1533,25 +1509,19 @@ double PairGranular::single(int i, int j, int itype, int jtype, if (twist_model[itype][jtype] == TWIST_MARSHALL){ k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; - mu_twist = TWOTHIRDS*a; + mu_twist = TWOTHIRDS*a*tangential_coeffs[itype][jtype][2];; } else{ k_twist = twist_coeffs[itype][jtype][0]; damp_twist = twist_coeffs[itype][jtype][1]; mu_twist = twist_coeffs[itype][jtype][2]; } - if (twist_history){ - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = mu_twist*Fncrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 } } -- GitLab From ff795e761a02300b790daa77ce98d806bdfc96b8 Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Tue, 19 Feb 2019 14:31:27 -0700 Subject: [PATCH 0139/1243] Added generalized granular option to fix wall/gran and fix wall/gran/region; some minor bug fixes for pair granular --- doc/src/pair_granular.txt | 13 +- src/GRANULAR/fix_wall_gran.cpp | 1038 ++++++++++++++++--------- src/GRANULAR/fix_wall_gran.h | 45 +- src/GRANULAR/fix_wall_gran_region.cpp | 105 +-- src/GRANULAR/fix_wall_gran_region.h | 2 +- src/GRANULAR/pair_granular.cpp | 55 +- src/GRANULAR/pair_granular.h | 4 +- 7 files changed, 788 insertions(+), 474 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index ff2ee94be0..911e3cc1dc 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -533,14 +533,16 @@ the pairwise interaction force. However, the single() function also calculates 10 extra pairwise quantities. The first 3 are the components of the tangential force between particles I and J, acting on particle I. The 4th is the magnitude of this tangential force. -The next 3 (5-7) are the components of the relative velocity in the -normal direction (along the line joining the 2 sphere centers). The -last 3 (8-10) the components of the relative velocity in the -tangential direction. +The next 3 (5-7) are the components of the rolling torque acting on +particle I. The next entry (8) is the magnitude of the rolling torque. +The next entry (9) is the magnitude of the twisting torque acting +about the vector connecting the two particle centers. +The last 3 (10-12) are the components of the vector connecting +the centers of the two particles (x_I - x_J). These extra quantities can be accessed by the "compute pair/local"_compute_pair_local.html command, as {p1}, {p2}, ..., -{p10}. +{p12}. :line @@ -568,6 +570,7 @@ compute depend on atom velocities. See the [Related commands:] "pair_coeff"_pair_coeff.html +"pair gran/*"_pair_gran.html [Default:] diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index d3129b7cdb..6e8cba7b4f 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -39,11 +39,24 @@ using namespace MathConst; // XYZ PLANE need to be 0,1,2 enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER,REGION}; -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,JKR_ROLLING,DMT_ROLLING}; +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,GRANULAR}; enum{NONE,CONSTANT,EQUAL}; -enum {TSUJI, BRILLIANTOV}; -enum {INDEP, BRILLROLL}; +#define PI27SQ 266.47931882941264802866 // 27*PI**2 +#define THREEROOT3 5.19615242270663202362 // 3*sqrt(3) +#define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) +#define INVROOT6 0.40824829046386307274 // 1/sqrt(6) +#define FOURTHIRDS 1.333333333333333 // 4/3 +#define THREEQUARTERS 0.75 // 3/4 +#define TWOPI 6.28318530717959 // 2*PI + +#define EPSILON 1e-10 + +enum {NORMAL_HOOKE, NORMAL_HERTZ, HERTZ_MATERIAL, DMT, JKR}; +enum {VELOCITY, VISCOELASTIC, TSUJI}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN}; +enum {TWIST_NONE, TWIST_SDS, TWIST_MARSHALL}; +enum {ROLL_NONE, ROLL_SDS}; #define BIG 1.0e20 #define EPSILON 1e-10 @@ -51,7 +64,7 @@ enum {INDEP, BRILLROLL}; /* ---------------------------------------------------------------------- */ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), idregion(NULL), shearone(NULL), fix_rigid(NULL), mass_rigid(NULL) + Fix(lmp, narg, arg), idregion(NULL), history_one(NULL), fix_rigid(NULL), mass_rigid(NULL) { if (narg < 4) error->all(FLERR,"Illegal fix wall/gran command"); @@ -66,19 +79,18 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[3],"hooke") == 0) pairstyle = HOOKE; else if (strcmp(arg[3],"hooke/history") == 0) pairstyle = HOOKE_HISTORY; else if (strcmp(arg[3],"hertz/history") == 0) pairstyle = HERTZ_HISTORY; - else if (strcmp(arg[3],"dmt/rolling") == 0) pairstyle = DMT_ROLLING; - //else if (strcmp(arg[3],"jkr/rolling") == 0) pairstyle = JKR_ROLLING; + else if (strcmp(arg[3],"granular") == 0) pairstyle = GRANULAR; else error->all(FLERR,"Invalid fix wall/gran interaction style"); - history = restart_peratom = 1; - if (pairstyle == HOOKE) history = restart_peratom = 0; + use_history = restart_peratom = 1; + if (pairstyle == HOOKE) use_history = restart_peratom = 0; // wall/particle coefficients int iarg; - if (pairstyle != JKR_ROLLING && pairstyle != DMT_ROLLING) { - sheardim = 3; + if (pairstyle != GRANULAR) { + size_history = 3; if (narg < 11) error->all(FLERR,"Illegal fix wall/gran command"); kn = force->numeric(FLERR,arg[4]); @@ -103,46 +115,157 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : kn /= force->nktv2p; kt /= force->nktv2p; } - iarg = 10; } else { - if (narg < 12) error->all(FLERR,"Illegal fix wall/gran command"); - - sheardim = 7; - Emod = force->numeric(FLERR,arg[4]); - Gmod = force->numeric(FLERR,arg[5]); - xmu = force->numeric(FLERR,arg[6]); - gamman = force->numeric(FLERR,arg[7]); - Ecoh = force->numeric(FLERR,arg[8]); - kR = force->numeric(FLERR,arg[9]); - muR = force->numeric(FLERR,arg[10]); - etaR = force->numeric(FLERR,arg[11]); - - //Defaults - normaldamp = TSUJI; - rollingdamp = INDEP; - - iarg = 12; - for (int iiarg=iarg; iiarg < narg; ++iiarg){ - if (strcmp(arg[iiarg], "normaldamp") == 0){ - if(iiarg+2 > narg) error->all(FLERR, "Invalid fix/wall/gran region command"); - if (strcmp(arg[iiarg+1],"tsuji") == 0){ - normaldamp = TSUJI; - alpha = gamman; + iarg = 4; + damping_model = VISCOELASTIC; + roll_model = twist_model = NONE; + while (iarg < narg){ + if (strcmp(arg[iarg], "hooke") == 0){ + if (iarg + 2 >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hooke option"); + normal_model = NORMAL_HOOKE; + normal_coeffs[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += 3; + } + else if (strcmp(arg[iarg], "hertz") == 0){ + int num_coeffs = 2; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hertz option"); + normal_model = NORMAL_HERTZ; + normal_coeffs[0] = force->numeric(FLERR,arg[iarg+1]); //kn + normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "hertz/material") == 0){ + int num_coeffs = 3; + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hertz option"); + normal_model = HERTZ_MATERIAL; + Emod = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping + poiss = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio + normal_coeffs[0] = Emod/(2*(1-poiss))*FOURTHIRDS; + normal_coeffs[2] = poiss; + iarg += num_coeffs+1; + } + else if (strcmp(arg[iarg], "dmt") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hertz option"); + normal_model = DMT; + Emod = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping + poiss = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio + normal_coeffs[0] = Emod/(2*(1-poiss))*FOURTHIRDS; + normal_coeffs[2] = poiss; + normal_coeffs[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "jkr") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal wall/gran command, not enough parameters provided for JKR option"); + beyond_contact = 1; + normal_model = JKR; + Emod = force->numeric(FLERR,arg[iarg+1]); //E + normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping + poiss = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio + normal_coeffs[0] = Emod/(2*(1-poiss))*FOURTHIRDS; + normal_coeffs[2] = poiss; + normal_coeffs[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion + iarg += 5; + } + else if (strcmp(arg[iarg], "damping") == 0){ + if (iarg+1 >= narg) error->all(FLERR, "Illegal wall/gran command, not enough parameters provided for damping model"); + if (strcmp(arg[iarg+1], "velocity") == 0){ + damping_model = VELOCITY; + iarg += 1; + } + else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ + damping_model = VISCOELASTIC; + iarg += 1; } - else if (strcmp(arg[iiarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for fix wall/gran dmt/rolling"); - iarg += 2; + else if (strcmp(arg[iarg+1], "tsuji") == 0){ + damping_model = TSUJI; + iarg += 1; + } + else error->all(FLERR, "Illegal wall/gran command, unrecognized damping model"); + iarg += 1; } - if (strcmp(arg[iiarg], "rollingdamp") == 0){ - if(iiarg+2 > narg) error->all(FLERR, "Invalid fix/wall/gran region command"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for fix wall/gran dmt/rolling"); - iarg += 2; + else if (strcmp(arg[iarg], "tangential") == 0){ + if (iarg + 1 >= narg) error->all(FLERR,"Illegal pair_coeff command, must specify tangential model after 'tangential' keyword"); + if (strcmp(arg[iarg+1], "linear_nohistory") == 0){ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + tangential_model = TANGENTIAL_NOHISTORY; + tangential_coeffs[0] = 0; + tangential_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + tangential_coeffs[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; + } + else if (strcmp(arg[iarg+1], "linear_history") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + tangential_model = TANGENTIAL_HISTORY; + tangential_history = 1; + tangential_coeffs[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + else{ + error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); + } + } + else if (strcmp(arg[iarg], "rolling") == 0){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal wall/gran command, not enough parameters"); + if (strcmp(arg[iarg+1], "none") == 0){ + roll_model = ROLL_NONE; + iarg += 2; + } + else if (strcmp(arg[iarg+1], "sds") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal wall/gran command, not enough parameters provided for rolling model"); + roll_model = ROLL_SDS; + roll_history = 1; + roll_coeffs[0] = force->numeric(FLERR,arg[iarg+2]); //kR + roll_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR + roll_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. + iarg += 5; + } + else{ + error->all(FLERR, "Illegal wall/gran command, rolling friction model not recognized"); + } + } + else if (strcmp(arg[iarg], "twisting") == 0){ + if (iarg + 1 >= narg) error->all(FLERR, "Illegal wall/gran command, not enough parameters"); + if (strcmp(arg[iarg+1], "none") == 0){ + twist_model = TWIST_NONE; + iarg += 2; + } + else if (strcmp(arg[iarg+1], "marshall") == 0){ + twist_model = TWIST_MARSHALL; + twist_history = 1; + iarg += 2; + } + else if (strcmp(arg[iarg+1], "sds") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal wall/gran command, not enough parameters provided for twist model"); + twist_model = TWIST_SDS; + twist_history = 1; + twist_coeffs[0] = force->numeric(FLERR,arg[iarg+2]); //kt + twist_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + twist_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; + } + else{ + error->all(FLERR, "Illegal wall/gran command, twisting friction model not recognized"); + } + } + else if (strcmp(arg[iarg], "xplane") == 0 || + strcmp(arg[iarg], "yplane") == 0 || + strcmp(arg[iarg], "zplane") == 0 || + strcmp(arg[iarg], "zcylinder") == 0 || + strcmp(arg[iarg], "region") == 0){ + break; + } + else{ + error->all(FLERR, "Illegal fix wall/gran command"); } } + size_history = (normal_model == JKR) + 3*tangential_history + 3*roll_history + twist_history; } // wallstyle args @@ -216,11 +339,10 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : iarg += 3; } else if (strcmp(arg[iarg],"store_contacts") == 0){ peratom_flag = 1; - size_peratom_cols = 8; //Could make this a user input option? + size_peratom_cols = 8; peratom_freq = 1; iarg += 1; } else error->all(FLERR,"Illegal fix wall/gran command"); - } if (wallstyle == XPLANE && domain->xperiodic) @@ -252,7 +374,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : // perform initial allocation of atom-based arrays // register with Atom class - shearone = NULL; + history_one = NULL; grow_arrays(atom->nmax); atom->add_callback(0); atom->add_callback(1); @@ -260,14 +382,14 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : nmax = 0; mass_rigid = NULL; - // initialize shear history as if particle is not touching region - // shearone will be NULL for wallstyle = REGION + // initialize history as if particle is not touching region + // history_one will be NULL for wallstyle = REGION - if (history && shearone) { + if (use_history && history_one) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) - for (int j = 0; j < sheardim; j++) - shearone[i][j] = 0.0; + for (int j = 0; j < size_history; j++) + history_one[i][j] = 0.0; } if (peratom_flag){ @@ -292,7 +414,7 @@ FixWallGran::~FixWallGran() // delete local storage delete [] idregion; - memory->destroy(shearone); + memory->destroy(history_one); memory->destroy(mass_rigid); } @@ -323,6 +445,34 @@ void FixWallGran::init() for (i = 0; i < modify->nfix; i++) if (modify->fix[i]->rigid_flag) break; if (i < modify->nfix) fix_rigid = modify->fix[i]; + + tangential_history_index = 0; + if (roll_history){ + if (tangential_history) roll_history_index = 3; + else roll_history_index = 0; + } + if (twist_history){ + if (tangential_history){ + if (roll_history) twist_history_index = 6; + else twist_history_index = 3; + } + else{ + if (roll_history) twist_history_index = 3; + else twist_history_index = 0; + } + } + if (normal_model == JKR){ + tangential_history_index += 1; + roll_history_index += 1; + twist_history_index += 1; + } + + if (damping_model == TSUJI){ + double cor = normal_coeffs[1]; + normal_coeffs[1] = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ + 27.467*pow(cor,4)-18.022*pow(cor,5)+ + 4.8218*pow(cor,6); + } } /* ---------------------------------------------------------------------- */ @@ -346,10 +496,10 @@ void FixWallGran::post_force(int /*vflag*/) double dx,dy,dz,del1,del2,delxy,delr,rsq,rwall,meff; double vwall[3]; - // do not update shear history during setup + // do not update history during setup - shearupdate = 1; - if (update->setupflag) shearupdate = 0; + history_update = 1; + if (update->setupflag) history_update = 0; // if just reneighbored: // update rigid body masses for owned atoms if using FixRigid @@ -395,7 +545,7 @@ void FixWallGran::post_force(int /*vflag*/) // if wall was set to NULL, it's skipped since lo/hi are infinity // compute force and torque on atom if close enough to wall // via wall potential matched to pair potential - // set shear if pair potential stores history + // set history if pair potential stores history double **x = atom->x; double **v = atom->v; @@ -450,12 +600,27 @@ void FixWallGran::post_force(int /*vflag*/) rsq = dx*dx + dy*dy + dz*dz; - if (rsq > radius[i]*radius[i]) { - if (history) - for (j = 0; j < sheardim; j++) - shearone[i][j] = 0.0; + double rad; + if (pairstyle == GRANULAR && normal_model == JKR){ + rad = radius[i] + pulloff_distance(radius[i]); + } + else + rad = radius[i]; - } else { + if (rsq > rad*rad) { + if (use_history) + for (j = 0; j < size_history; j++) + history_one[i][j] = 0.0; + } + else { + if (pairstyle == GRANULAR && normal_model == JKR && use_history){ + if ((history_one[i][0] == 0) && (rsq > radius[i]*radius[i])){ + // Particles have not contacted yet, and are outside of contact distance + for (j = 0; j < size_history; j++) + history_one[i][j] = 0.0; + continue; + } + } // meff = effective mass of sphere // if I is part of rigid body, use body mass @@ -484,20 +649,16 @@ void FixWallGran::post_force(int /*vflag*/) omega[i],torque[i],radius[i],meff, contact); else if (pairstyle == HOOKE_HISTORY) hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], + omega[i],torque[i],radius[i],meff,history_one[i], contact); else if (pairstyle == HERTZ_HISTORY) hertz_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], + omega[i],torque[i],radius[i],meff,history_one[i], contact); - else if (pairstyle == DMT_ROLLING) - dmt_rolling(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], + else if (pairstyle == GRANULAR) + granular(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], + omega[i],torque[i],radius[i],meff,history_one[i], contact); - /*else if (pairstyle == JKR_ROLLING) - jkr_rolling(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i], - contact);*/ } } } @@ -605,7 +766,7 @@ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, double *vwall, double *v, double *f, double *omega, double *torque, - double radius, double meff, double *shear, + double radius, double meff, double *history, double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; @@ -657,28 +818,28 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, // shear history effects - if (shearupdate) { - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; + if (history_update) { + history[0] += vtr1*dt; + history[1] += vtr2*dt; + history[2] += vtr3*dt; } - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); // rotate shear displacements - rsht = shear[0]*dx + shear[1]*dy + shear[2]*dz; + rsht = history[0]*dx + history[1]*dy + history[2]*dz; rsht = rsht*rsqinv; - if (shearupdate) { - shear[0] -= rsht*dx; - shear[1] -= rsht*dy; - shear[2] -= rsht*dz; + if (history_update) { + history[0] -= rsht*dx; + history[1] -= rsht*dy; + history[2] -= rsht*dz; } // 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); + fs1 = - (kt*history[0] + meff*gammat*vtr1); + fs2 = - (kt*history[1] + meff*gammat*vtr2); + fs3 = - (kt*history[2] + meff*gammat*vtr3); // rescale frictional displacements and forces if needed @@ -687,11 +848,11 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, if (fs > fn) { if (shrmag != 0.0) { - shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) - + history[0] = (fn/fs) * (history[0] + meff*gammat*vtr1/kt) - meff*gammat*vtr1/kt; - shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) - + history[1] = (fn/fs) * (history[1] + meff*gammat*vtr2/kt) - meff*gammat*vtr2/kt; - shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) - + history[2] = (fn/fs) * (history[2] + meff*gammat*vtr3/kt) - meff*gammat*vtr3/kt; fs1 *= fn/fs ; fs2 *= fn/fs; @@ -728,7 +889,7 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, double *vwall, double rwall, double *v, double *f, double *omega, double *torque, - double radius, double meff, double *shear, + double radius, double meff, double *history, double *contact) { double r,vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; @@ -787,28 +948,28 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, // shear history effects - if (shearupdate) { - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; + if (history_update) { + history[0] += vtr1*dt; + history[1] += vtr2*dt; + history[2] += vtr3*dt; } - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); - // rotate shear displacements + // rotate history displacements - rsht = shear[0]*dx + shear[1]*dy + shear[2]*dz; + rsht = history[0]*dx + history[1]*dy + history[2]*dz; rsht = rsht*rsqinv; - if (shearupdate) { - shear[0] -= rsht*dx; - shear[1] -= rsht*dy; - shear[2] -= rsht*dz; + if (history_update) { + history[0] -= rsht*dx; + history[1] -= rsht*dy; + history[2] -= rsht*dz; } // 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); + fs1 = -polyhertz * (kt*history[0] + meff*gammat*vtr1); + fs2 = -polyhertz * (kt*history[1] + meff*gammat*vtr2); + fs3 = -polyhertz * (kt*history[2] + meff*gammat*vtr3); // rescale frictional displacements and forces if needed @@ -817,11 +978,11 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, if (fs > fn) { if (shrmag != 0.0) { - shear[0] = (fn/fs) * (shear[0] + meff*gammat*vtr1/kt) - + history[0] = (fn/fs) * (history[0] + meff*gammat*vtr1/kt) - meff*gammat*vtr1/kt; - shear[1] = (fn/fs) * (shear[1] + meff*gammat*vtr2/kt) - + history[1] = (fn/fs) * (history[1] + meff*gammat*vtr2/kt) - meff*gammat*vtr2/kt; - shear[2] = (fn/fs) * (shear[2] + meff*gammat*vtr3/kt) - + history[2] = (fn/fs) * (history[2] + meff*gammat*vtr3/kt) - meff*gammat*vtr3/kt; fs1 *= fn/fs ; fs2 *= fn/fs; @@ -854,268 +1015,366 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, } -void FixWallGran::dmt_rolling(double rsq, double dx, double dy, double dz, +void FixWallGran::granular(double rsq, double dx, double dy, double dz, double *vwall, double rwall, double *v, double *f, double *omega, double *torque, - double radius, double meff, double *shear, + double radius, double meff, double *history, double *contact) { - int i,j,ii,jj,inum,jnum; - int itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,r,rinv,rsqinv,R,a; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; - double Fhz, Fdamp, Fdmt, Fne, Fntot, Fscrit, Frcrit; - double overlap; - double mi,mj,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - double signtwist, magtwist, magtortwist, Mtcrit; - double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; - double tortwist1, tortwist2, tortwist3; - double shrmag,rsht; - - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - - radsum = radius + rwall; - if (rwall == 0) R = radius; - else R = radius*rwall/(radius+rwall); - - nx = dx*rinv; - ny = dy*rinv; - nz = dz*rinv; - - // relative translational velocity - - vr1 = v[0] - vwall[0]; - vr2 = v[1] - vwall[1]; - vr3 = v[2] - vwall[2]; - - // normal component - - vnnr = vr1*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - - //**************************************** - //Normal force = Hertzian contact + DMT + damping - //**************************************** - overlap = radsum - r; - a = sqrt(R*overlap); - kn = 4.0/3.0*Emod*a; - Fhz = kn*overlap; - - //Damping (based on Tsuji et al) - if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman; - else if (normaldamp == TSUJI) eta_N=alpha*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - //DMT - Fdmt = -4*MY_PI*Ecoh*R; - - Fne = Fhz + Fdmt; - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including shear history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - wr1 = radius*omega[0] * rinv; - wr2 = radius*omega[1] * rinv; - wr3 = radius*omega[2] * rinv; - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // Rotate and update shear displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (shearupdate) { - rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - shear[0] -= rsht*nx; - shear[1] -= rsht*ny; - shear[2] -= rsht*nz; - //Also rescale to preserve magnitude - shear[0] *= scalefac; - shear[1] *= scalefac; - shear[2] *= scalefac; - } - //Update shear history - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; - } - - // tangential forces = shear + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*Gmod*a; - - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = xmu * fabs(Fne); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + shear[2]*shear[2]); - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - //**************************************** - // Rolling force, including shear history effects - //**************************************** - - relrot1 = omega[0]; //- omega[j][0]; TODO: figure out how to - relrot2 = omega[1]; //- omega[j][1]; incorporate wall angular - relrot3 = omega[2]; //- omega[j][2]; velocity - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - - if (shearupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - shear[3] -= rolldotn*nx; - shear[4] -= rolldotn*ny; - shear[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - shear[3] *= scalefac; - shear[4] *= scalefac; - shear[5] *= scalefac; - } - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; - } - - if (rollingdamp == BRILLROLL) etaR = muR*fabs(Fne); - fr1 = -kR*shear[3] - etaR*vrl1; - fr2 = -kR*shear[4] - etaR*vrl2; - fr3 = -kR*shear[5] - etaR*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR * fabs(Fne); - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - shear[3] = -1.0/kR*(Frcrit*fr1/fr + etaR*vrl1); - shear[4] = -1.0/kR*(Frcrit*fr2/fr + etaR*vrl2); - shear[5] = -1.0/kR*(Frcrit*fr3/fr + etaR*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - - - //**************************************** - // Twisting torque, including shear history effects - //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - shear[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit){ - shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[0] += fx; - f[1] += fy; - f[2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[0] -= radi*tor1; - torque[1] -= radi*tor2; - torque[2] -= radi*tor3; - - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[0] += tortwist1; - torque[1] += tortwist2; - torque[2] += tortwist3; - - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); - - torque[0] += torroll1; - torque[1] += torroll2; - torque[2] += torroll3; - + int i,j,ii,jj,inum,jnum,itype,jtype; + double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; + double radi,radj,radsum,r,rinv,rsqinv; + double Reff, delta, dR, dR2; + + double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; + double wr1,wr2,wr3; + double vtr1,vtr2,vtr3,vrel; + + double knfac, damp_normal, damp_normal_prefactor; + double k_tangential, damp_tangential; + double Fne, Ft, Fdamp, Fntot, Fncrit, Fscrit, Frcrit; + double fs, fs1, fs2, fs3; + + double mi,mj,damp,ccel,tor1,tor2,tor3; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + + //For JKR + double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double t0, t1, t2, t3, t4, t5, t6; + double sqrt1, sqrt2, sqrt3, sqrt4; + + //Rolling + double k_roll, damp_roll; + double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double rollmag, rolldotn, scalefac; + double fr, fr1, fr2, fr3; + + //Twisting + double k_twist, damp_twist, mu_twist; + double signtwist, magtwist, magtortwist, Mtcrit; + double tortwist1, tortwist2, tortwist3; + + double shrmag,rsht; + int *ilist,*jlist,*numneigh,**firstneigh; + int *touch,**firsttouch; + double *allhistory,**firsthistory; + + r = sqrt(rsq); + radsum = rwall + radius; + + E = normal_coeffs[0]; + + radsum = radius + rwall; + if (rwall == 0) Reff = radius; + else Reff = radius*rwall/(radius+rwall); + + rinv = 1.0/r; + + nx = dx*rinv; + ny = dy*rinv; + nz = dz*rinv; + + // relative translational velocity + + vr1 = v[0] - vwall[0]; + vr2 = v[1] - vwall[1]; + vr3 = v[2] - vwall[2]; + + // normal component + + vnnr = vr1*nx + vr2*ny + vr3*nz; //v_R . n + vn1 = nx*vnnr; + vn2 = ny*vnnr; + vn3 = nz*vnnr; + + delta = radsum - r; + dR = delta*Reff; + if (normal_model == JKR){ + history[0] = 1.0; + E *= THREEQUARTERS; + R2=Reff*Reff; + coh = normal_coeffs[3]; + dR2 = dR*dR; + t0 = coh*coh*R2*R2*E; + t1 = PI27SQ*t0; + t2 = 8*dR*dR2*E*E*E; + t3 = 4*dR2*E; + sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues + t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); + t5 = t3/t4 + t4/E; + sqrt2 = MAX(0, 2*dR + t5); + t6 = sqrt(sqrt2); + sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); + a = INVROOT6*(t6 + sqrt(sqrt3)); + a2 = a*a; + knfac = normal_coeffs[0]*a; + Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); + } + else{ + knfac = E; //Hooke + a = sqrt(dR); + if (normal_model != HOOKE){ + Fne *= a; + knfac *= a; + } + Fne = knfac*delta; + if (normal_model == DMT) + Fne -= 4*MY_PI*normal_coeffs[3]*Reff; + } + + if (damping_model == VELOCITY){ + damp_normal = 1; + } + else if (damping_model == VISCOELASTIC){ + damp_normal = a*meff; + } + else if (damping_model == TSUJI){ + damp_normal = sqrt(meff*knfac); + } + + damp_normal_prefactor = normal_coeffs[1]*damp_normal; + Fdamp = -damp_normal_prefactor*vnnr; + + Fntot = Fne + Fdamp; + + //**************************************** + //Tangential force, including history effects + //**************************************** + + // tangential component + vt1 = vr1 - vn1; + vt2 = vr2 - vn2; + vt3 = vr3 - vn3; + + // relative rotational velocity + wr1 = radius*omega[0] * rinv; + wr2 = radius*omega[1] * rinv; + wr3 = radius*omega[2] * rinv; + + // relative tangential velocities + vtr1 = vt1 - (nz*wr2-ny*wr3); + vtr2 = vt2 - (nx*wr3-nz*wr1); + vtr3 = vt3 - (ny*wr1-nx*wr2); + vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; + vrel = sqrt(vrel); + + if (normal_model == JKR){ + F_pulloff = 3*M_PI*coh*Reff; + Fncrit = fabs(Fne + 2*F_pulloff); + } + else if (normal_model == DMT){ + F_pulloff = 4*M_PI*coh*Reff; + Fncrit = fabs(Fne + 2*F_pulloff); + } + else{ + Fncrit = fabs(Fntot); + } + + //------------------------------ + //Tangential forces + //------------------------------ + k_tangential = tangential_coeffs[0]; + damp_tangential = tangential_coeffs[1]*damp_normal_prefactor; + + int thist0 = tangential_history_index; + int thist1 = thist0 + 1; + int thist2 = thist1 + 1; + + if (tangential_history){ + shrmag = sqrt(history[thist0]*history[thist0] + history[thist1]*history[thist1] + + history[thist2]*history[thist2]); + + // Rotate and update displacements. + // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 + if (history_update) { + rsht = history[thist0]*nx + history[thist1]*ny + history[thist2]*nz; + if (fabs(rsht) < EPSILON) rsht = 0; + if (rsht > 0){ + scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + history[thist0] -= rsht*nx; + history[thist1] -= rsht*ny; + history[thist2] -= rsht*nz; + //Also rescale to preserve magnitude + history[thist0] *= scalefac; + history[thist1] *= scalefac; + history[thist2] *= scalefac; + } + //Update history + history[thist0] += vtr1*dt; + history[thist1] += vtr2*dt; + history[thist2] += vtr3*dt; + } + + // tangential forces = history + tangential velocity damping + fs1 = -k_tangential*history[thist0] - damp_tangential*vtr1; + fs2 = -k_tangential*history[thist1] - damp_tangential*vtr2; + fs3 = -k_tangential*history[thist2] - damp_tangential*vtr3; + + // rescale frictional displacements and forces if needed + Fscrit = tangential_coeffs[2] * Fncrit; + fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); + if (fs > Fscrit) { + if (shrmag != 0.0) { + history[thist0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); + history[thist1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); + history[thist2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); + fs1 *= Fscrit/fs; + fs2 *= Fscrit/fs; + fs3 *= Fscrit/fs; + } else fs1 = fs2 = fs3 = 0.0; + } + } + else{ //Classic pair gran/hooke (no history) + fs = meff*damp_tangential*vrel; + if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; + else Ft = 0.0; + fs1 = -Ft*vtr1; + fs2 = -Ft*vtr2; + fs3 = -Ft*vtr3; + } + + //**************************************** + // Rolling resistance + //**************************************** + + if (roll_model != ROLL_NONE){ + relrot1 = omega[0]; + relrot2 = omega[1]; + relrot3 = omega[2]; + + // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) + // This is different from the Marshall papers, which use the Bagi/Kuhn formulation + // for rolling velocity (see Wang et al for why the latter is wrong) + vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; + vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; + vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; + vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); + if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; + else vrlmaginv = 0.0; + + int rhist0 = roll_history_index; + int rhist1 = rhist0 + 1; + int rhist2 = rhist1 + 1; + + // Rolling displacement + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); + + rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; + + if (history_update){ + if (fabs(rolldotn) < EPSILON) rolldotn = 0; + if (rolldotn > 0){ //Rotate into tangential plane + scalefac = rollmag/(rollmag - rolldotn); + history[rhist0] -= rolldotn*nx; + history[rhist1] -= rolldotn*ny; + history[rhist2] -= rolldotn*nz; + //Also rescale to preserve magnitude + history[rhist0] *= scalefac; + history[rhist1] *= scalefac; + history[rhist2] *= scalefac; + } + history[rhist0] += vrl1*dt; + history[rhist1] += vrl2*dt; + history[rhist2] += vrl3*dt; + } + + k_roll = roll_coeffs[0]; + damp_roll = roll_coeffs[1]; + fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; + fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; + fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; + + // rescale frictional displacements and forces if needed + Frcrit = roll_coeffs[2] * Fncrit; + + fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); + if (fr > Frcrit) { + if (rollmag != 0.0) { + history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); + history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); + history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); + fr1 *= Frcrit/fr; + fr2 *= Frcrit/fr; + fr3 *= Frcrit/fr; + } else fr1 = fr2 = fr3 = 0.0; + } + } + + //**************************************** + // Twisting torque, including history effects + //**************************************** + if (twist_model != TWIST_NONE){ + magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) + if (twist_model == TWIST_MARSHALL){ + k_twist = 0.5*k_tangential*a*a;; //eq 32 of Marshall paper + damp_twist = 0.5*damp_tangential*a*a; + mu_twist = TWOTHIRDS*a*tangential_coeffs[2]; + } + else{ + k_twist = twist_coeffs[0]; + damp_twist = twist_coeffs[1]; + mu_twist = twist_coeffs[2]; + } + if (history_update){ + history[twist_history_index] += magtwist*dt; + } + magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) + signtwist = (magtwist > 0) - (magtwist < 0); + Mtcrit = mu_twist*Fncrit;//critical torque (eq 44) + if (fabs(magtortwist) > Mtcrit) { + history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); + magtortwist = -Mtcrit * signtwist; //eq 34 + } + } + // Apply forces & torques + + fx = nx*Fntot + fs1; + fy = ny*Fntot + fs2; + fz = nz*Fntot + fs3; + + if (peratom_flag){ + contact[1] = fx; + contact[2] = fy; + contact[3] = fz; + } + + f[0] += fx; + f[1] += fy; + f[2] += fz; + + tor1 = ny*fs3 - nz*fs2; + tor2 = nz*fs1 - nx*fs3; + tor3 = nx*fs2 - ny*fs1; + + torque[0] -= radius*tor1; + torque[1] -= radius*tor2; + torque[2] -= radius*tor3; + + if (twist_model != TWIST_NONE){ + tortwist1 = magtortwist * nx; + tortwist2 = magtortwist * ny; + tortwist3 = magtortwist * nz; + + torque[0] += tortwist1; + torque[1] += tortwist2; + torque[2] += tortwist3; + } + + if (roll_model != ROLL_NONE){ + torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr + torroll2 = Reff*(nz*fr1 - nx*fr3); + torroll3 = Reff*(nx*fr2 - ny*fr1); + + torque[0] += torroll1; + torque[1] += torroll2; + torque[2] += torroll3; + } } + /* ---------------------------------------------------------------------- memory usage of local atom-based arrays ------------------------------------------------------------------------- */ @@ -1124,7 +1383,7 @@ double FixWallGran::memory_usage() { int nmax = atom->nmax; double bytes = 0.0; - if (history) bytes += nmax*sheardim * sizeof(double); // shear history + if (use_history) bytes += nmax*size_history * sizeof(double); // shear history if (fix_rigid) bytes += nmax * sizeof(int); // mass_rigid if (peratom_flag) bytes += nmax*size_peratom_cols*sizeof(double); //store contacts return bytes; @@ -1136,7 +1395,7 @@ double FixWallGran::memory_usage() void FixWallGran::grow_arrays(int nmax) { - if (history) memory->grow(shearone,nmax,sheardim,"fix_wall_gran:shearone"); + if (use_history) memory->grow(history_one,nmax,size_history,"fix_wall_gran:history_one"); if (peratom_flag){ memory->grow(array_atom,nmax,size_peratom_cols,"fix_wall_gran:array_atom"); } @@ -1148,9 +1407,9 @@ void FixWallGran::grow_arrays(int nmax) void FixWallGran::copy_arrays(int i, int j, int /*delflag*/) { - if (history) - for (int m = 0; m < sheardim; m++) - shearone[j][m] = shearone[i][m]; + if (use_history) + for (int m = 0; m < size_history; m++) + history_one[j][m] = history_one[i][m]; if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) array_atom[j][m] = array_atom[i][m]; @@ -1163,9 +1422,9 @@ void FixWallGran::copy_arrays(int i, int j, int /*delflag*/) void FixWallGran::set_arrays(int i) { - if (history) - for (int m = 0; m < sheardim; m++) - shearone[i][m] = 0; + if (use_history) + for (int m = 0; m < size_history; m++) + history_one[i][m] = 0; if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) array_atom[i][m] = 0; @@ -1179,9 +1438,9 @@ void FixWallGran::set_arrays(int i) int FixWallGran::pack_exchange(int i, double *buf) { int n = 0; - if (history){ - for (int m = 0; m < sheardim; m++) - buf[n++] = shearone[i][m]; + if (use_history){ + for (int m = 0; m < size_history; m++) + buf[n++] = history_one[i][m]; } if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) @@ -1197,9 +1456,9 @@ int FixWallGran::pack_exchange(int i, double *buf) int FixWallGran::unpack_exchange(int nlocal, double *buf) { int n = 0; - if (history){ - for (int m = 0; m < sheardim; m++) - shearone[nlocal][m] = buf[n++]; + if (use_history){ + for (int m = 0; m < size_history; m++) + history_one[nlocal][m] = buf[n++]; } if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) @@ -1214,12 +1473,12 @@ int FixWallGran::unpack_exchange(int nlocal, double *buf) int FixWallGran::pack_restart(int i, double *buf) { - if (!history) return 0; + if (!use_history) return 0; int n = 0; - buf[n++] = sheardim + 1; - for (int m = 0; m < sheardim; m++) - buf[n++] = shearone[i][m]; + buf[n++] = size_history + 1; + for (int m = 0; m < size_history; m++) + buf[n++] = history_one[i][m]; return n; } @@ -1229,7 +1488,7 @@ int FixWallGran::pack_restart(int i, double *buf) void FixWallGran::unpack_restart(int nlocal, int nth) { - if (!history) return; + if (!use_history) return; double **extra = atom->extra; @@ -1239,8 +1498,8 @@ void FixWallGran::unpack_restart(int nlocal, int nth) for (int i = 0; i < nth; i++) m += static_cast (extra[nlocal][m]); m++; - for (int i = 0; i < sheardim; i++) - shearone[nlocal][i] = extra[nlocal][m++]; + for (int i = 0; i < size_history; i++) + history_one[nlocal][i] = extra[nlocal][m++]; } /* ---------------------------------------------------------------------- @@ -1249,8 +1508,8 @@ void FixWallGran::unpack_restart(int nlocal, int nth) int FixWallGran::maxsize_restart() { - if (!history) return 0; - return 1 + sheardim; + if (!use_history) return 0; + return 1 + size_history; } /* ---------------------------------------------------------------------- @@ -1259,8 +1518,8 @@ int FixWallGran::maxsize_restart() int FixWallGran::size_restart(int /*nlocal*/) { - if (!history) return 0; - return 1 + sheardim; + if (!use_history) return 0; + return 1 + size_history; } /* ---------------------------------------------------------------------- */ @@ -1270,3 +1529,12 @@ void FixWallGran::reset_dt() dt = update->dt; } +double FixWallGran::pulloff_distance(double radius){ + double coh, E, a, dist; + coh = normal_coeffs[3]; + E = normal_coeffs[0]*THREEQUARTERS; + a = cbrt(9*M_PI*coh*radius/(4*E)); + dist = a*a/radius - 2*sqrt(M_PI*coh*a/E); + return dist; +} + diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran.h index 4212b96544..07c6c131cf 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran.h @@ -54,12 +54,11 @@ class FixWallGran : public Fix { void hertz_history(double, double, double, double, double *, double, double *, double *, double *, double *, double, double, double *, double *); - void dmt_rolling(double, double, double, double, double *, double, - double *, double *, double *, double *, double, double, - double *, double *); - // void jkr_rolling(double, double, double, double, double *, double, - // double *, double *, double *, double *, double, double, - // double *, double *); + void granular(double, double, double, double, double *, double, + double *, double *, double *, double *, double, double, + double *, double *); + + double pulloff_distance(double); protected: int wallstyle,wiggle,wshear,axis; @@ -67,23 +66,43 @@ class FixWallGran : public Fix { bigint time_origin; double kn,kt,gamman,gammat,xmu; - //For DMT/ROLLING - int normaldamp, rollingdamp; - double Emod, Gmod, alpha, Ecoh, kR, muR, etaR; + //For granular + //Model choices + int normal_model, damping_model; + int tangential_model, roll_model, twist_model; + + int beyond_contact; + + //History flags + int normal_history, tangential_history, roll_history, twist_history; + + //Indices of history entries + int normal_history_index; + int tangential_history_index; + int roll_history_index; + int twist_history_index; + + //Material coefficients + double Emod, poiss, Gmod; + //Contact model coefficients + double normal_coeffs[4]; + double tangential_coeffs[3]; + double roll_coeffs[3]; + double twist_coeffs[3]; double lo,hi,cylradius; double amplitude,period,omega,vshear; double dt; char *idregion; - int history; // if particle/wall interaction stores history - int shearupdate; // flag for whether shear history is updated - int sheardim; // # of shear history values per contact + int use_history; // if particle/wall interaction stores history + int history_update; // flag for whether shear history is updated + int size_history; // # of shear history values per contact // shear history for single contact per particle - double **shearone; + double **history_one; // rigid body masses for use in granular interactions diff --git a/src/GRANULAR/fix_wall_gran_region.cpp b/src/GRANULAR/fix_wall_gran_region.cpp index 17e16cb16b..95b34e0929 100644 --- a/src/GRANULAR/fix_wall_gran_region.cpp +++ b/src/GRANULAR/fix_wall_gran_region.cpp @@ -39,7 +39,8 @@ using namespace MathConst; // same as FixWallGran -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,JKR_ROLLING,DMT_ROLLING}; +enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,GRANULAR}; +enum {NORMAL_HOOKE, NORMAL_HERTZ, HERTZ_MATERIAL, DMT, JKR}; #define BIG 1.0e20 @@ -47,7 +48,7 @@ enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,JKR_ROLLING,DMT_ROLLING}; FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) : FixWallGran(lmp, narg, arg), region(NULL), region_style(NULL), ncontact(NULL), - walls(NULL), shearmany(NULL), c2r(NULL) + walls(NULL), history_many(NULL), c2r(NULL) { restart_global = 1; motion_resetflag = 0; @@ -66,17 +67,17 @@ FixWallGranRegion::FixWallGranRegion(LAMMPS *lmp, int narg, char **arg) : // re-allocate atom-based arrays with nshear // do not register with Atom class, since parent class did that - memory->destroy(shearone); - shearone = NULL; + memory->destroy(history_one); + history_one = NULL; ncontact = NULL; walls = NULL; - shearmany = NULL; + history_many = NULL; grow_arrays(atom->nmax); // initialize shear history as if particle is not touching region - if (history) { + if (use_history) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) ncontact[i] = 0; @@ -92,7 +93,7 @@ FixWallGranRegion::~FixWallGranRegion() memory->destroy(ncontact); memory->destroy(walls); - memory->destroy(shearmany); + memory->destroy(history_many); } /* ---------------------------------------------------------------------- */ @@ -138,8 +139,8 @@ void FixWallGranRegion::post_force(int /*vflag*/) // do not update shear history during setup - shearupdate = 1; - if (update->setupflag) shearupdate = 0; + history_update = 1; + if (update->setupflag) history_update = 0; // if just reneighbored: // update rigid body masses for owned atoms if using FixRigid @@ -188,7 +189,12 @@ void FixWallGranRegion::post_force(int /*vflag*/) if (mask[i] & groupbit) { if (!region->match(x[i][0],x[i][1],x[i][2])) continue; - nc = region->surface(x[i][0],x[i][1],x[i][2],radius[i]); + if (pairstyle == GRANULAR && normal_model == JKR){ + nc = region->surface(x[i][0],x[i][1],x[i][2],radius[i]+pulloff_distance(radius[i])); + } + else{ + nc = region->surface(x[i][0],x[i][1],x[i][2],radius[i]); + } if (nc > tmax) error->one(FLERR,"Too many wall/gran/region contacts for one particle"); @@ -198,7 +204,7 @@ void FixWallGranRegion::post_force(int /*vflag*/) // also set c2r[] = indices into region->contact[] for each of N contacts // process zero or one contact here, otherwise invoke update_contacts() - if (history) { + if (use_history) { if (nc == 0) { ncontact[i] = 0; continue; @@ -209,8 +215,8 @@ void FixWallGranRegion::post_force(int /*vflag*/) if (ncontact[i] == 0) { ncontact[i] = 1; walls[i][0] = iwall; - for (m = 0; m < sheardim; m++) - shearmany[i][0][m] = 0.0; + for (m = 0; m < size_history; m++) + history_many[i][0][m] = 0.0; } else if (ncontact[i] > 1 || iwall != walls[i][0]) update_contacts(i,nc); } else update_contacts(i,nc); @@ -224,13 +230,20 @@ void FixWallGranRegion::post_force(int /*vflag*/) rsq = region->contact[ic].r*region->contact[ic].r; + if (pairstyle == GRANULAR && normal_model == JKR){ + if (history_many[i][c2r[ic]][0] == 0.0 && rsq > radius[i]*radius[i]){ + for (m = 0; m < size_history; m++) + history_many[i][0][m] = 0.0; + continue; + } + } + dx = region->contact[ic].delx; dy = region->contact[ic].dely; dz = region->contact[ic].delz; if (regiondynamic) region->velocity_contact(vwall, x[i], ic); - // meff = effective mass of sphere // if I is part of rigid body, use body mass @@ -259,13 +272,13 @@ void FixWallGranRegion::post_force(int /*vflag*/) else if (pairstyle == HOOKE_HISTORY) hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], omega[i],torque[i],radius[i],meff, - shearmany[i][c2r[ic]], contact); + history_many[i][c2r[ic]], contact); else if (pairstyle == HERTZ_HISTORY) hertz_history(rsq,dx,dy,dz,vwall,region->contact[ic].radius, v[i],f[i],omega[i],torque[i], - radius[i],meff,shearmany[i][c2r[ic]], contact); - else if (pairstyle == DMT_ROLLING) - dmt_rolling(rsq,dx,dy,dz,vwall,region->contact[ic].radius, v[i],f[i],omega[i],torque[i], radius[i],meff,shearmany[i][c2r[ic]], contact); + radius[i],meff,history_many[i][c2r[ic]], contact); + else if (pairstyle == GRANULAR) + granular(rsq,dx,dy,dz,vwall,region->contact[ic].radius, v[i],f[i],omega[i],torque[i], radius[i],meff,history_many[i][c2r[ic]], contact); } } @@ -294,8 +307,8 @@ void FixWallGranRegion::update_contacts(int i, int nc) if (region->contact[m].iwall == walls[i][iold]) break; if (m >= nc) { ilast = ncontact[i]-1; - for (j = 0; j < sheardim; j++) - shearmany[i][iold][j] = shearmany[i][ilast][j]; + for (j = 0; j < size_history; j++) + history_many[i][iold][j] = history_many[i][ilast][j]; walls[i][iold] = walls[i][ilast]; ncontact[i]--; } else iold++; @@ -317,8 +330,8 @@ void FixWallGranRegion::update_contacts(int i, int nc) iadd = ncontact[i]; c2r[iadd] = inew; - for (j = 0; j < sheardim; j++) - shearmany[i][iadd][j] = 0.0; + for (j = 0; j < size_history; j++) + history_many[i][iadd][j] = 0.0; walls[i][iadd] = iwall; ncontact[i]++; } @@ -333,10 +346,10 @@ double FixWallGranRegion::memory_usage() { int nmax = atom->nmax; double bytes = 0.0; - if (history) { // shear history + if (use_history) { // shear history bytes += nmax * sizeof(int); // ncontact bytes += nmax*tmax * sizeof(int); // walls - bytes += nmax*tmax*sheardim * sizeof(double); // shearmany + bytes += nmax*tmax*size_history * sizeof(double); // history_many } if (fix_rigid) bytes += nmax * sizeof(int); // mass_rigid return bytes; @@ -348,10 +361,10 @@ double FixWallGranRegion::memory_usage() void FixWallGranRegion::grow_arrays(int nmax) { - if (history) { + if (use_history) { memory->grow(ncontact,nmax,"fix_wall_gran:ncontact"); memory->grow(walls,nmax,tmax,"fix_wall_gran:walls"); - memory->grow(shearmany,nmax,tmax,sheardim,"fix_wall_gran:shearmany"); + memory->grow(history_many,nmax,tmax,size_history,"fix_wall_gran:history_many"); } if (peratom_flag){ memory->grow(array_atom,nmax,size_peratom_cols,"fix_wall_gran:array_atom"); @@ -366,12 +379,12 @@ void FixWallGranRegion::copy_arrays(int i, int j, int /*delflag*/) { int m,n,iwall; - if (history){ + if (use_history){ n = ncontact[i]; for (iwall = 0; iwall < n; iwall++) { walls[j][iwall] = walls[i][iwall]; - for (m = 0; m < sheardim; m++) - shearmany[j][iwall][m] = shearmany[i][iwall][m]; + for (m = 0; m < size_history; m++) + history_many[j][iwall][m] = history_many[i][iwall][m]; } ncontact[j] = ncontact[i]; } @@ -388,7 +401,7 @@ void FixWallGranRegion::copy_arrays(int i, int j, int /*delflag*/) void FixWallGranRegion::set_arrays(int i) { - if (history) + if (use_history) ncontact[i] = 0; if (peratom_flag){ for (int m = 0; m < size_peratom_cols; m++) @@ -405,13 +418,13 @@ int FixWallGranRegion::pack_exchange(int i, double *buf) int m; int n = 0; - if (history){ + if (use_history){ int count = ncontact[i]; buf[n++] = ubuf(count).d; for (int iwall = 0; iwall < count; iwall++) { buf[n++] = ubuf(walls[i][iwall]).d; - for (m = 0; m < sheardim; m++) - buf[n++] = shearmany[i][iwall][m]; + for (m = 0; m < size_history; m++) + buf[n++] = history_many[i][iwall][m]; } } if (peratom_flag){ @@ -432,12 +445,12 @@ int FixWallGranRegion::unpack_exchange(int nlocal, double *buf) int n = 0; - if (history){ + if (use_history){ int count = ncontact[nlocal] = (int) ubuf(buf[n++]).i; for (int iwall = 0; iwall < count; iwall++) { walls[nlocal][iwall] = (int) ubuf(buf[n++]).i; - for (m = 0; m < sheardim; m++) - shearmany[nlocal][iwall][m] = buf[n++]; + for (m = 0; m < size_history; m++) + history_many[nlocal][iwall][m] = buf[n++]; } } if (peratom_flag){ @@ -456,7 +469,7 @@ int FixWallGranRegion::pack_restart(int i, double *buf) { int m; - if (!history) return 0; + if (!use_history) return 0; int n = 1; int count = ncontact[i]; @@ -464,8 +477,8 @@ int FixWallGranRegion::pack_restart(int i, double *buf) buf[n++] = ubuf(count).d; for (int iwall = 0; iwall < count; iwall++) { buf[n++] = ubuf(walls[i][iwall]).d; - for (m = 0; m < sheardim; m++) - buf[n++] = shearmany[i][iwall][m]; + for (m = 0; m < size_history; m++) + buf[n++] = history_many[i][iwall][m]; } buf[0] = n; return n; @@ -479,7 +492,7 @@ void FixWallGranRegion::unpack_restart(int nlocal, int nth) { int k; - if (!history) return; + if (!use_history) return; double **extra = atom->extra; @@ -492,8 +505,8 @@ void FixWallGranRegion::unpack_restart(int nlocal, int nth) int count = ncontact[nlocal] = (int) ubuf(extra[nlocal][m++]).i; for (int iwall = 0; iwall < count; iwall++) { walls[nlocal][iwall] = (int) ubuf(extra[nlocal][m++]).i; - for (k = 0; k < sheardim; k++) - shearmany[nlocal][iwall][k] = extra[nlocal][m++]; + for (k = 0; k < size_history; k++) + history_many[nlocal][iwall][k] = extra[nlocal][m++]; } } @@ -503,8 +516,8 @@ void FixWallGranRegion::unpack_restart(int nlocal, int nth) int FixWallGranRegion::maxsize_restart() { - if (!history) return 0; - return 2 + tmax*(sheardim+1); + if (!use_history) return 0; + return 2 + tmax*(size_history+1); } /* ---------------------------------------------------------------------- @@ -513,8 +526,8 @@ int FixWallGranRegion::maxsize_restart() int FixWallGranRegion::size_restart(int nlocal) { - if (!history) return 0; - return 2 + ncontact[nlocal]*(sheardim+1); + if (!use_history) return 0; + return 2 + ncontact[nlocal]*(size_history+1); } /* ---------------------------------------------------------------------- diff --git a/src/GRANULAR/fix_wall_gran_region.h b/src/GRANULAR/fix_wall_gran_region.h index 8d1b6d533a..fd40e27e4c 100644 --- a/src/GRANULAR/fix_wall_gran_region.h +++ b/src/GRANULAR/fix_wall_gran_region.h @@ -54,7 +54,7 @@ class FixWallGranRegion : public FixWallGran { int tmax; // max # of region walls one particle can touch int *ncontact; // # of shear contacts per particle int **walls; // which wall each contact is with - double ***shearmany; // shear history per particle per contact + double ***history_many; // history per particle per contact int *c2r; // contact to region mapping // c2r[i] = index of Ith contact in // region-contact[] list of contacts diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 5631240fea..ac0b668854 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -45,6 +45,7 @@ using namespace MathConst; #define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) #define INVROOT6 0.40824829046386307274 // 1/sqrt(6) #define FOURTHIRDS 1.333333333333333 // 4/3 +#define THREEQUARTERS 0.75 // 3/4 #define TWOPI 6.28318530717959 // 2*PI #define EPSILON 1e-10 @@ -63,7 +64,7 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) no_virial_fdotr_compute = 1; fix_history = NULL; - single_extra = 9; + single_extra = 12; svector = new double[single_extra]; neighprev = 0; @@ -238,10 +239,11 @@ void PairGranular::compute(int eflag, int vflag) radsum = radi + radj; E = normal_coeffs[itype][jtype][0]; - Reff = radi*radj/(radi+radj); + Reff = radi*radj/radsum; touchflag = false; if (normal_model[itype][jtype] == JKR){ + E *= THREEQUARTERS; if (touch[jj]){ R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; @@ -319,17 +321,17 @@ void PairGranular::compute(int eflag, int vflag) sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); a = INVROOT6*(t6 + sqrt(sqrt3)); a2 = a*a; - knfac = FOURTHIRDS*E*a; + knfac = normal_coeffs[itype][jtype][0]*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); } else{ knfac = E; //Hooke + Fne = knfac*delta; a = sqrt(dR); if (normal_model[itype][jtype] != HOOKE){ Fne *= a; knfac *= a; } - Fne = knfac*delta; if (normal_model[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } @@ -711,9 +713,9 @@ void PairGranular::coeff(int narg, char **arg) } else if (strcmp(arg[iarg], "hertz/material") == 0){ int num_coeffs = 3; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_model_one = HERTZ; - normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz/material option"); + normal_model_one = HERTZ_MATERIAL; + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio iarg += num_coeffs+1; @@ -721,10 +723,10 @@ void PairGranular::coeff(int narg, char **arg) else if (strcmp(arg[iarg], "dmt") == 0){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); normal_model_one = DMT; - normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E + normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio - normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion + normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; } else if (strcmp(arg[iarg], "jkr") == 0){ @@ -755,21 +757,27 @@ void PairGranular::coeff(int narg, char **arg) iarg += 1; } else if (strcmp(arg[iarg], "tangential") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); + if (iarg + 1 >= narg) error->all(FLERR,"Illegal pair_coeff command, must specify tangential model after 'tangential' keyword"); if (strcmp(arg[iarg+1], "linear_nohistory") == 0){ + if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); tangential_model_one = TANGENTIAL_NOHISTORY; + tangential_coeffs_one[0] = 0; + tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat + tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. + iarg += 4; } else if (strcmp(arg[iarg+1], "linear_history") == 0){ + if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); tangential_model_one = TANGENTIAL_HISTORY; tangential_history = 1; + tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt + tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat + tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. + iarg += 5; } else{ error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); } - tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt - tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; } else if (strcmp(arg[iarg], "rolling") == 0){ if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); @@ -842,7 +850,7 @@ void PairGranular::coeff(int narg, char **arg) if (normal_model_one != HERTZ && normal_model_one != HOOKE){ Emod[i][j] = Emod[j][i] = normal_coeffs_one[0]; poiss[i][j] = poiss[j][i] = normal_coeffs_one[2]; - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(Emod[i][j], Emod[i][j], poiss[i][j], poiss[i][j]); + normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = FOURTHIRDS*mix_stiffnessE(Emod[i][j], Emod[i][j], poiss[i][j], poiss[i][j]); } else{ normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_one[0]; @@ -1068,14 +1076,13 @@ double PairGranular::init_one(int i, int j) if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist + cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; + pulloff = 0.0; if (normal_model[i][j] == JKR){ pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_dynamic[j], i, j); cutoff += pulloff; } - else{ - pulloff = 0; - } if (normal_model[i][j] == JKR) pulloff = pulloff_distance(maxrad_frozen[i], maxrad_dynamic[j], i, j); @@ -1224,10 +1231,12 @@ double PairGranular::single(int i, int j, int itype, int jtype, radi = radius[i]; radj = radius[j]; radsum = radi + radj; - Reff = radi*radj/(radi+radj); + Reff = radi*radj/radsum; bool touchflag; + E = normal_coeffs[itype][jtype][0]; if (normal_model[itype][jtype] == JKR){ + E *= THREEQUARTERS; R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); @@ -1333,7 +1342,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); a = INVROOT6*(t6 + sqrt(sqrt3)); a2 = a*a; - knfac = FOURTHIRDS*E*a; + knfac = normal_coeffs[itype][jtype][0]*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); } else{ @@ -1348,7 +1357,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } - //Consider restricting Hooke to only have 'velocity' as an option for damping? if (damping_model[itype][jtype] == VELOCITY){ damp_normal = normal_coeffs[itype][jtype][1]; } @@ -1536,6 +1544,9 @@ double PairGranular::single(int i, int j, int itype, int jtype, svector[6] = fr3; svector[7] = fr; svector[8] = magtortwist; + svector[9] = delx; + svector[10] = dely; + svector[11] = delz; return 0.0; } @@ -1614,7 +1625,7 @@ double PairGranular::pulloff_distance(double radi, double radj, int itype, int j Reff = radi*radj/(radi+radj); if (Reff <= 0) return 0; coh = normal_coeffs[itype][itype][3]; - E = normal_coeffs[itype][jtype][0]; + E = normal_coeffs[itype][jtype][0]*THREEQUARTERS; a = cbrt(9*M_PI*coh*Reff/(4*E)); return a*a/Reff - 2*sqrt(M_PI*coh*a/E); } diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 625ff17c72..7bce3831f1 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -65,9 +65,9 @@ public: private: int size_history; - //Models choices + //Model choices int **normal_model, **damping_model; - double **tangential_model, **roll_model, **twist_model; + int **tangential_model, **roll_model, **twist_model; //History flags int normal_history, tangential_history, roll_history, twist_history; -- GitLab From 4e26ca29f7d43b75b729e3c23f54566dd155ba63 Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Tue, 19 Feb 2019 16:47:13 -0700 Subject: [PATCH 0140/1243] Changes to new generalized granular pair styles and fix wall/gran -Clean-up of unused variables in code -Bug fix for single method of pair granular -Changes to fix wall/gran to fix issues with JKR -Doc page updates for fix wall/gran and fix wall/gran/region --- doc/src/fix_wall_gran.txt | 53 +++++++++++++++--------- doc/src/fix_wall_gran_region.txt | 43 ++++++++++++------- src/GRANULAR/fix_wall_gran.cpp | 16 +++---- src/GRANULAR/pair_gran_hooke_history.cpp | 4 -- src/GRANULAR/pair_granular.cpp | 50 +++++++--------------- 5 files changed, 85 insertions(+), 81 deletions(-) diff --git a/doc/src/fix_wall_gran.txt b/doc/src/fix_wall_gran.txt index 871ee2e5d1..096bec4920 100644 --- a/doc/src/fix_wall_gran.txt +++ b/doc/src/fix_wall_gran.txt @@ -11,18 +11,21 @@ fix wall/gran/omp command :h3 [Syntax:] -fix ID group-ID wall/gran fstyle Kn Kt gamma_n gamma_t xmu dampflag wallstyle args keyword values ... :pre +fix ID group-ID wall/gran fstyle fstyle_params wallstyle args keyword values ... :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l wall/gran = style name of this fix command :l fstyle = style of force interactions between particles and wall :l - possible choices: hooke, hooke/history, hertz/history :pre -Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) :l -Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) :l -gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) :l -gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) :l -xmu = static yield criterion (unitless value between 0.0 and 1.0e4) :l -dampflag = 0 or 1 if tangential damping force is excluded or included :l + possible choices: hooke, hooke/history, hertz/history, granular :pre +fstyle_params = parameters associated with force interaction style :l + For {hooke}, {hooke/history}, and {hertz/history}, {fstyle_params} are: + Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) + Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) + gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) + gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) + xmu = static yield criterion (unitless value between 0.0 and 1.0e4) + dampflag = 0 or 1 if tangential damping force is excluded or included :pre + For {granular}, {fstyle_params} are set using the same syntax as for the {pair_coeff} command of "pair_style granular"_pair_granular.html :pre wallstyle = {xplane} or {yplane} or {zplane} or {zcylinder} :l args = list of arguments for a particular style :l {xplane} or {yplane} or {zplane} args = lo hi @@ -44,7 +47,10 @@ keyword = {wiggle} or {shear} :l fix 1 all wall/gran hooke 200000.0 NULL 50.0 NULL 0.5 0 xplane -10.0 10.0 fix 1 all wall/gran hooke/history 200000.0 NULL 50.0 NULL 0.5 0 zplane 0.0 NULL -fix 2 all wall/gran hooke 100000.0 20000.0 50.0 30.0 0.5 1 zcylinder 15.0 wiggle z 3.0 2.0 :pre +fix 2 all wall/gran hooke 100000.0 20000.0 50.0 30.0 0.5 1 zcylinder 15.0 wiggle z 3.0 2.0 +fix 3 all wall/gran granular hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 zplane 0.0 NULL +fix 4 all wall/gran granular jkr 1000.0 50.0 tangential linear_history 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall zcylinder 15.0 wiggle z 3.0 2.0 +fix 5 all wall/gran granular dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall zplane 0.0 NULL :pre [Description:] @@ -54,31 +60,39 @@ close enough to touch it. The nature of the wall/particle interactions are determined by the {fstyle} setting. It can be any of the styles defined by the -"pair_style granular"_pair_gran.html commands. Currently this is -{hooke}, {hooke/history}, or {hertz/history}. The equation for the +"pair_style gran/*"_pair_gran.html or the more general "pair_style granular"_pair_granular.html" +commands. Currently the options are {hooke}, {hooke/history}, or {hertz/history} for the former, +and {granular} with all the possible options of the associated {pair_coeff} command +for the latter. The equation for the force between the wall and particles touching it is the same as the -corresponding equation on the "pair_style granular"_pair_gran.html doc -page, in the limit of one of the two particles going to infinite +corresponding equation on the "pair_style gran/*"_pair_gran.html +and "pair_style_granular"_pair_granular.html doc +pages, in the limit of one of the two particles going to infinite radius and mass (flat wall). Specifically, delta = radius - r = overlap of particle with wall, m_eff = mass of particle, and the -effective radius of contact = RiRj/Ri+Rj is just the radius of the -particle. +effective radius of contact = RiRj/Ri+Rj is set to the radius +of the particle. The parameters {Kn}, {Kt}, {gamma_n}, {gamma_t}, {xmu} and {dampflag} have the same meaning and units as those specified with the -"pair_style granular"_pair_gran.html commands. This means a NULL can +"pair_style gran/*"_pair_gran.html commands. This means a NULL can be used for either {Kt} or {gamma_t} as described on that page. If a NULL is used for {Kt}, then a default value is used where {Kt} = 2/7 {Kn}. If a NULL is used for {gamma_t}, then a default value is used where {gamma_t} = 1/2 {gamma_n}. +All the model choices for cohesion, tangential friction, rolling friction +and twisting friction supported by the "pair_style granular"_pair_granular.html +through its {pair_coeff} command are also supported for walls. These are discussed +in greater detail on the doc page for "pair_style granular"_pair_granular.html. + Note that you can choose a different force styles and/or different -values for the 6 wall/particle coefficients than for particle/particle +values for the wall/particle coefficients than for particle/particle interactions. E.g. if you wish to model the wall as a different material. NOTE: As discussed on the doc page for "pair_style -granular"_pair_gran.html, versions of LAMMPS before 9Jan09 used a +gran/*"_pair_gran.html, versions of LAMMPS before 9Jan09 used a different equation for Hertzian interactions. This means Hertizian wall/particle interactions have also changed. They now include a sqrt(radius) term which was not present before. Also the previous @@ -188,6 +202,7 @@ Any dimension (xyz) that has a granular wall must be non-periodic. "fix move"_fix_move.html, "fix wall/gran/region"_fix_wall_gran_region.html, -"pair_style granular"_pair_gran.html +"pair_style gran/*"_pair_gran.html +"pair_style granular"_pair_granular.html [Default:] none diff --git a/doc/src/fix_wall_gran_region.txt b/doc/src/fix_wall_gran_region.txt index 50d744b305..6dcac2c180 100644 --- a/doc/src/fix_wall_gran_region.txt +++ b/doc/src/fix_wall_gran_region.txt @@ -10,24 +10,30 @@ fix wall/gran/region command :h3 [Syntax:] -fix ID group-ID wall/gran/region fstyle Kn Kt gamma_n gamma_t xmu dampflag wallstyle regionID :pre +fix ID group-ID wall/gran/region fstyle fstyle_params wallstyle regionID :pre ID, group-ID are documented in "fix"_fix.html command :ulb,l wall/region = style name of this fix command :l fstyle = style of force interactions between particles and wall :l - possible choices: hooke, hooke/history, hertz/history :pre -Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) :l -Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) :l -gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) :l -gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) :l -xmu = static yield criterion (unitless value between 0.0 and 1.0e4) :l -dampflag = 0 or 1 if tangential damping force is excluded or included :l + possible choices: hooke, hooke/history, hertz/history, granular :pre +fstyle_params = parameters associated with force interaction style :l + For {hooke}, {hooke/history}, and {hertz/history}, {fstyle_params} are: + Kn = elastic constant for normal particle repulsion (force/distance units or pressure units - see discussion below) + Kt = elastic constant for tangential contact (force/distance units or pressure units - see discussion below) + gamma_n = damping coefficient for collisions in normal direction (1/time units or 1/time-distance units - see discussion below) + gamma_t = damping coefficient for collisions in tangential direction (1/time units or 1/time-distance units - see discussion below) + xmu = static yield criterion (unitless value between 0.0 and 1.0e4) + dampflag = 0 or 1 if tangential damping force is excluded or included :pre + For {granular}, {fstyle_params} are set using the same syntax as for the {pair_coeff} command of "pair_style granular"_pair_granular.html :pre wallstyle = region (see "fix wall/gran"_fix_wall_gran.html for options for other kinds of walls) :l region-ID = region whose boundary will act as wall :l,ule [Examples:] -fix wall all wall/gran/region hooke/history 1000.0 200.0 200.0 100.0 0.5 1 region myCone :pre +fix wall all wall/gran/region hooke/history 1000.0 200.0 200.0 100.0 0.5 1 region myCone +fix 3 all wall/gran/region granular hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 region myBox +fix 4 all wall/gran/region granular jkr 1000.0 50.0 tangential linear_history 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall region myCone +fix 5 all wall/gran/region granular dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall region myCone :pre [Description:] @@ -122,11 +128,14 @@ to make the two faces differ by epsilon in their position. The nature of the wall/particle interactions are determined by the {fstyle} setting. It can be any of the styles defined by the -"pair_style granular"_pair_gran.html commands. Currently this is -{hooke}, {hooke/history}, or {hertz/history}. The equation for the +"pair_style gran/*"_pair_gran.html or the more general "pair_style granular"_pair_granular.html" +commands. Currently the options are {hooke}, {hooke/history}, or {hertz/history} for the former, +and {granular} with all the possible options of the associated {pair_coeff} command +for the latter. The equation for the force between the wall and particles touching it is the same as the -corresponding equation on the "pair_style granular"_pair_gran.html doc -page, but the effective radius is calculated using the radius of the +corresponding equation on the "pair_style gran/*"_pair_gran.html +and "pair_style_granular"_pair_granular.html doc +pages, but the effective radius is calculated using the radius of the particle and the radius of curvature of the wall at the contact point. Specifically, delta = radius - r = overlap of particle with wall, @@ -140,12 +149,18 @@ particle. The parameters {Kn}, {Kt}, {gamma_n}, {gamma_t}, {xmu} and {dampflag} have the same meaning and units as those specified with the -"pair_style granular"_pair_gran.html commands. This means a NULL can +"pair_style gran/*"_pair_gran.html commands. This means a NULL can be used for either {Kt} or {gamma_t} as described on that page. If a NULL is used for {Kt}, then a default value is used where {Kt} = 2/7 {Kn}. If a NULL is used for {gamma_t}, then a default value is used where {gamma_t} = 1/2 {gamma_n}. + +All the model choices for cohesion, tangential friction, rolling friction +and twisting friction supported by the "pair_style granular"_pair_granular.html +through its {pair_coeff} command are also supported for walls. These are discussed +in greater detail on the doc page for "pair_style granular"_pair_granular.html. + Note that you can choose a different force styles and/or different values for the 6 wall/particle coefficients than for particle/particle interactions. E.g. if you wish to model the wall as a different diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 6e8cba7b4f..3b959e1a01 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -1021,9 +1021,8 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, double radius, double meff, double *history, double *contact) { - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,r,rinv,rsqinv; + double fx,fy,fz,nx,ny,nz; + double radsum,r,rinv; double Reff, delta, dR, dR2; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; @@ -1035,17 +1034,17 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, double Fne, Ft, Fdamp, Fntot, Fncrit, Fscrit, Frcrit; double fs, fs1, fs2, fs3; - double mi,mj,damp,ccel,tor1,tor2,tor3; + double tor1,tor2,tor3; double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; //For JKR - double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; + double R2, coh, F_pulloff, a, a2, E; double t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; + double sqrt1, sqrt2, sqrt3; //Rolling double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double torroll1, torroll2, torroll3; double rollmag, rolldotn, scalefac; double fr, fr1, fr2, fr3; @@ -1055,9 +1054,6 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, double tortwist1, tortwist2, tortwist3; double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *allhistory,**firsthistory; r = sqrt(rsq); radsum = rwall + radius; diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 04df3b3d9b..344e72f8ef 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -349,10 +349,6 @@ void PairGranHookeHistory::settings(int narg, char **arg) { if (narg != 6) error->all(FLERR,"Illegal pair_style command"); - - - - kn = force->numeric(FLERR,arg[0]); if (strcmp(arg[1],"NULL") == 0) kt = kn * 2.0/7.0; else kt = force->numeric(FLERR,arg[1]); diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index ac0b668854..caef852ab0 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -130,7 +130,7 @@ void PairGranular::compute(int eflag, int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv; + double radi,radj,radsum,rsq,r,rinv; double Reff, delta, dR, dR2; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; @@ -140,19 +140,19 @@ void PairGranular::compute(int eflag, int vflag) double knfac, damp_normal, damp_normal_prefactor; double k_tangential, damp_tangential; double Fne, Ft, Fdamp, Fntot, Fncrit, Fscrit, Frcrit; - double fs, fs1, fs2, fs3; + double fs, fs1, fs2, fs3, tor1, tor2, tor3; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double mi,mj,meff; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3; //For JKR double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; double t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; + double sqrt1, sqrt2, sqrt3; //Rolling double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; + double torroll1, torroll2, torroll3; double rollmag, rolldotn, scalefac; double fr, fr1, fr2, fr3; @@ -204,7 +204,6 @@ void PairGranular::compute(int eflag, int vflag) double *rmass = atom->rmass; int *mask = atom->mask; int nlocal = atom->nlocal; - int newton_pair = force->newton_pair; inum = list->inum; ilist = list->ilist; @@ -465,9 +464,6 @@ void PairGranular::compute(int eflag, int vflag) vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; int rhist0 = roll_history_index; int rhist1 = rhist0 + 1; @@ -1192,12 +1188,12 @@ double PairGranular::single(int i, int j, int itype, int jtype, double rsq, double factor_coul, double factor_lj, double &fforce) { double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; + double r,rinv,delx,dely,delz, nx, ny, nz, Reff; double dR, dR2; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; double vtr1,vtr2,vtr3,vrel; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double mi,mj,meff; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3; double knfac, damp_normal, damp_normal_prefactor; double k_tangential, damp_tangential; @@ -1207,25 +1203,22 @@ double PairGranular::single(int i, int j, int itype, int jtype, //For JKR double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; double delta, t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; + double sqrt1, sqrt2, sqrt3; //Rolling double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; - double rollmag, rolldotn, scalefac; + double rollmag; double fr, fr1, fr2, fr3; //Twisting double k_twist, damp_twist, mu_twist; double signtwist, magtwist, magtortwist, Mtcrit; - double tortwist1, tortwist2, tortwist3; - double shrmag,rsht; + double shrmag; int jnum; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *history,*allhistory,**firsthistory; + int *jlist; + double *history,*allhistory; double *radius = atom->radius; radi = radius[i]; @@ -1312,8 +1305,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, // if I or J part of rigid body, use body mass // if I or J is frozen, meff is other particle - int *type = atom->type; - mi = rmass[i]; mj = rmass[j]; if (fix_rigid) { @@ -1348,11 +1339,11 @@ double PairGranular::single(int i, int j, int itype, int jtype, else{ knfac = E; a = sqrt(dR); + Fne = knfac*delta; if (normal_model[itype][jtype] != HOOKE){ Fne *= a; knfac *= a; } - Fne = knfac*delta; if (normal_model[itype][jtype] == DMT) Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } @@ -1471,9 +1462,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; int rhist0 = roll_history_index; int rhist1 = rhist0 + 1; @@ -1484,8 +1472,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, history[rhist1]*history[rhist1] + history[rhist2]*history[rhist2]); - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - k_roll = roll_coeffs[itype][jtype][0]; damp_roll = roll_coeffs[itype][jtype][1]; fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; @@ -1498,9 +1484,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); if (fr > Frcrit) { if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); fr1 *= Frcrit/fr; fr2 *= Frcrit/fr; fr3 *= Frcrit/fr; @@ -1528,7 +1511,6 @@ double PairGranular::single(int i, int j, int itype, int jtype, signtwist = (magtwist > 0) - (magtwist < 0); Mtcrit = mu_twist*Fncrit;//critical torque (eq 44) if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); magtortwist = -Mtcrit * signtwist; //eq 34 } } @@ -1621,7 +1603,7 @@ double PairGranular::mix_geom(double valii, double valjj) double PairGranular::pulloff_distance(double radi, double radj, int itype, int jtype) { - double E, coh, a, delta_pulloff, Reff; + double E, coh, a, Reff; Reff = radi*radj/(radi+radj); if (Reff <= 0) return 0; coh = normal_coeffs[itype][itype][3]; -- GitLab From 8db88b1c02a6b9e26e2eafad986707efb06ab85a Mon Sep 17 00:00:00 2001 From: Norbert Podhorszki Date: Thu, 24 Jan 2019 13:48:08 -0500 Subject: [PATCH 0141/1243] Added initial untested ADIOS 2.x code with cmake building problems --- cmake/CMakeLists.txt | 48 +++- runconf | 22 ++ src/USER-ADIOS/Install.sh | 89 +++++++ src/USER-ADIOS/README | 16 ++ src/USER-ADIOS/dump_atom_adios.cpp | 314 ++++++++++++++++++++++++ src/USER-ADIOS/dump_atom_adios.h | 70 ++++++ src/USER-ADIOS/dump_custom_adios.cpp | 354 +++++++++++++++++++++++++++ src/USER-ADIOS/dump_custom_adios.h | 94 +++++++ 8 files changed, 1005 insertions(+), 2 deletions(-) create mode 100644 runconf create mode 100644 src/USER-ADIOS/Install.sh create mode 100644 src/USER-ADIOS/README create mode 100644 src/USER-ADIOS/dump_atom_adios.cpp create mode 100644 src/USER-ADIOS/dump_atom_adios.h create mode 100644 src/USER-ADIOS/dump_custom_adios.cpp create mode 100644 src/USER-ADIOS/dump_custom_adios.h diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 9ad64a59ed..5010643fd8 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -2,7 +2,22 @@ # CMake build system # This file is part of LAMMPS # Created by Christoph Junghans and Richard Berger -cmake_minimum_required(VERSION 2.8.12) +if(PKG_USER-ADIOS) + message(STATUS "Force newer standards because using ADIOS") + cmake_minimum_required(VERSION 3.6) + # Force C++11 and C99 + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED True) + # Use meta-compile features if available, otherwise use specific language + # features +# if(NOT (CMAKE_VERSION VERSION_LESS 3.9)) +# set(ADIOS2_CXX11_FEATURES cxx_std_11) +# else() +# set(ADIOS2_CXX11_FEATURES cxx_auto_type cxx_nullptr) +# endif() +else() + cmake_minimum_required(VERSION 2.8.12) +endif() project(lammps CXX) set(SOVERSION 0) @@ -178,7 +193,7 @@ set(DEFAULT_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS DIPOLE GRANULAR USER-MEAMC USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF USER-PHONON USER-PLUMED USER-PTM USER-QTB USER-REAXC USER-SCAFACOS USER-SDPD USER-SMD USER-SMTBQ USER-SPH USER-TALLY USER-UEF USER-VTK - USER-QUIP USER-QMMM USER-YAFF) + USER-QUIP USER-QMMM USER-YAFF USER-ADIOS) set(ACCEL_PACKAGES USER-OMP KOKKOS OPT USER-INTEL GPU) set(OTHER_PACKAGES CORESHELL QEQ) foreach(PKG ${DEFAULT_PACKAGES}) @@ -613,6 +628,7 @@ if(PKG_USER-NETCDF) add_definitions(-DLMP_HAS_NETCDF -DNC_64BIT_DATA=0x0020) endif() + if(PKG_USER-SMD) option(DOWNLOAD_EIGEN3 "Download Eigen3 instead of using an already installed one)" OFF) if(DOWNLOAD_EIGEN3) @@ -1354,6 +1370,34 @@ if(BUILD_EXE) endif() endif() +#if(PKG_USER-ADIOS) +# cmake_minimum_required(VERSION 3.6) +# enable_language(C) +# +# find_package(ADIOS2 REQUIRED) +## find_package(MPI REQUIRED) +# include_directories(${ADIOS2_INCLUDE_DIRS}) +## include_directories(/opt/adios2/include) +## list(APPEND LAMMPS_LINK_LIBS ${ADIOS2_LIBRARIES}) +# list(APPEND LAMMPS_LINK_LIBS ${MPI_C_LIBRARIES}) +# if(BUILD_LIB) +## target_link_libraries(lammps adios2::adios2 MPI::MPI_C) +## #target_include_directories(lammps PRIVATE ${ADIOS_INCLUDE_DIRS}) +# elseif(BUILD_EXE) +## target_link_libraries(lmp adios2::adios2 MPI::MPI_C) +# endif() +#endif(PKG_USER-ADIOS) + +if(PKG_USER-ADIOS) + enable_language(C) + find_package(ADIOS2 REQUIRED) + if(BUILD_LIB) + target_link_libraries(lammps adios2::adios2) + elseif(BUILD_EXE) + target_link_libraries(lmp adios2::adios2) + endif() +endif() + ############################################################################### # Build documentation ############################################################################### diff --git a/runconf b/runconf new file mode 100644 index 0000000000..bb313981c5 --- /dev/null +++ b/runconf @@ -0,0 +1,22 @@ + +# -D LAMMPS_SIZES=value # smallbig (default) or bigbig or smallsmall + +export HDF5_ROOT=/opt/hdf5-serial +export ADIOS2_DIR=/opt/adios2 + +cmake -D CMAKE_INSTALL_PREFIX=/opt/lammps \ + -D CMAKE_BUILD_TYPE=Debug \ + -D BUILD_MPI=yes \ + -D LAMMPS_MACHINE=adiosvm \ + -D BUILD_EXE=yes \ + -D BUILD_LIB=no \ + -D BUILD_SHARED_LIBS=no \ + -D BUILD_DOC=no \ + -D LAMMPS_SIZES=smallbig \ + -D PKG_USER-H5MD=yes \ + -D PKG_USER-ADIOS=yes \ + ../cmake + + + + diff --git a/src/USER-ADIOS/Install.sh b/src/USER-ADIOS/Install.sh new file mode 100644 index 0000000000..cae755406b --- /dev/null +++ b/src/USER-ADIOS/Install.sh @@ -0,0 +1,89 @@ +# Install/unInstall package files in LAMMPS +# mode = 0/1/2 for uninstall/install/update + +mode=$1 + +# arg1 = file, arg2 = file it depends on + +action () { + if (test $mode = 0) then + rm -f ../$1 + elif (! cmp -s $1 ../$1) then + if (test -z "$2" || test -e ../$2) then + cp $1 .. + if (test $mode = 2) then + echo " updating src/$1" + fi + fi + elif (test -n "$2") then + if (test ! -e ../$2) then + rm -f ../$1 + fi + fi +} + +for file in *.cpp *.h; do + action $file +done + +# edit 2 Makefile.package files to include/exclude package info + +if (test $1 = 1) then + +# if (test -z "$ADIOS_DIR") then +# if command -v adios_config; then +# ADIOS_DIR=`adios_config -d` +# else +# echo "ERROR: ADIOS_DIR environment variable needs to point to ADIOS" \ +# " installation directory or adios_config should be in PATH" +# fi +# fi +# ADIOS_INC=-I${ADIOS_DIR}/include +# ADIOS_LIB=`${ADIOS_DIR}/bin/adios_config -l` +# +# echo "adios_SYSINC=${ADIOS_INC} +#adios_SYSLIB=${ADIOS_LIB} +#adios_SYSPATH=${ADIOS_DIR} +#" > ../Makefile.adios + + + if (test -e ../Makefile.package) then + sed -i -e 's/[^ \t]*adios[^ \t]* //g' ../Makefile.package + sed -i -e 's/-DLMP_ADIOS //g' ../Makefile.package + sed -i -e '/^adios_SYS.*$/d' ../Makefile.package +# sed -i -e '4 i \ +#adios_SYSINC='"${ADIOS_INC}"' +#' ../Makefile.package +# sed -i -e '5 i \ +#adios_SYSLIB='"${ADIOS_LIB}"' +#' ../Makefile.package +# sed -i -e '6 i \ +#adios_SYSPATH='"${ADIOS_DIR}"' +#' ../Makefile.package + sed -i -e 's|^PKG_INC =[ \t]*|&-DLMP_ADIOS |' ../Makefile.package + sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(adios_SYSINC) |' ../Makefile.package + sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(adios_SYSLIB) |' ../Makefile.package + sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(adios_SYSPATH) |' ../Makefile.package + fi + + if (test -e ../Makefile.package.settings) then + sed -i -e '/^include.*adios.*$/d' ../Makefile.package.settings + # multiline form needed for BSD sed on Macs + sed -i -e '4 i \ +include ..\/..\/lib\/adios\/Makefile.lammps +' ../Makefile.package.settings + fi + +elif (test $1 = 0) then + + if (test -e ../Makefile.package) then + sed -i -e 's/[^ \t]*adios[^ \t]* //g' ../Makefile.package + sed -i -e 's/-DLMP_ADIOS //g' ../Makefile.package + sed -i -e '/^adios_SYS.*$/d' ../Makefile.package + fi + + if (test -e ../Makefile.package.settings) then + sed -i -e '/^include.*adios.*$/d' ../Makefile.package.settings + fi + +fi diff --git a/src/USER-ADIOS/README b/src/USER-ADIOS/README new file mode 100644 index 0000000000..49717a741f --- /dev/null +++ b/src/USER-ADIOS/README @@ -0,0 +1,16 @@ +This package provides the adios dump and restart styles. + +See the doc page for the "dump adios" and "restart adios" commands. +These styles require having ADIOS 2.x itself installed on your system. + +Configure LAMMPS with CMake + a. set the environment variable + ADIOS2_DIR + to the ADIOS 2.x installation path + b. use the cmake option + -D PKG_USER-ADIOS=yes + +The person who created this package is Norbert Podhorszki (Oak Ridge National Laboratory); +If you need help, please submit a ticket at the OLCF ticket user support mentioning his name in the ticket. +https://www.olcf.ornl.gov/support/submit-ticket + diff --git a/src/USER-ADIOS/dump_atom_adios.cpp b/src/USER-ADIOS/dump_atom_adios.cpp new file mode 100644 index 0000000000..b6ace357ac --- /dev/null +++ b/src/USER-ADIOS/dump_atom_adios.cpp @@ -0,0 +1,314 @@ +/* ---------------------------------------------------------------------- + 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: Norbert Podhorszki (ORNL) +------------------------------------------------------------------------- */ + +#include +#include "dump_atom_adios.h" +#include "domain.h" +#include "atom.h" +#include "update.h" +#include "group.h" +#include "memory.h" +#include "universe.h" +#include "error.h" + + +using namespace LAMMPS_NS; + +#define MAX_TEXT_HEADER_SIZE 4096 +#define DUMP_BUF_CHUNK_SIZE 16384 +#define DUMP_BUF_INCREMENT_SIZE 4096 + +/* ---------------------------------------------------------------------- */ + +DumpAtomADIOS::DumpAtomADIOS(LAMMPS *lmp, int narg, char **arg) : + DumpAtom(lmp, narg, arg) +{ + ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON); + groupSize = 0; +} + +/* ---------------------------------------------------------------------- */ + +DumpAtomADIOS::~DumpAtomADIOS() +{ + if (fh) + { + fh.Close(); + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpAtomADIOS::openfile() +{ + if (multifile) { + // if one file per timestep, replace '*' with current timestep + char *filestar = strdup(filename); + char *filecurrent = new char[strlen(filestar) + 16]; + char *ptr = strchr(filestar,'*'); + *ptr = '\0'; + if (padflag == 0) + sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", + filestar,update->ntimestep,ptr+1); + else { + char bif[8],pad[16]; + strcpy(bif,BIGINT_FORMAT); + sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]); + sprintf(filecurrent,pad,filestar,update->ntimestep,ptr+1); + } + fh = io.Open(filecurrent, adios2::Mode::Write, world); + if (!fh) { + char str[128]; + sprintf(str,"Cannot open dump file %s",filecurrent); + error->one(FLERR,str); + } + free(filestar); + delete [] filecurrent; + } + else + { + if (!singlefile_opened) + { + fh = io.Open(filename, adios2::Mode::Write, world); + if (!fh) { + char str[128]; + sprintf(str,"Cannot open dump file %s",filename); + error->one(FLERR,str); + } + singlefile_opened = 1; + } + + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpAtomADIOS::write() +{ + if (domain->triclinic == 0) { + boxxlo = domain->boxlo[0]; + boxxhi = domain->boxhi[0]; + boxylo = domain->boxlo[1]; + boxyhi = domain->boxhi[1]; + boxzlo = domain->boxlo[2]; + boxzhi = domain->boxhi[2]; + } else { + boxxlo = domain->boxlo_bound[0]; + boxxhi = domain->boxhi_bound[0]; + boxylo = domain->boxlo_bound[1]; + boxyhi = domain->boxhi_bound[1]; + boxzlo = domain->boxlo_bound[2]; + boxzhi = domain->boxhi_bound[2]; + boxxy = domain->xy; + boxxz = domain->xz; + boxyz = domain->yz; + } + + // nme = # of dump lines this proc contributes to dump + + nme = count(); + + // ntotal = total # of atoms in snapshot + // atomOffset = sum of # of atoms up to this proc (exclusive prefix sum) + + bigint bnme = nme; + MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world); + + bigint atomOffset; // sum of all atoms on processes 0..me-1 + MPI_Scan (&bnme, &atomOffset, 1, MPI_LMP_BIGINT, MPI_SUM, world); + atomOffset -= nme; // exclusive prefix sum needed + + // Now we know the global size and the local subset size and offset + // of the atoms table + size_t nAtomsGlobal = static_cast(ntotal); + size_t startRow = static_cast(atomOffset); + size_t nAtomsLocal = static_cast(nme); + size_t nColumns = static_cast(size_one); + varAtoms.SetShape({nAtomsGlobal,nColumns}); + varAtoms.SetSelection({{startRow, 0}, {nAtomsLocal,nColumns}}); + + // insure buf is sized for packing + // adios does not limit per-process data size so nme*size_one is not constrained to int + // if sorting on IDs also request ID list from pack() + // sort buf as needed + + if (nme > maxbuf) { + maxbuf = nme; + memory->destroy(buf); + memory->create(buf,(maxbuf*size_one),"dump:buf"); + } + if (sort_flag && sortcol == 0 && nme > maxids) { + maxids = nme; + memory->destroy(ids); + memory->create(ids,maxids,"dump:ids"); + } + + if (sort_flag && sortcol == 0) pack(ids); + else pack(NULL); + if (sort_flag) sort(); + + // Calculate data size written by this process + groupSize = nme * size_one * sizeof(double); // size of atoms data on this process + groupSize += 3*sizeof(uint64_t) + 1*sizeof(int); // scalars written by each process + if (me == 0) { + groupSize += 1*sizeof(uint64_t) + 1*sizeof(int) + 6*sizeof(double); // scalars + if (domain->triclinic) { + groupSize += 3*sizeof(double); // boxxy, boxxz, boxyz + } + } + + openfile(); + fh.BeginStep(); + // write info on data as scalars (by me==0) + if (me == 0) { + fh.Put("ntimestep", update->ntimestep); + fh.Put("nprocs", nprocs); + + fh.Put("boxxlo", boxxlo); + fh.Put("boxxhi", boxxhi); + fh.Put("boxylo", boxylo); + fh.Put("boxyhi", boxyhi); + fh.Put("boxzlo", boxzlo); + fh.Put("boxzhi", boxzhi); + + if (domain->triclinic) { + fh.Put("boxxy", boxxy); + fh.Put("boxxz", boxxz); + fh.Put("boxyz", boxyz); + } + } + // Everyone needs to write scalar variables that are used as dimensions and offsets of arrays + fh.Put("natoms", ntotal); + fh.Put("ncolumns", size_one); + fh.Put("nme", bnme); + fh.Put("offset", atomOffset); + // now write the atoms + fh.Put("atoms", buf); + fh.EndStep();// I/O will happen now... + + if (multifile) + { + fh.Close(); + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpAtomADIOS::init_style() +{ + if (image_flag == 0) size_one = 5; + else size_one = 8; + + // setup boundary string + + domain->boundary_string(boundstr); + + // remove % from filename since ADIOS always writes a global file with data/metadata + int len = strlen(filename); + char *ptr = strchr(filename,'%'); + if (ptr) { + *ptr = '\0'; + char *s = new char[len-1]; + sprintf(s,"%s%s",filename,ptr+1); + strncpy(filename,s,len); + } + + // setup column string + + if (scale_flag == 0 && image_flag == 0) + columns = (char *) "id type x y z"; + else if (scale_flag == 0 && image_flag == 1) + columns = (char *) "id type x y z ix iy iz"; + else if (scale_flag == 1 && image_flag == 0) + columns = (char *) "id type xs ys zs"; + else if (scale_flag == 1 && image_flag == 1) + columns = (char *) "id type xs ys zs ix iy iz"; + + // setup function ptrs + + if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 0) + pack_choice = &DumpAtomADIOS::pack_scale_noimage; + else if (scale_flag == 1 && image_flag == 1 && domain->triclinic == 0) + pack_choice = &DumpAtomADIOS::pack_scale_image; + else if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 1) + pack_choice = &DumpAtomADIOS::pack_scale_noimage_triclinic; + else if (scale_flag == 1 && image_flag == 1 && domain->triclinic == 1) + pack_choice = &DumpAtomADIOS::pack_scale_image_triclinic; + else if (scale_flag == 0 && image_flag == 0) + pack_choice = &DumpAtomADIOS::pack_noscale_noimage; + else if (scale_flag == 0 && image_flag == 1) + pack_choice = &DumpAtomADIOS::pack_noscale_image; + + /* Define the group of variables for the atom style here since it's a fixed set */ + adios2::IO io = ad->DeclareIO(ioName); + if (!io.InConfigFile()) + { + // if not defined by user, we can change the default settings + // BPFile is the default writer + io.SetEngine("BPFile"); + int num_aggregators = multiproc; + if (num_aggregators == 0) + num_aggregators = 1; + char nstreams[128]; + sprintf (nstreams, "%d", num_aggregators); + io.SetParameters({{"substreams", nstreams}}); + if (me==0 && screen) fprintf(screen, "ADIOS method for %s is n-to-m (aggregation with %s writers)\n", filename, nstreams); + } + + + io.DefineVariable("ntimestep"); + io.DefineVariable("natoms"); + + io.DefineVariable("nprocs"); + io.DefineVariable("ncolumns"); + + io.DefineVariable("boxxlo"); + io.DefineVariable("boxxhi"); + io.DefineVariable("boxylo"); + io.DefineVariable("boxyhi"); + io.DefineVariable("boxzlo"); + io.DefineVariable("boxzhi"); + + io.DefineVariable("boxxy"); + io.DefineVariable("boxxz"); + io.DefineVariable("boxyz"); + + io.DefineAttribute("triclinic", domain->triclinic); + io.DefineAttribute("scaled", scale_flag); + io.DefineAttribute("image", image_flag); + + int *boundaryptr = reinterpret_cast(domain->boundary); + io.DefineAttribute("boundary", boundaryptr, 6); + + io.DefineAttribute("columns", columns); + io.DefineAttribute("boundarystr", boundstr); + io.DefineAttribute("LAMMPS/dump_style", "atom"); + io.DefineAttribute("LAMMPS/version", universe->version); + io.DefineAttribute("LAMMPS/num_ver", universe->num_ver); + + io.DefineVariable("nme", {adios2::LocalValueDim}); // local dimension variable + io.DefineVariable("offset", {adios2::LocalValueDim}); // local dimension variable + + // atom table size is not known at the moment + // it will be correctly defined at the moment of write + size_t UnknownSizeYet = 1; + size_t nColumns = static_cast(size_one); + varAtoms = io.DefineVariable("atoms", + {UnknownSizeYet,nColumns}, + {UnknownSizeYet, 0}, + {UnknownSizeYet,nColumns}); +} diff --git a/src/USER-ADIOS/dump_atom_adios.h b/src/USER-ADIOS/dump_atom_adios.h new file mode 100644 index 0000000000..a3999bea76 --- /dev/null +++ b/src/USER-ADIOS/dump_atom_adios.h @@ -0,0 +1,70 @@ +/* -*- 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 DUMP_CLASS + +DumpStyle(atom/adios,DumpAtomADIOS) + +#else + +#ifndef LMP_DUMP_ATOM_ADIOS_H +#define LMP_DUMP_ATOM_ADIOS_H + +#include "dump_atom.h" +#include +#include +#include "adios2.h" + +namespace LAMMPS_NS { + +class DumpAtomADIOS : public DumpAtom { + + public: + DumpAtomADIOS(class LAMMPS *, int, char **); + virtual ~DumpAtomADIOS(); + + protected: + + const std::string ioName="atom"; // name of adios group, referrable in adios2_config.xml + adios2::ADIOS *ad = nullptr; // adios object + adios2::IO io; // adios group of variables and attributes in this dump + adios2::Engine fh; // adios file/stream handle object + adios2::Variable varAtoms; // one ADIOS output variable we need to change + uint64_t groupSize; // pre-calculate # of bytes written per processor in a step before writing anything + uint64_t groupTotalSize; // ADIOS buffer size returned by adios_group_size(), valid only if size is > default 16MB ADIOS buffer + std::string filecurrent; // name of file for this round (with % and * replaced) + + virtual void openfile(); + virtual void write(); + virtual void init_style(); + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Cannot open dump file %s + +The output file for the dump command cannot be opened. Check that the +path and name are correct. + +E: Too much per-proc info for dump + +Number of local atoms times number of columns must fit in a 32-bit +integer for dump. + +*/ diff --git a/src/USER-ADIOS/dump_custom_adios.cpp b/src/USER-ADIOS/dump_custom_adios.cpp new file mode 100644 index 0000000000..738e6dc076 --- /dev/null +++ b/src/USER-ADIOS/dump_custom_adios.cpp @@ -0,0 +1,354 @@ +/* ---------------------------------------------------------------------- + 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 Coffman (IBM) +------------------------------------------------------------------------- */ + +#include +#include +#include +#include "dump_custom_adios.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "region.h" +#include "group.h" +#include "input.h" +#include "variable.h" +#include "update.h" +#include "modify.h" +#include "compute.h" +#include "fix.h" +#include "universe.h" +#include "memory.h" +#include "error.h" +#include + +using namespace LAMMPS_NS; + +#define MAX_TEXT_HEADER_SIZE 4096 +#define DUMP_BUF_CHUNK_SIZE 16384 +#define DUMP_BUF_INCREMENT_SIZE 4096 + +enum{ID,MOL,TYPE,ELEMENT,MASS, + X,Y,Z,XS,YS,ZS,XSTRI,YSTRI,ZSTRI,XU,YU,ZU,XUTRI,YUTRI,ZUTRI, + XSU,YSU,ZSU,XSUTRI,YSUTRI,ZSUTRI, + IX,IY,IZ, + VX,VY,VZ,FX,FY,FZ, + Q,MUX,MUY,MUZ,MU,RADIUS,DIAMETER, + OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ, + TQX,TQY,TQZ,SPIN,ERADIUS,ERVEL,ERFORCE, + COMPUTE,FIX,VARIABLE}; +enum{LT,LE,GT,GE,EQ,NEQ}; +enum{INT,DOUBLE,STRING,BIGINT}; // same as in DumpCustom + +/* ---------------------------------------------------------------------- */ + +DumpCustomADIOS::DumpCustomADIOS(LAMMPS *lmp, int narg, char **arg) : + DumpCustom(lmp, narg, arg) +{ + ad = new adios2::ADIOS("adios2_config.xml", world, adios2::DebugON); + groupsize = 0; + //if (screen) fprintf(screen, "DumpCustomADIOS constructor: nvariable=%d id_variable=%p, variables=%p, nfield=%d, earg=%p\n", nvariable, id_variable, variable, nfield, earg); + columnNames.reserve(nfield); + for (int i = 0; i < nfield; ++i) { + columnNames[i]=std::string(earg[i]); + //if (screen) fprintf(screen, "earg[%d] = '%s'\n", i, earg[i]); + } +} + +/* ---------------------------------------------------------------------- */ + +DumpCustomADIOS::~DumpCustomADIOS() +{ + columnNames.clear(); + if (fh) + { + fh.Close(); + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpCustomADIOS::openfile() +{ + if (multifile) { + // if one file per timestep, replace '*' with current timestep + char *filestar = strdup(filename); + char *filecurrent = new char[strlen(filestar) + 16]; + char *ptr = strchr(filestar,'*'); + *ptr = '\0'; + if (padflag == 0) + sprintf(filecurrent,"%s" BIGINT_FORMAT "%s", + filestar,update->ntimestep,ptr+1); + else { + char bif[8],pad[16]; + strcpy(bif,BIGINT_FORMAT); + sprintf(pad,"%%s%%0%d%s%%s",padflag,&bif[1]); + sprintf(filecurrent,pad,filestar,update->ntimestep,ptr+1); + } + fh = io.Open(filecurrent, adios2::Mode::Write, world); + if (!fh) { + char str[128]; + sprintf(str,"Cannot open dump file %s",filecurrent); + error->one(FLERR,str); + } + free(filestar); + delete [] filecurrent; + } + else + { + if (!singlefile_opened) + { + fh = io.Open(filename, adios2::Mode::Write, world); + if (!fh) { + char str[128]; + sprintf(str,"Cannot open dump file %s",filename); + error->one(FLERR,str); + } + singlefile_opened = 1; + } + + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpCustomADIOS::write() +{ + if (domain->triclinic == 0) { + boxxlo = domain->boxlo[0]; + boxxhi = domain->boxhi[0]; + boxylo = domain->boxlo[1]; + boxyhi = domain->boxhi[1]; + boxzlo = domain->boxlo[2]; + boxzhi = domain->boxhi[2]; + } else { + boxxlo = domain->boxlo_bound[0]; + boxxhi = domain->boxhi_bound[0]; + boxylo = domain->boxlo_bound[1]; + boxyhi = domain->boxhi_bound[1]; + boxzlo = domain->boxlo_bound[2]; + boxzhi = domain->boxhi_bound[2]; + boxxy = domain->xy; + boxxz = domain->xz; + boxyz = domain->yz; + } + + // nme = # of dump lines this proc contributes to dump + + nme = count(); + + // ntotal = total # of atoms in snapshot + // atomOffset = sum of # of atoms up to this proc (exclusive prefix sum) + + bigint bnme = nme; + MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world); + + bigint atomOffset; // sum of all atoms on processes 0..me-1 + MPI_Scan (&bnme, &atomOffset, 1, MPI_LMP_BIGINT, MPI_SUM, world); + atomOffset -= nme; // exclusive prefix sum needed + + // Now we know the global size and the local subset size and offset + // of the atoms table + size_t nAtomsGlobal = static_cast(ntotal); + size_t startRow = static_cast(atomOffset); + size_t nAtomsLocal = static_cast(nme); + size_t nColumns = static_cast(size_one); + varAtoms.SetShape({nAtomsGlobal,nColumns}); + varAtoms.SetSelection({{startRow, 0}, {nAtomsLocal,nColumns}}); + + // insure filewriter proc can receive everyone's info + // limit nmax*size_one to int since used as arg in MPI_Rsend() below + // pack my data into buf + // if sorting on IDs also request ID list from pack() + // sort buf as needed + + if (nme > maxbuf) { + if ((bigint) nme * size_one > MAXSMALLINT) + error->all(FLERR,"Too much per-proc info for dump"); + maxbuf = nme; + memory->destroy(buf); + memory->create(buf,(maxbuf*size_one),"dump:buf"); + } + if (sort_flag && sortcol == 0 && nme > maxids) { + maxids = nme; + memory->destroy(ids); + memory->create(ids,maxids,"dump:ids"); + } + + if (sort_flag && sortcol == 0) pack(ids); + else pack(NULL); + if (sort_flag) sort(); + + // Calculate data size written by this process + groupsize = nme * size_one * sizeof(double); // size of atoms data on this process + groupsize += 3*sizeof(uint64_t) + 1*sizeof(int); // scalars written by each process + if (me == 0) { + groupsize += 1*sizeof(uint64_t) + 1*sizeof(int) + 6*sizeof(double); // scalars + if (domain->triclinic) { + groupsize += 3*sizeof(double); // boxxy, boxxz, boxyz + } + } + + openfile(); + fh.BeginStep(); + // write info on data as scalars (by me==0) + if (me == 0) { + fh.Put("ntimestep", update->ntimestep); + fh.Put("nprocs", nprocs); + + fh.Put("boxxlo", boxxlo); + fh.Put("boxxhi", boxxhi); + fh.Put("boxylo", boxylo); + fh.Put("boxyhi", boxyhi); + fh.Put("boxzlo", boxzlo); + fh.Put("boxzhi", boxzhi); + + if (domain->triclinic) { + fh.Put("boxxy", boxxy); + fh.Put("boxxz", boxxz); + fh.Put("boxyz", boxyz); + } + } + // Everyone needs to write scalar variables that are used as dimensions and offsets of arrays + fh.Put("natoms", ntotal); + fh.Put("ncolumns", size_one); + fh.Put("nme", bnme); + fh.Put("offset", atomOffset); + // now write the atoms + fh.Put("atoms", buf); + fh.EndStep();// I/O will happen now... + + if (multifile) + { + fh.Close(); + } +} + +/* ---------------------------------------------------------------------- */ + +void DumpCustomADIOS::init_style() +{ + + // setup boundary string + + domain->boundary_string(boundstr); + + // remove % from filename since ADIOS always writes a global file with data/metadata + int len = strlen(filename); + char *ptr = strchr(filename,'%'); + if (ptr) { + *ptr = '\0'; + char *s = new char[len-1]; + sprintf(s,"%s%s",filename,ptr+1); + strncpy(filename,s,len); + } + + /* The next four loops are copied from dump_custom_mpiio, but nothing is done with them. + * It is unclear why we need them here. + * For metadata, variable[] will be written out as an ADIOS attribute if nvariable>0 + */ + // find current ptr for each compute,fix,variable + // check that fix frequency is acceptable + int icompute; + for (int i = 0; i < ncompute; i++) { + icompute = modify->find_compute(id_compute[i]); + 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(FLERR,"Could not find dump custom fix ID"); + fix[i] = modify->fix[ifix]; + if (nevery % modify->fix[ifix]->peratom_freq) + 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(FLERR,"Could not find dump custom variable name"); + variable[i] = ivariable; + } + + // set index and check validity of region + if (iregion >= 0) { + iregion = domain->find_region(idregion); + if (iregion == -1) + error->all(FLERR,"Region ID for dump custom does not exist"); + } + + /* Define the group of variables for the atom style here since it's a fixed set */ + adios2::IO io = ad->DeclareIO(ioName); + if (!io.InConfigFile()) + { + // if not defined by user, we can change the default settings + // BPFile is the default writer + io.SetEngine("BPFile"); + int num_aggregators = multiproc; + if (num_aggregators == 0) + num_aggregators = 1; + char nstreams[128]; + sprintf (nstreams, "%d", num_aggregators); + io.SetParameters({{"substreams", nstreams}}); + if (me==0 && screen) fprintf(screen, "ADIOS method for %s is n-to-m (aggregation with %s writers)\n", filename, nstreams); + } + + + io.DefineVariable("ntimestep"); + io.DefineVariable("natoms"); + + io.DefineVariable("nprocs"); + io.DefineVariable("ncolumns"); + + io.DefineVariable("boxxlo"); + io.DefineVariable("boxxhi"); + io.DefineVariable("boxylo"); + io.DefineVariable("boxyhi"); + io.DefineVariable("boxzlo"); + io.DefineVariable("boxzhi"); + + io.DefineVariable("boxxy"); + io.DefineVariable("boxxz"); + io.DefineVariable("boxyz"); + + io.DefineAttribute("triclinic", domain->triclinic); + + int *boundaryptr = reinterpret_cast(domain->boundary); + io.DefineAttribute("boundary", boundaryptr, 6); + + size_t nColumns = static_cast(size_one); + io.DefineAttribute("columns", columnNames.data(), nColumns); + io.DefineAttribute("columnstr", columns); + io.DefineAttribute("boundarystr", boundstr); + io.DefineAttribute("LAMMPS/dump_style", "atom"); + io.DefineAttribute("LAMMPS/version", universe->version); + io.DefineAttribute("LAMMPS/num_ver", universe->num_ver); + + io.DefineVariable("nme", {adios2::LocalValueDim}); // local dimension variable + io.DefineVariable("offset", {adios2::LocalValueDim}); // local dimension variable + + // atom table size is not known at the moment + // it will be correctly defined at the moment of write + size_t UnknownSizeYet = 1; + varAtoms = io.DefineVariable("atoms", + {UnknownSizeYet,nColumns}, + {UnknownSizeYet, 0}, + {UnknownSizeYet,nColumns}); + +} diff --git a/src/USER-ADIOS/dump_custom_adios.h b/src/USER-ADIOS/dump_custom_adios.h new file mode 100644 index 0000000000..2461e20b2e --- /dev/null +++ b/src/USER-ADIOS/dump_custom_adios.h @@ -0,0 +1,94 @@ +/* -*- 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 DUMP_CLASS + +DumpStyle(custom/adios,DumpCustomADIOS) + +#else + +#ifndef LMP_DUMP_CUSTOM_ADIOS_H +#define LMP_DUMP_CUSTOM_ADIOS_H + +#include "dump_custom.h" +#include +#include +#include "adios2.h" + +namespace LAMMPS_NS { + +class DumpCustomADIOS : public DumpCustom { + public: + DumpCustomADIOS(class LAMMPS *, int, char **); + virtual ~DumpCustomADIOS(); + + protected: + + const std::string ioName="custom"; // name of adios group, referrable in adios2_config.xml + adios2::ADIOS *ad = nullptr; // adios object + adios2::IO io; // adios group of variables and attributes in this dump + adios2::Engine fh; // adios file/stream handle object + adios2::Variable varAtoms; // one ADIOS output variable we need to change + uint64_t groupsize; // pre-calculate # of bytes written per processor in a step before writing anything + std::vectorcolumnNames; // list of column names for the atom table (individual list of 'columns' string) + + virtual void openfile(); + virtual void write(); + virtual void init_style(); + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Cannot open dump file %s + +The output file for the dump command cannot be opened. Check that the +path and name are correct. + +E: Too much per-proc info for dump + +Number of local atoms times number of columns must fit in a 32-bit +integer for dump. + +E: Dump_modify format string is too short + +There are more fields to be dumped in a line of output than your +format string specifies. + +E: Could not find dump custom compute ID + +Self-explanatory. + +E: Could not find dump custom fix ID + +Self-explanatory. + +E: Dump custom and fix not computed at compatible times + +The fix must produce per-atom quantities on timesteps that dump custom +needs them. + +E: Could not find dump custom variable name + +Self-explanatory. + +E: Region ID for dump custom does not exist + +Self-explanatory. + +*/ -- GitLab From 24234d3a0bc43ba1ba22800c0fb9fafd24464309 Mon Sep 17 00:00:00 2001 From: Norbert Podhorszki Date: Thu, 24 Jan 2019 14:14:50 -0500 Subject: [PATCH 0142/1243] Fixed cmake build for ADIOS 2.x --- cmake/CMakeLists.txt | 38 +++++++++++--------------------------- runconf | 2 +- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5010643fd8..bf2a176d58 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -216,6 +216,17 @@ endif() include_directories(${LAMMPS_SOURCE_DIR}) + +if(PKG_USER-ADIOS) + # The search for ADIOS2 must come before MPI because + # it includes its own MPI search with the latest FindMPI.cmake + # script that defines the MPI::MPI_C target + enable_language(C) + find_package(ADIOS2 REQUIRED) + list(APPEND LAMMPS_LINK_LIBS adios2::adios2) +endif() + + # do MPI detection after language activation, if MPI for these language is required find_package(MPI QUIET) option(BUILD_MPI "Build MPI version" ${MPI_FOUND}) @@ -1370,33 +1381,6 @@ if(BUILD_EXE) endif() endif() -#if(PKG_USER-ADIOS) -# cmake_minimum_required(VERSION 3.6) -# enable_language(C) -# -# find_package(ADIOS2 REQUIRED) -## find_package(MPI REQUIRED) -# include_directories(${ADIOS2_INCLUDE_DIRS}) -## include_directories(/opt/adios2/include) -## list(APPEND LAMMPS_LINK_LIBS ${ADIOS2_LIBRARIES}) -# list(APPEND LAMMPS_LINK_LIBS ${MPI_C_LIBRARIES}) -# if(BUILD_LIB) -## target_link_libraries(lammps adios2::adios2 MPI::MPI_C) -## #target_include_directories(lammps PRIVATE ${ADIOS_INCLUDE_DIRS}) -# elseif(BUILD_EXE) -## target_link_libraries(lmp adios2::adios2 MPI::MPI_C) -# endif() -#endif(PKG_USER-ADIOS) - -if(PKG_USER-ADIOS) - enable_language(C) - find_package(ADIOS2 REQUIRED) - if(BUILD_LIB) - target_link_libraries(lammps adios2::adios2) - elseif(BUILD_EXE) - target_link_libraries(lmp adios2::adios2) - endif() -endif() ############################################################################### # Build documentation diff --git a/runconf b/runconf index bb313981c5..18f05f38a5 100644 --- a/runconf +++ b/runconf @@ -1,7 +1,7 @@ # -D LAMMPS_SIZES=value # smallbig (default) or bigbig or smallsmall -export HDF5_ROOT=/opt/hdf5-serial +export HDF5_ROOT=/opt/hdf5-parallel export ADIOS2_DIR=/opt/adios2 cmake -D CMAKE_INSTALL_PREFIX=/opt/lammps \ -- GitLab From 200fed9d4c484318002779e728d33ad234d7cb55 Mon Sep 17 00:00:00 2001 From: Norbert Podhorszki Date: Thu, 24 Jan 2019 15:00:32 -0500 Subject: [PATCH 0143/1243] Fix basic errors in USER-ADIOS code --- src/USER-ADIOS/dump_atom_adios.cpp | 2 +- src/USER-ADIOS/dump_custom_adios.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/USER-ADIOS/dump_atom_adios.cpp b/src/USER-ADIOS/dump_atom_adios.cpp index b6ace357ac..e7a5f05e9d 100644 --- a/src/USER-ADIOS/dump_atom_adios.cpp +++ b/src/USER-ADIOS/dump_atom_adios.cpp @@ -254,7 +254,7 @@ void DumpAtomADIOS::init_style() pack_choice = &DumpAtomADIOS::pack_noscale_image; /* Define the group of variables for the atom style here since it's a fixed set */ - adios2::IO io = ad->DeclareIO(ioName); + io = ad->DeclareIO(ioName); if (!io.InConfigFile()) { // if not defined by user, we can change the default settings diff --git a/src/USER-ADIOS/dump_custom_adios.cpp b/src/USER-ADIOS/dump_custom_adios.cpp index 738e6dc076..5f54b987b1 100644 --- a/src/USER-ADIOS/dump_custom_adios.cpp +++ b/src/USER-ADIOS/dump_custom_adios.cpp @@ -63,7 +63,7 @@ DumpCustomADIOS::DumpCustomADIOS(LAMMPS *lmp, int narg, char **arg) : //if (screen) fprintf(screen, "DumpCustomADIOS constructor: nvariable=%d id_variable=%p, variables=%p, nfield=%d, earg=%p\n", nvariable, id_variable, variable, nfield, earg); columnNames.reserve(nfield); for (int i = 0; i < nfield; ++i) { - columnNames[i]=std::string(earg[i]); + columnNames.push_back(earg[i]); //if (screen) fprintf(screen, "earg[%d] = '%s'\n", i, earg[i]); } } @@ -294,7 +294,7 @@ void DumpCustomADIOS::init_style() } /* Define the group of variables for the atom style here since it's a fixed set */ - adios2::IO io = ad->DeclareIO(ioName); + io = ad->DeclareIO(ioName); if (!io.InConfigFile()) { // if not defined by user, we can change the default settings -- GitLab From 410d79d8b7d8ce4f01db038e10bd2a043a8dcdfd Mon Sep 17 00:00:00 2001 From: Norbert Podhorszki Date: Thu, 24 Jan 2019 15:01:15 -0500 Subject: [PATCH 0144/1243] Add an example for USER/adios based on the balance example --- examples/USER/adios/adios2_config.xml | 45 ++++++++++ examples/USER/adios/in.adios_balance | 56 +++++++++++++ examples/USER/adios/log.balance | 114 ++++++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 examples/USER/adios/adios2_config.xml create mode 100644 examples/USER/adios/in.adios_balance create mode 100644 examples/USER/adios/log.balance diff --git a/examples/USER/adios/adios2_config.xml b/examples/USER/adios/adios2_config.xml new file mode 100644 index 0000000000..5e1908eb52 --- /dev/null +++ b/examples/USER/adios/adios2_config.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/USER/adios/in.adios_balance b/examples/USER/adios/in.adios_balance new file mode 100644 index 0000000000..b44870afbb --- /dev/null +++ b/examples/USER/adios/in.adios_balance @@ -0,0 +1,56 @@ +# 2d circle of particles inside a box with LJ walls + +variable b index 0 + +variable x index 50 +variable y index 20 +variable d index 20 +variable v index 5 +variable w index 2 + +units lj +dimension 2 +atom_style atomic +boundary f f p + +lattice hex 0.85 +region box block 0 $x 0 $y -0.5 0.5 +create_box 1 box +region circle sphere $(v_d/2+1) $(v_d/2/sqrt(3.0)+1) 0.0 $(v_d/2) +create_atoms 1 region circle +mass 1 1.0 + +velocity all create 0.5 87287 loop geom +velocity all set $v $w 0 sum yes + +pair_style lj/cut 2.5 +pair_coeff 1 1 10.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 1 all nve + +fix 2 all wall/lj93 xlo 0.0 1 1 2.5 xhi $x 1 1 2.5 +fix 3 all wall/lj93 ylo 0.0 1 1 2.5 yhi $y 1 1 2.5 + +comm_style tiled +fix 10 all balance 50 0.9 rcb + +compute 1 all property/atom proc +variable p atom c_1%10 +dump 2 all custom 50 balance.dump id v_p x y z +dump 3 all custom/adios 50 balance_custom.bp id v_p x y z +dump 4 all atom/adios 50 balance_atom.bp + +#dump 3 all image 50 image.*.jpg v_p type & +# adiam 1.0 view 0 0 zoom 1.8 subbox yes 0.02 +#variable colors string & +# "red green blue yellow white & +# purple pink orange lime gray" +#dump_modify 3 pad 5 amap 0 10 sa 1 10 ${colors} + +thermo_style custom step temp epair press f_10[3] f_10 +thermo 100 + +run 200 diff --git a/examples/USER/adios/log.balance b/examples/USER/adios/log.balance new file mode 100644 index 0000000000..162ecf7741 --- /dev/null +++ b/examples/USER/adios/log.balance @@ -0,0 +1,114 @@ +LAMMPS (4 Jan 2019) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:87) + using 1 OpenMP thread(s) per MPI task +# 2d circle of particles inside a box with LJ walls + +variable b index 0 + +variable x index 50 +variable y index 20 +variable d index 20 +variable v index 5 +variable w index 2 + +units lj +dimension 2 +atom_style atomic +boundary f f p + +lattice hex 0.85 +Lattice spacing in x,y,z = 1.16553 2.01877 1.16553 +region box block 0 $x 0 $y -0.5 0.5 +region box block 0 50 0 $y -0.5 0.5 +region box block 0 50 0 20 -0.5 0.5 +create_box 1 box +Created orthogonal box = (0 0 -0.582767) to (58.2767 40.3753 0.582767) + 2 by 2 by 1 MPI processor grid +region circle sphere $(v_d/2+1) $(v_d/2/sqrt(3.0)+1) 0.0 $(v_d/2) +region circle sphere 11 $(v_d/2/sqrt(3.0)+1) 0.0 $(v_d/2) +region circle sphere 11 6.7735026918962581988 0.0 $(v_d/2) +region circle sphere 11 6.7735026918962581988 0.0 10 +create_atoms 1 region circle +Created 361 atoms + Time spent = 0.00171804 secs +mass 1 1.0 + +velocity all create 0.5 87287 loop geom +velocity all set $v $w 0 sum yes +velocity all set 5 $w 0 sum yes +velocity all set 5 2 0 sum yes + +pair_style lj/cut 2.5 +pair_coeff 1 1 10.0 1.0 2.5 + +neighbor 0.3 bin +neigh_modify delay 0 every 1 check yes + +fix 1 all nve + +fix 2 all wall/lj93 xlo 0.0 1 1 2.5 xhi $x 1 1 2.5 +fix 2 all wall/lj93 xlo 0.0 1 1 2.5 xhi 50 1 1 2.5 +fix 3 all wall/lj93 ylo 0.0 1 1 2.5 yhi $y 1 1 2.5 +fix 3 all wall/lj93 ylo 0.0 1 1 2.5 yhi 20 1 1 2.5 + +comm_style tiled +fix 10 all balance 50 0.9 rcb + +compute 1 all property/atom proc +variable p atom c_1%10 +dump 2 all custom 50 balance.dump id v_p x y z +dump 3 all custom/adios 50 balance_custom.bp id v_p x y z +dump 4 all atom/adios 50 balance_atom.bp + +#dump 3 all image 50 image.*.jpg v_p type # adiam 1.0 view 0 0 zoom 1.8 subbox yes 0.02 +#variable colors string # "red green blue yellow white # purple pink orange lime gray" +#dump_modify 3 pad 5 amap 0 10 sa 1 10 ${colors} + +thermo_style custom step temp epair press f_10[3] f_10 +thermo 100 + +run 200 +Neighbor list info ... + update every 1 steps, delay 0 steps, check yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 42 29 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d/newton + bin: standard +Per MPI rank memory allocation (min/avg/max) = 4.926 | 4.933 | 4.944 Mbytes +Step Temp E_pair Press f_10[3] f_10 + 0 25.701528 -29.143179 -1.2407285 3.2354571 1.0526316 + 100 26.269576 -29.713313 7.9052334 1.2742382 1.0304709 + 200 26.368336 -29.809962 1.6412462 1.2520776 1.0083102 +Loop time of 0.0992351 on 4 procs for 200 steps with 361 atoms + +Performance: 870660.046 tau/day, 2015.417 timesteps/s +32.2% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.0078368 | 0.0081607 | 0.0085468 | 0.3 | 8.22 +Neigh | 0.002804 | 0.0045915 | 0.0092173 | 3.9 | 4.63 +Comm | 0.044407 | 0.05352 | 0.062051 | 3.0 | 53.93 +Output | 0.011406 | 0.012025 | 0.01342 | 0.7 | 12.12 +Modify | 0.006305 | 0.0064294 | 0.0066617 | 0.2 | 6.48 +Other | | 0.01451 | | | 14.62 + +Nlocal: 90.25 ave 91 max 90 min +Histogram: 3 0 0 0 0 0 0 0 0 1 +Nghost: 58.25 ave 64 max 51 min +Histogram: 1 0 0 0 0 0 2 0 0 1 +Neighs: 730.75 ave 801 max 671 min +Histogram: 1 0 1 0 0 1 0 0 0 1 + +Total # of neighbors = 2923 +Ave neighs/atom = 8.09695 +Neighbor list builds = 60 +Dangerous builds = 0 +Total wall time: 0:00:00 -- GitLab From a4b9542ba95581a299c421e8d0b20545af06df68 Mon Sep 17 00:00:00 2001 From: Norbert Podhorszki Date: Wed, 6 Feb 2019 14:32:01 -0500 Subject: [PATCH 0145/1243] remove personal runconf file. cleanup ADIOS2 xml config file for example --- examples/USER/adios/adios2_config.xml | 17 ++--------------- runconf | 22 ---------------------- 2 files changed, 2 insertions(+), 37 deletions(-) delete mode 100644 runconf diff --git a/examples/USER/adios/adios2_config.xml b/examples/USER/adios/adios2_config.xml index 5e1908eb52..7462731d43 100644 --- a/examples/USER/adios/adios2_config.xml +++ b/examples/USER/adios/adios2_config.xml @@ -4,23 +4,10 @@ - LAMMPS Users Manual - + @@ -21,7 +21,7 @@ :line LAMMPS Documentation :c,h1 -8 Feb 2019 version :c,h2 +28 Feb 2019 version :c,h2 "What is a LAMMPS version?"_Manual_version.html diff --git a/src/version.h b/src/version.h index f15fa13e02..0539f757c9 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "8 Feb 2019" +#define LAMMPS_VERSION "28 Feb 2019" -- GitLab From 54e5c763338e958c8da3920a11cc99b606c406e6 Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 27 Feb 2019 15:50:08 -0600 Subject: [PATCH 0169/1243] Bump KIM API version to 2.0.1 --- cmake/CMakeLists.txt | 4 ++-- lib/kim/Install.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 30c8171f28..96cf6aa8b6 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -663,8 +663,8 @@ if(PKG_KIM) enable_language(Fortran) include(ExternalProject) ExternalProject_Add(kim_build - URL https://s3.openkim.org/kim-api/kim-api-v2-2.0.0.txz - URL_MD5 1ff8f563ad5991f7a2a25b35a13d7308 + URL https://s3.openkim.org/kim-api/kim-api-v2-2.0.1.txz + URL_MD5 289c57f0c3bc2a549662283cac1c4ef1 BINARY_DIR build CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} diff --git a/lib/kim/Install.py b/lib/kim/Install.py index e2465eec85..7a3d9c148d 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -18,7 +18,7 @@ parser = ArgumentParser(prog='Install.py', # settings thisdir = fullpath('.') -version = "kim-api-v2-2.0.0" +version = "kim-api-v2-2.0.1" # help message -- GitLab From 6bd56c2a85aad06f1451fbdd93c51a3803054033 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 27 Feb 2019 17:08:13 -0500 Subject: [PATCH 0170/1243] update author attribution --- src/USER-ADIOS/dump_custom_adios.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-ADIOS/dump_custom_adios.cpp b/src/USER-ADIOS/dump_custom_adios.cpp index 5b76688098..cd14195d45 100644 --- a/src/USER-ADIOS/dump_custom_adios.cpp +++ b/src/USER-ADIOS/dump_custom_adios.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Paul Coffman (IBM) + Contributing author: Norbert Podhorszki (ORNL) ------------------------------------------------------------------------- */ #include "dump_custom_adios.h" -- GitLab From b60f0f754cc82c1353f272ad358826f80284267f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 27 Feb 2019 17:18:08 -0500 Subject: [PATCH 0171/1243] small tweaks to USER-ADIOS docs --- doc/src/Build_extras.txt | 8 ++++++-- doc/src/dump_adios.txt | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/src/Build_extras.txt b/doc/src/Build_extras.txt index 4a12930304..0fa87f4b60 100644 --- a/doc/src/Build_extras.txt +++ b/doc/src/Build_extras.txt @@ -579,8 +579,12 @@ the lib/voronoi/Makefile.lammps file. USER-ADIOS package :h4,link(user-adios) -The USER-ADIOS package requires the "ADIOS I/O library"_https://github.com/ornladios/ADIOS2, version 2.3.1 or newer. -Make sure that you have ADIOS built with/without MPI if you build LAMMPS with/without MPI, respectively. +The USER-ADIOS package requires the "ADIOS I/O library"_https://github.com/ornladios/ADIOS2, +version 2.3.1 or newer. Make sure that you have ADIOS built either with or +without MPI to match if you build LAMMPS with or without MPI. +ADIOS compilation settings for LAMMPS are automatically detected, if the PATH +and LD_LIBRARY_PATH environment variables have been updated for the local ADIOS +installation and the instructions below are followed for the respective build systems. [CMake build]: diff --git a/doc/src/dump_adios.txt b/doc/src/dump_adios.txt index 7425264ea4..e3c919db5a 100644 --- a/doc/src/dump_adios.txt +++ b/doc/src/dump_adios.txt @@ -58,9 +58,9 @@ When using the ADIOS tool 'bpls' to list the content of a .bp file, bpls will print {__} for the size of the output table indicating that its size is changing every step. -The {atom/adios} and {custom/adios} dump styles are part of the USER-adios package. -They are only enabled if LAMMPS was built with that package. See the -"Build package"_Build_package.html doc page for more info. +The {atom/adios} and {custom/adios} dump styles are part of the USER-ADIOS +package. They are only enabled if LAMMPS was built with that package. +See the "Build package"_Build_package.html doc page for more info. :line -- GitLab From 286112ffbc5e3b48620957abb1508078a8326e6c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 11:00:55 -0500 Subject: [PATCH 0172/1243] count each force computation as one simulation step. this avoids accessing uninitialized data, too. --- .../phonon/dynamical_matrix_command/Manual.md | 48 ------------------- src/USER-PHONON/dynamical_matrix.cpp | 4 +- src/USER-PHONON/third_order.cpp | 4 +- 3 files changed, 6 insertions(+), 50 deletions(-) delete mode 100755 examples/USER/phonon/dynamical_matrix_command/Manual.md diff --git a/examples/USER/phonon/dynamical_matrix_command/Manual.md b/examples/USER/phonon/dynamical_matrix_command/Manual.md deleted file mode 100755 index c361f80325..0000000000 --- a/examples/USER/phonon/dynamical_matrix_command/Manual.md +++ /dev/null @@ -1,48 +0,0 @@ -# dynamical_matrix command - -## Syntax - -``` -dynamical_matrix group-ID style args keyword value ... -``` - -* group-ID = ID of group of atoms to displace -* style = *regular* or *eskm* -``` -*regular* args = gamma - gamma = finite difference displacement length -*eskm* args = gamma - gamma = finite difference displacement length -``` -* zero or more keyword/value pairs may be appended -* keyword = *file* or *binary* -``` -*file* value = output_file - output_file = name of file to dump the dynamical matrix into -*binary* values = *yes* or *no* or *gzip* -``` - -## Examples - -``` -dynamical_matrix 1 regular 0.000001 -dynamical_matrix 1 eskm 0.000001 -dynamical_matrix 3 regular 0.00004 file dynmat.dat -dynamical_matrix 5 eskm 0.00000001 file dynamical.dat binary yes -``` - -## Description - -Calculate the dynamical matrix of the selected group. - -## Restrictions - -None - -## Related commands - -None - -## Default - -The option defaults are file = "dynmat.dyn", binary = no diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index da98a23a7d..cef59b3a63 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -258,6 +258,7 @@ void DynamicalMatrix::calculateMatrix() if (comm->me == 0 && screen) fprintf(screen,"Calculating Dynamical Matrix...\n"); + update->nsteps = 0; for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); for (bigint alpha=0; alpha<3; alpha++){ @@ -390,6 +391,7 @@ void DynamicalMatrix::update_force() comm->reverse_comm(); timer->stamp(Timer::COMM); } + ++ update->nsteps; } /* ---------------------------------------------------------------------- @@ -545,4 +547,4 @@ void DynamicalMatrix::create_groupmap() delete[] displs; delete[] sub_groupmap; delete[] temp_groupmap; -} \ No newline at end of file +} diff --git a/src/USER-PHONON/third_order.cpp b/src/USER-PHONON/third_order.cpp index 41382e64cb..b4d2032a04 100644 --- a/src/USER-PHONON/third_order.cpp +++ b/src/USER-PHONON/third_order.cpp @@ -247,6 +247,7 @@ void ThirdOrder::calculateMatrix() if (comm->me == 0 && screen) fprintf(screen,"Calculating Anharmonic Dynamical Matrix...\n"); + update->nsteps = 0; for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); for (bigint alpha=0; alpha<3; alpha++){ @@ -411,6 +412,7 @@ void ThirdOrder::update_force() comm->reverse_comm(); timer->stamp(Timer::COMM); } + ++ update->nsteps; } /* ---------------------------------------------------------------------- @@ -551,4 +553,4 @@ void ThirdOrder::create_groupmap() delete[] displs; delete[] sub_groupmap; delete[] temp_groupmap; -} \ No newline at end of file +} -- GitLab From 5d8e3c6cb4d054f963d9319373ab2b43116b7d82 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 28 Feb 2019 10:14:35 -0700 Subject: [PATCH 0173/1243] Optimize reneighbor for small systems --- src/KOKKOS/comm_kokkos.cpp | 29 ++++++++++++++++------------- src/KOKKOS/comm_kokkos.h | 1 + src/KOKKOS/npair_kokkos.h | 4 ++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index c288a0e4a1..c782305ef5 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -1046,10 +1046,16 @@ void CommKokkos::borders_device() { } if (1) { - k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); - k_pbc_flag = DAT::tdual_int_1d("comm:pbc_flag",nswap); - k_firstrecv = DAT::tdual_int_1d("comm:firstrecv",nswap); - k_sendnum_scan = DAT::tdual_int_1d("comm:sendnum_scan",nswap); + if (nswap > k_pbc.extent(0)) { + k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); + k_swap = DAT::tdual_int_2d("comm:swap",3,nswap); + k_pbc_flag .d_view = Kokkos::subview(k_swap.d_view,0,Kokkos::ALL); + k_firstrecv .d_view = Kokkos::subview(k_swap.d_view,1,Kokkos::ALL); + k_sendnum_scan.d_view = Kokkos::subview(k_swap.d_view,2,Kokkos::ALL); + k_pbc_flag .h_view = Kokkos::subview(k_swap.h_view,0,Kokkos::ALL); + k_firstrecv .h_view = Kokkos::subview(k_swap.h_view,1,Kokkos::ALL); + k_sendnum_scan.h_view = Kokkos::subview(k_swap.h_view,2,Kokkos::ALL); + } int scan = 0; for (int iswap = 0; iswap < nswap; iswap++) { scan += sendnum[iswap]; @@ -1064,15 +1070,12 @@ void CommKokkos::borders_device() { k_pbc.h_view(iswap,5) = pbc[iswap][5]; } totalsend = scan; - k_pbc .modify(); - k_pbc_flag .modify(); - k_firstrecv .modify(); - k_sendnum_scan.modify(); - - k_pbc .sync(); - k_pbc_flag .sync(); - k_firstrecv .sync(); - k_sendnum_scan.sync(); + + k_swap.modify(); + k_pbc.modify(); + + k_swap.sync(); + k_pbc.sync(); } } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/comm_kokkos.h b/src/KOKKOS/comm_kokkos.h index bf2ee8822f..cab8124231 100644 --- a/src/KOKKOS/comm_kokkos.h +++ b/src/KOKKOS/comm_kokkos.h @@ -63,6 +63,7 @@ class CommKokkos : public CommBrick { //double *buf_send; // send buffer for all comm //double *buf_recv; // recv buffer for all comm + DAT::tdual_int_2d k_swap; DAT::tdual_int_2d k_pbc; DAT::tdual_int_1d k_pbc_flag; DAT::tdual_int_1d k_firstrecv; diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index 970e40c9fc..373ddf799e 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -280,7 +280,7 @@ class NeighborKokkosExecute bboxlo[0] = _bboxlo[0]; bboxlo[1] = _bboxlo[1]; bboxlo[2] = _bboxlo[2]; bboxhi[0] = _bboxhi[0]; bboxhi[1] = _bboxhi[1]; bboxhi[2] = _bboxhi[2]; - resize = typename AT::t_int_scalar("NeighborKokkosFunctor::resize"); + resize = typename AT::t_int_scalar(Kokkos::view_alloc("NeighborKokkosFunctor::resize",Kokkos::WithoutInitializing)); #ifndef KOKKOS_USE_CUDA_UVM h_resize = Kokkos::create_mirror_view(resize); #else @@ -288,7 +288,7 @@ class NeighborKokkosExecute #endif h_resize() = 1; new_maxneighs = typename AT:: - t_int_scalar("NeighborKokkosFunctor::new_maxneighs"); + t_int_scalar(Kokkos::view_alloc("NeighborKokkosFunctor::new_maxneighs",Kokkos::WithoutInitializing)); #ifndef KOKKOS_USE_CUDA_UVM h_new_maxneighs = Kokkos::create_mirror_view(new_maxneighs); #else -- GitLab From 16946d8c6d02adc64b7f608610a4de616e23225c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 14:45:07 -0500 Subject: [PATCH 0174/1243] integrate dynamical_matrix command into LAMMPS manual --- doc/src/Commands_all.txt | 1 + doc/src/commands_list.txt | 1 + doc/src/dynamical_matrix.txt | 52 +++++++++++++++++++++ doc/src/lammps.book | 1 + doc/utils/sphinx-config/false_positives.txt | 2 + src/USER-PHONON/README | 22 ++++++--- 6 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 doc/src/dynamical_matrix.txt diff --git a/doc/src/Commands_all.txt b/doc/src/Commands_all.txt index f137ccffd9..ff86cd842a 100644 --- a/doc/src/Commands_all.txt +++ b/doc/src/Commands_all.txt @@ -54,6 +54,7 @@ An alphabetic list of all general LAMMPS commands. "dump netcdf"_dump_netcdf.html, "dump netcdf/mpiio"_dump_netcdf.html, "dump vtk"_dump_vtk.html, +"dynamical_matrix"_dynamical_matrix.html, "echo"_echo.html, "fix"_fix.html, "fix_modify"_fix_modify.html, diff --git a/doc/src/commands_list.txt b/doc/src/commands_list.txt index 78fa9fbf87..81f088d3d3 100644 --- a/doc/src/commands_list.txt +++ b/doc/src/commands_list.txt @@ -39,6 +39,7 @@ Commands :h1 dump_molfile dump_netcdf dump_vtk + dynamical_matrix echo fix fix_modify diff --git a/doc/src/dynamical_matrix.txt b/doc/src/dynamical_matrix.txt new file mode 100644 index 0000000000..a7dc4e442e --- /dev/null +++ b/doc/src/dynamical_matrix.txt @@ -0,0 +1,52 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +dynamical_matrix command :h3 + +[Syntax:] + +dynamical_matrix group-ID style gamma args keyword value ... :pre + +group-ID = ID of group of atoms to displace :ulb,l +style = {regular} or {eskm} :l +gamma = finite different displacement length (distance units) :l +one or more keyword/arg pairs may be appended :l + keyword = {file} or {binary} + {file} name = name of output file for the dynamical matrix + {binary} arg = {yes} or {no} or {gzip} :pre +:ule + +[Examples:] + +dynamical_matrix 1 regular 0.000001 +dynamical_matrix 1 eskm 0.000001 +dynamical_matrix 3 regular 0.00004 file dynmat.dat +dynamical_matrix 5 eskm 0.00000001 file dynamical.dat binary yes :pre + +[Description:] + +Calculate the dynamical matrix of the selected group. + +[Restrictions:] + +The command collects the entire dynamical matrix a single MPI rank, +so the memory requirements can be very significant for large systems. + +This command assumes a periodic system. + +This command is part of the USER-PHONON package. It is only enabled if +LAMMPS was built with that package. See the "Build +package"_Build_package.html doc page for more info. + +[Related commands:] + +"fix phonon"_fix_phonon.html + +[Default:] + +The default settings are file = "dynmat.dyn", binary = no diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 5ae3456ad4..827cafed75 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -157,6 +157,7 @@ dump_molfile.html dump_netcdf.html dump_vtk.html dump_cfg_uef.html +dynamical_matrix.html echo.html group.html group2ndx.html diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 8807b2d680..bbfdf946f4 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -625,8 +625,10 @@ dVx dW dx dy +dyn dyne dynes +dynmat Dyre Dzyaloshinskii Eaa diff --git a/src/USER-PHONON/README b/src/USER-PHONON/README index 2212eaaebd..b1ffcb9b09 100644 --- a/src/USER-PHONON/README +++ b/src/USER-PHONON/README @@ -1,19 +1,24 @@ This package contains a fix phonon command that calculates dynamical -matrices, which can then be used to compute phonon dispersion -relations, directly from molecular dynamics simulations. +matrices from finite temperature MD simulations, which can then be +used to compute phonon dispersion relations, directly from molecular +dynamics simulations. -See the doc page for the fix phonon command for detailed usage -instructions. +It also contains two commands to compute the dynamical matrix and +the corresponding third order matrix at pre-optimized positions +through finite differences. + +See the doc page for the fix phonon command or the dynamical_matrix +third_order commands for detailed usage instructions. Use of this package requires building LAMMPS with FFT suppport, as described in doc/Section_start.html. -There are example scripts for using this package in +There are example scripts for using commands in this package in examples/USER/phonon. There is an auxiliary post-processing tool in tools/phonon that will compute phonon frequencies and dispersion relations from the dynamical -matrices output by this command. +matrices output by the fix phonon command. There is also an alternative code, dump2phonon, available which enables one to use the functions of fix-phonon by reading in atom-style dump @@ -21,6 +26,9 @@ files of lammps (which can be converted from the trajectories of any other MD code): https://github.com/lingtikong/dump2phonon -The person who created this package is Ling-Ti Kong (konglt at +The person who created fix phonon is Ling-Ti Kong (konglt at sjtu.edu.cn) at Shanghai Jiao Tong University. Contact him directly if you have questions. + +The person who created dynamical_matrix and third_order is +Charlie Sievers at UC Davis. -- GitLab From 9298fe7868c293a5b6fbca1753c9f07747913e2b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 14:45:42 -0500 Subject: [PATCH 0175/1243] fix segfault and copy-n-modify issues with third order command --- src/USER-PHONON/third_order.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/USER-PHONON/third_order.cpp b/src/USER-PHONON/third_order.cpp index b4d2032a04..f7d72687c6 100644 --- a/src/USER-PHONON/third_order.cpp +++ b/src/USER-PHONON/third_order.cpp @@ -13,6 +13,7 @@ #include "group.h" #include "force.h" #include "math_extra.h" +#include "memory.h" #include "bond.h" #include "angle.h" #include "dihedral.h" @@ -40,7 +41,8 @@ ThirdOrder::ThirdOrder(LAMMPS *lmp) : Pointers(lmp), fp(NULL) ThirdOrder::~ThirdOrder() { - if (fp) fclose(fp); + if (fp && me == 0) fclose(fp); + memory->destroy(groupmap); fp = NULL; } @@ -73,10 +75,11 @@ void ThirdOrder::setup() neighbor->ndanger = 0; // compute all forces - update_force(); + external_force_clear = 0; eflag=0; vflag=0; + update_force(); if (gcount == atom->natoms) for (bigint i=0; inatoms; i++) @@ -92,8 +95,8 @@ void ThirdOrder::command(int narg, char **arg) MPI_Comm_rank(world,&me); if (domain->box_exist == 0) - error->all(FLERR,"Dynamical_matrix command before simulation box is defined"); - if (narg < 2) error->all(FLERR,"Illegal dynamical_matrix command"); + error->all(FLERR,"Third_order command before simulation box is defined"); + if (narg < 2) error->all(FLERR,"Illegal third_oreder command"); lmp->init(); @@ -109,10 +112,11 @@ void ThirdOrder::command(int narg, char **arg) // group and style igroup = group->find(arg[0]); - if (igroup == -1) error->all(FLERR,"Could not find dynamical matrix group ID"); + if (igroup == -1) error->all(FLERR,"Could not find third_order group ID"); groupbit = group->bitmask[igroup]; gcount = group->count(igroup); dynlen = (gcount)*3; + memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); update->setupflag = 1; int style = -1; -- GitLab From 7062bc862eea91a173bec63e4d6a14c0d496d7a7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 15:21:48 -0500 Subject: [PATCH 0176/1243] remove third_order command and ASE based examples to be added in a new pull request --- .../dynamical_matrix_command/GaAs/GaAs.py | 39 - .../dynamical_matrix_command/GaN/GaN.py | 39 - .../dynamical_matrix_command/Quartz/quartz.py | 57 - .../third_order_command/silicon/Manual.md | 48 - .../third_order_command/silicon/README.md | 25 - .../silicon/Si.opt.tersoff | 66 - .../third_order_command/silicon/combine.sh | 17 - .../silicon/ff-silicon.lmp | 19 - .../third_order_command/silicon/in.silicon | 84 - .../silicon/lmp_bank/silicon_216.lmp | 238 - .../silicon/lmp_bank/silicon_512.lmp | 534 -- .../silicon/lmp_bank/silicon_8.lmp | 29 - .../silicon/results/out.silicon | 58 - .../silicon/results/third_order | 4608 ----------------- .../silicon/silicon_input_file.lmp | 29 - src/USER-PHONON/README | 11 +- src/USER-PHONON/third_order.cpp | 560 -- src/USER-PHONON/third_order.h | 76 - 18 files changed, 5 insertions(+), 6532 deletions(-) delete mode 100644 examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py delete mode 100644 examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py delete mode 100644 examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py delete mode 100755 examples/USER/phonon/third_order_command/silicon/Manual.md delete mode 100755 examples/USER/phonon/third_order_command/silicon/README.md delete mode 100755 examples/USER/phonon/third_order_command/silicon/Si.opt.tersoff delete mode 100755 examples/USER/phonon/third_order_command/silicon/combine.sh delete mode 100755 examples/USER/phonon/third_order_command/silicon/ff-silicon.lmp delete mode 100755 examples/USER/phonon/third_order_command/silicon/in.silicon delete mode 100755 examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_216.lmp delete mode 100755 examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_512.lmp delete mode 100755 examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_8.lmp delete mode 100755 examples/USER/phonon/third_order_command/silicon/results/out.silicon delete mode 100755 examples/USER/phonon/third_order_command/silicon/results/third_order delete mode 100755 examples/USER/phonon/third_order_command/silicon/silicon_input_file.lmp delete mode 100644 src/USER-PHONON/third_order.cpp delete mode 100644 src/USER-PHONON/third_order.h diff --git a/examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py b/examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py deleted file mode 100644 index 1e9d58a71b..0000000000 --- a/examples/USER/phonon/dynamical_matrix_command/GaAs/GaAs.py +++ /dev/null @@ -1,39 +0,0 @@ -from ase import Atoms, Atom -from ase.calculators.lammpslib import LAMMPSlib -import numpy as np -import matplotlib.pyplot as plt -from mpi4py import MPI - -comm = MPI.COMM_WORLD -rank = comm.Get_rank() - -GaAs = Atoms([Atom('Ga', (0.0, 0.0, 0.0)), - Atom('As', (1.413425, 1.413425, 1.413425))], - cell=[(0.0, 2.82685, 2.82685), (2.82685, 0.0, 2.82685), (2.82685, 2.82685, 0.0)], - pbc=True,) - -cmds = ["pair_style bop", "pair_coeff * * ../../../../../potentials/GaAs.bop.table Ga As", - "comm_modify cutoff 12"] - -mends = ["info system", - "dynamical_matrix all eskm 0.000001 file dynmat.dat binary no", - "neigh_modify delay 0"] - -N = 5 -GaAs = GaAs.repeat([N, N, N]) - -lammps = LAMMPSlib(lmpcmds=cmds, atom_types={'Ga': 1, 'As': 2}, amendments=mends, log_file='lammps.log') - -GaAs.set_calculator(lammps) -GaAs.get_potential_energy() - -if rank == 0: - dynmat = np.loadtxt("dynmat.dat") - dynmat = dynmat.reshape(([int(3*(len(dynmat)/3)**0.5), int(3*(len(dynmat)/3)**0.5)])) - eigv = np.linalg.eigvals(dynmat) - eigv.sort() - eigv = np.sqrt(np.abs(eigv))/(2*np.pi) - plt.hist(eigv, 80) - plt.xlabel('Frequency (THz)') - plt.show() - diff --git a/examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py b/examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py deleted file mode 100644 index 52e14ca47d..0000000000 --- a/examples/USER/phonon/dynamical_matrix_command/GaN/GaN.py +++ /dev/null @@ -1,39 +0,0 @@ -from ase import Atoms, Atom -from ase.calculators.lammpslib import LAMMPSlib -import numpy as np -import matplotlib.pyplot as plt -from mpi4py import MPI - -comm = MPI.COMM_WORLD -rank = comm.Get_rank() - -GaN = Atoms([Atom('Ga', (1.59, 0.917986928012, 0.0)), - Atom('Ga', (1.59, -0.917986928012, 2.583)), - Atom('N', (1.59, 0.917986928012, 1.98891)), - Atom('N', (1.59, -0.917986928012, 4.57191))], - cell=[(1.59, -2.75396078403, 0.0), (1.59, 2.75396078403, 0.0), (0.0, 0.0, 5.166)], - pbc=True) - -cmds = ["pair_style tersoff", "pair_coeff * * ../../../../../potentials/GaN.tersoff Ga N"] - -mends = ["info system", - "dynamical_matrix all eskm 0.000001 file dynmat.dat binary no", - "neigh_modify delay 0"] - -N = 6 -GaN = GaN.repeat([N, N, N]) - -lammps = LAMMPSlib(lmpcmds=cmds, atom_types={'Ga': 1, 'N': 2}, amendments=mends, log_file='lammps.log') - -GaN.set_calculator(lammps) -GaN.get_potential_energy() - -if rank == 0: - dynmat = np.loadtxt("dynmat.dat") - dynmat = dynmat.reshape(([int(3*(len(dynmat)/3)**0.5), int(3*(len(dynmat)/3)**0.5)])) - eigv = np.linalg.eigvals(dynmat) - eigv.sort() - eigv = np.sqrt(np.abs(eigv))/(2*np.pi) - plt.hist(eigv, 80) - plt.xlabel('Frequency (THz)') - plt.show() diff --git a/examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py b/examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py deleted file mode 100644 index 79a81aa95c..0000000000 --- a/examples/USER/phonon/dynamical_matrix_command/Quartz/quartz.py +++ /dev/null @@ -1,57 +0,0 @@ -from ase import Atoms, Atom -from ase.calculators.lammpslib import LAMMPSlib -import numpy as np -import matplotlib.pyplot as plt -from mpi4py import MPI - -comm = MPI.COMM_WORLD -rank = comm.Get_rank() - -quartz = Atoms( - [Atom('Si', (1.1545226, -1.99969180169, 0.0)), - Atom('Si', (1.1545226, 1.99969180169, 3.6036)), - Atom('Si', (2.6069548, 2.15247249027e-16, 1.8018)), - Atom('O', (1.6724232, -0.624132037742, 0.64378314)), - Atom('O', (1.6724232, 0.624132037742, 2.9598186618)), - Atom('O', (2.1623026, -2.49695388906, 4.2473849418)), - Atom('O', (3.5392742, 1.13629495821, 1.1580150582)), - Atom('O', (3.5392742, -1.13629495821, 2.4455813382)), - Atom('O', (2.1623026, 2.49695388906, 4.76161686))], - cell=[(2.458, -4.257380885, 0.0), (2.458, 4.257380885, 0.0), (0.0, 0.0, 5.4054)], - pbc=True, - ) - -# number of repeats -N = 3 -quartz = quartz.repeat([N, N, N]) - -header = ['units metal', - 'atom_style charge', - 'atom_modify map array sort 0 0'] - -cmds = ["pair_style buck/coul/long 10.0 8.0", - "pair_coeff 1 1 0 1 0", - "pair_coeff 1 2 18003.7572 0.20520 133.5381", - "pair_coeff 2 2 1388.7730 0.36232 175.0000", - "kspace_style ewald 1.0e-12", - "set type 1 charge 2.4", - "set type 2 charge -1.2"] - -mends = ["dynamical_matrix all eskm 0.000001 file dynmat.dat binary no", - "neigh_modify delay 0"] - - -lammps = LAMMPSlib(lmpcmds=cmds, lammps_header=header, amendments=mends, log_file='lammps.log') - -quartz.set_calculator(lammps) -quartz.get_potential_energy() - -if rank == 0: - dynmat = np.loadtxt("dynmat.dat") - dynmat = dynmat.reshape(([int(3*(len(dynmat)/3)**0.5), int(3*(len(dynmat)/3)**0.5)])) - eigv = np.linalg.eigvals(dynmat) - eigv.sort() - plt.hist(33*np.sqrt(np.abs(eigv))/(2*np.pi), 80) - plt.xlabel('Frequency (cm-1)') - plt.show() - diff --git a/examples/USER/phonon/third_order_command/silicon/Manual.md b/examples/USER/phonon/third_order_command/silicon/Manual.md deleted file mode 100755 index 49340cb54d..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/Manual.md +++ /dev/null @@ -1,48 +0,0 @@ -# third_order command - -## Syntax - -``` -third_order group-ID style args keyword value ... -``` - -* group-ID = ID of group of atoms to displace -* style = *regular* or *ballistico* -``` -*regular* args = gamma - gamma = finite difference displacement length -*ballistico* args = gamma - gamma = finite difference displacement length -``` -* zero or more keyword/value pairs may be appended -* keyword = *file* or *binary* -``` -*file* value = output_file - output_file = name of file to dump the dynamical matrix into -*binary* values = *no* or *gzip* -``` - -## Examples - -``` -third_order 1 regular 0.000001 -third_order 1 ballistico 0.000001 -third_order 3 regular 0.00004 file third_order.dat -third_order 5 ballistico 0.00000001 file third_order.dat binary gzip -``` - -## Description - -Calculate the finite difference third order tensor of the selected group. - -## Restrictions - -None - -## Related commands - -None - -## Default - -The option defaults are file = "third_order.dat", binary = no diff --git a/examples/USER/phonon/third_order_command/silicon/README.md b/examples/USER/phonon/third_order_command/silicon/README.md deleted file mode 100755 index c938734393..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# LAMMPS LATTICE DYNAMICS COMMANDS - -## THIRD ORDER TENSOR CALCULATOR - -This directory contains the ingredients to calculate a third order tensor. - -Example: -``` -$THIRD_ORDER=third_order #tensor output file -NP=4 #number of processors -mpirun -np $NP lmp_mpi -in in.silicon -out out.silicon -combine.sh third_order -``` - -To test out a different silicon example: -``` -$THIRD_ORDER=third_order -$LMP_FILE=amorphous_silicon.lmp -cp lmp_bank/$LMP_FILE ./silicon_input_file.lmp -NP=4 #number of processors -mpirun -np $NP lmp_mpi -in in.silicon -out out.silicon -bash combine.sh $THIRD_ORDER -``` - -## Requires: MANYBODY and MOLECULE packages diff --git a/examples/USER/phonon/third_order_command/silicon/Si.opt.tersoff b/examples/USER/phonon/third_order_command/silicon/Si.opt.tersoff deleted file mode 100755 index 3bc19f0581..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/Si.opt.tersoff +++ /dev/null @@ -1,66 +0,0 @@ -# Tersoff 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: -# A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms -# other quantities are unitless - -# Aidan Thompson (athomps at sandia.gov) takes full blame for this -# file. It specifies various potentials published by J. Tersoff for -# silicon, carbon and germanium. Since Tersoff published several -# different silicon potentials, I refer to them using atom types -# Si(B), Si(C) and Si(D). The last two are almost almost identical but -# refer to two different publications. These names should be used in -# the LAMMPS command when the file is invoked. For example: -# pair_coeff * * SiCGe.tersoff Si(B). The Si(D), C and Ge potentials -# can be used pure silicon, pure carbon, pure germanium, binary SiC, -# and binary SiGe, but not binary GeC or ternary SiGeC. LAMMPS will -# generate an error if this file is used with any combination -# involving C and Ge, since there are no entries for the GeC -# interactions (Tersoff did not publish parameters for this -# cross-interaction.) - -# format of a single entry (one or more lines): -# element 1, element 2, element 3, -# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A - -# The original Tersoff potential for Silicon, Si(B) -# J. Tersoff, PRB, 37, 6991 (1988) - -Si(B) Si(B) Si(B) 3.0 1.0 1.3258 4.8381 2.0417 0.0000 22.956 - 0.33675 1.3258 95.373 3.0 0.2 3.2394 3264.7 - -# The later Tersoff potential for Silicon, Si(C) -# J. Tersoff, PRB, 38, 9902 (1988) - -Si(C) Si(C) Si(C) 3.0 1.0 1.7322 1.0039e5 16.218 -0.59826 0.78734 - 1.0999e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 - -# The later Tersoff potential for Carbon, Silicon, and Germanium -# J. Tersoff, PRB, 39, 5566 (1989) + errata (PRB 41, 3248) -# The Si and C parameters are very close to those in SiC.tersoff - -C C C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 2.2119 346.74 1.95 0.15 3.4879 1393.6 -Si(D) Si(D) Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 -Ge Ge Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.7047 419.23 2.95 0.15 2.4451 1769.0 - -C Si(D) Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 -C Si(D) C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 1.95 0.15 0.0 0.0 -C C Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 - -Si(D) C C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 -Si(D) Si(D) C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 -Si(D) C Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 - -Si(D) Ge Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 -Si(D) Si(D) Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 -Si(D) Ge Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 - -Ge Si(D) Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 -Ge Si(D) Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.95 0.15 0.0 0.0 -Ge Ge Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 - -# Optimized Tersoff for Carbon: Lindsay and Broido PRB 81, 205441 (2010) -# element 1, element 2, element 3, -# m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A -C(O) C(O) C(O) 3.0 1.0 0.0 3.8049e4 4.3484 -0.930 0.72751 1.5724e-7 2.2119 430.0 1.95 0.15 3.4879 1393.6 - diff --git a/examples/USER/phonon/third_order_command/silicon/combine.sh b/examples/USER/phonon/third_order_command/silicon/combine.sh deleted file mode 100755 index 3eca2537be..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/combine.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -#This script takes one argument -#The argument is the base name for the split up tensor -#The script then combines and sorts the tensor -#$1 file name - -echo "$1" -[ -f $1 ] && rm $1 - -for i in $(ls ./$1*); do - cat $i >> temp - rm $i -done - -sort temp | sort -s -n -k 3 | sort -s -n -k 1 > $1 -rm temp diff --git a/examples/USER/phonon/third_order_command/silicon/ff-silicon.lmp b/examples/USER/phonon/third_order_command/silicon/ff-silicon.lmp deleted file mode 100755 index f3b895f168..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/ff-silicon.lmp +++ /dev/null @@ -1,19 +0,0 @@ -############################# -#Atoms types - mass - charge# -############################# -#@ 1 atom types #!THIS LINE IS NECESSARY DON'T SPEND HOURS FINDING THAT OUT!# - -variable Si equal 1 - -############# -#Atom Masses# -############# - -mass ${Si} 28.08550 - -########################### -#Pair Potentials - Tersoff# -########################### - -pair_style tersoff -pair_coeff * * Si.opt.tersoff Si(D) diff --git a/examples/USER/phonon/third_order_command/silicon/in.silicon b/examples/USER/phonon/third_order_command/silicon/in.silicon deleted file mode 100755 index b8a9e214c4..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/in.silicon +++ /dev/null @@ -1,84 +0,0 @@ -###############################mm -# Atom style - charge/vdw/bonded# -################################# -atom_style full - -############################################## -#Units Metal : eV - ps - angstrom - bar# -# Real : kcal/mol - fs - angstrom - atm# -############################################## -units metal - -############ -#Run number# -############ -variable run_no equal 0 # is it a restart? -variable res_no equal ${run_no}-1 # restart file number - -####################################### -#Random Seeds and Domain Decomposition# -####################################### -variable iseed0 equal 2357 -variable iseed1 equal 26488 -variable iseed2 equal 10669 -processors * * 1 - -########### -#Data File# -########### -variable inpfile string silicon_input_file.lmp -variable resfile string final_restart.${res_no} -variable ff_file string ff-silicon.lmp - -########## -#Run Type# -########## -variable minimise equal 0 #Energy Minimization - -############################### -#Molecular Dynamics Parameters# -############################### -neighbor 1 bin - -################################ -#Energy Minimization Parameters# -################################ -variable mtraj equal 1 # trajectory output frequency - all system -variable etol equal 1e-5 # % change in energy -variable ftol equal 1e-5 # max force threshold (force units) -variable maxiter equal 10000 # max # of iterations - -######################## -#3D Periodic Simulation# -######################## -boundary p p p - -############################# -#Reading the input structure# -############################# -if "${run_no} == 0" then "read_data ${inpfile}" else "read_restart ${resfile}" - -############# -#Force Field# -############# -include ${ff_file} - -##################### -#Energy Minimization# -##################### -if "${minimise} <= 0 || ${run_no} > 0" then "jump SELF end_minimise" - print "Doing CG minimisation" - dump mdcd all dcd ${mtraj} min.dcd - dump_modify mdcd unwrap yes - min_style cg - min_modify line quadratic - minimize ${etol} ${ftol} ${maxiter} ${maxiter} - reset_timestep 0 - undump mdcd -label end_minimise - -################## -#Dynamical Matrix# -################## -third_order all ballistico 0.00001 file third_order binary no - diff --git a/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_216.lmp b/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_216.lmp deleted file mode 100755 index 893d75e69b..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_216.lmp +++ /dev/null @@ -1,238 +0,0 @@ -LAMMPS description - - 216 atoms - 0 bonds - 0 angles - 0 dihedrals - 0 impropers - - 1 atom types - 0 bond types - 0 angle types - 0 dihedral types - 0 improper types - - - 0.0000000 16.293000 xlo xhi - 0.0000000 16.293000 ylo yhi - 0.0000000 16.293000 zlo zhi - - Atoms - - 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 - 2 2 1 0.0000000 0.0000000 2.7160000 2.7160000 - 3 3 1 0.0000000 2.7160000 2.7160000 0.0000000 - 4 4 1 0.0000000 2.7160000 0.0000000 2.7160000 - 5 5 1 0.0000000 4.0730000 1.3580000 4.0730000 - 6 6 1 0.0000000 1.3580000 1.3580000 1.3580000 - 7 7 1 0.0000000 1.3580000 4.0730000 4.0730000 - 8 8 1 0.0000000 4.0730000 4.0730000 1.3580000 - 9 9 1 0.0000000 0.0000000 0.0000000 5.4310000 - 10 10 1 0.0000000 0.0000000 2.7160000 8.1460000 - 11 11 1 0.0000000 2.7160000 2.7160000 5.4310000 - 12 12 1 0.0000000 2.7160000 0.0000000 8.1460000 - 13 13 1 0.0000000 4.0730000 1.3580000 9.5040000 - 14 14 1 0.0000000 1.3580000 1.3580000 6.7890000 - 15 15 1 0.0000000 1.3580000 4.0730000 9.5040000 - 16 16 1 0.0000000 4.0730000 4.0730000 6.7890000 - 17 17 1 0.0000000 0.0000000 0.0000000 10.8620000 - 18 18 1 0.0000000 0.0000000 2.7160000 13.5780000 - 19 19 1 0.0000000 2.7160000 2.7160000 10.8620000 - 20 20 1 0.0000000 2.7160000 0.0000000 13.5780000 - 21 21 1 0.0000000 4.0730000 1.3580000 14.9350000 - 22 22 1 0.0000000 1.3580000 1.3580000 12.2200000 - 23 23 1 0.0000000 1.3580000 4.0730000 14.9350000 - 24 24 1 0.0000000 4.0730000 4.0730000 12.2200000 - 25 25 1 0.0000000 0.0000000 5.4310000 0.0000000 - 26 26 1 0.0000000 0.0000000 8.1460000 2.7160000 - 27 27 1 0.0000000 2.7160000 8.1460000 0.0000000 - 28 28 1 0.0000000 2.7160000 5.4310000 2.7160000 - 29 29 1 0.0000000 4.0730000 6.7890000 4.0730000 - 30 30 1 0.0000000 1.3580000 6.7890000 1.3580000 - 31 31 1 0.0000000 1.3580000 9.5040000 4.0730000 - 32 32 1 0.0000000 4.0730000 9.5040000 1.3580000 - 33 33 1 0.0000000 0.0000000 5.4310000 5.4310000 - 34 34 1 0.0000000 0.0000000 8.1460000 8.1460000 - 35 35 1 0.0000000 2.7160000 8.1460000 5.4310000 - 36 36 1 0.0000000 2.7160000 5.4310000 8.1460000 - 37 37 1 0.0000000 4.0730000 6.7890000 9.5040000 - 38 38 1 0.0000000 1.3580000 6.7890000 6.7890000 - 39 39 1 0.0000000 1.3580000 9.5040000 9.5040000 - 40 40 1 0.0000000 4.0730000 9.5040000 6.7890000 - 41 41 1 0.0000000 0.0000000 5.4310000 10.8620000 - 42 42 1 0.0000000 0.0000000 8.1460000 13.5780000 - 43 43 1 0.0000000 2.7160000 8.1460000 10.8620000 - 44 44 1 0.0000000 2.7160000 5.4310000 13.5780000 - 45 45 1 0.0000000 4.0730000 6.7890000 14.9350000 - 46 46 1 0.0000000 1.3580000 6.7890000 12.2200000 - 47 47 1 0.0000000 1.3580000 9.5040000 14.9350000 - 48 48 1 0.0000000 4.0730000 9.5040000 12.2200000 - 49 49 1 0.0000000 0.0000000 10.8620000 0.0000000 - 50 50 1 0.0000000 0.0000000 13.5780000 2.7160000 - 51 51 1 0.0000000 2.7160000 13.5780000 0.0000000 - 52 52 1 0.0000000 2.7160000 10.8620000 2.7160000 - 53 53 1 0.0000000 4.0730000 12.2200000 4.0730000 - 54 54 1 0.0000000 1.3580000 12.2200000 1.3580000 - 55 55 1 0.0000000 1.3580000 14.9350000 4.0730000 - 56 56 1 0.0000000 4.0730000 14.9350000 1.3580000 - 57 57 1 0.0000000 0.0000000 10.8620000 5.4310000 - 58 58 1 0.0000000 0.0000000 13.5780000 8.1460000 - 59 59 1 0.0000000 2.7160000 13.5780000 5.4310000 - 60 60 1 0.0000000 2.7160000 10.8620000 8.1460000 - 61 61 1 0.0000000 4.0730000 12.2200000 9.5040000 - 62 62 1 0.0000000 1.3580000 12.2200000 6.7890000 - 63 63 1 0.0000000 1.3580000 14.9350000 9.5040000 - 64 64 1 0.0000000 4.0730000 14.9350000 6.7890000 - 65 65 1 0.0000000 0.0000000 10.8620000 10.8620000 - 66 66 1 0.0000000 0.0000000 13.5780000 13.5780000 - 67 67 1 0.0000000 2.7160000 13.5780000 10.8620000 - 68 68 1 0.0000000 2.7160000 10.8620000 13.5780000 - 69 69 1 0.0000000 4.0730000 12.2200000 14.9350000 - 70 70 1 0.0000000 1.3580000 12.2200000 12.2200000 - 71 71 1 0.0000000 1.3580000 14.9350000 14.9350000 - 72 72 1 0.0000000 4.0730000 14.9350000 12.2200000 - 73 73 1 0.0000000 5.4310000 0.0000000 0.0000000 - 74 74 1 0.0000000 5.4310000 2.7160000 2.7160000 - 75 75 1 0.0000000 8.1460000 2.7160000 0.0000000 - 76 76 1 0.0000000 8.1460000 0.0000000 2.7160000 - 77 77 1 0.0000000 9.5040000 1.3580000 4.0730000 - 78 78 1 0.0000000 6.7890000 1.3580000 1.3580000 - 79 79 1 0.0000000 6.7890000 4.0730000 4.0730000 - 80 80 1 0.0000000 9.5040000 4.0730000 1.3580000 - 81 81 1 0.0000000 5.4310000 0.0000000 5.4310000 - 82 82 1 0.0000000 5.4310000 2.7160000 8.1460000 - 83 83 1 0.0000000 8.1460000 2.7160000 5.4310000 - 84 84 1 0.0000000 8.1460000 0.0000000 8.1460000 - 85 85 1 0.0000000 9.5040000 1.3580000 9.5040000 - 86 86 1 0.0000000 6.7890000 1.3580000 6.7890000 - 87 87 1 0.0000000 6.7890000 4.0730000 9.5040000 - 88 88 1 0.0000000 9.5040000 4.0730000 6.7890000 - 89 89 1 0.0000000 5.4310000 0.0000000 10.8620000 - 90 90 1 0.0000000 5.4310000 2.7160000 13.5780000 - 91 91 1 0.0000000 8.1460000 2.7160000 10.8620000 - 92 92 1 0.0000000 8.1460000 0.0000000 13.5780000 - 93 93 1 0.0000000 9.5040000 1.3580000 14.9350000 - 94 94 1 0.0000000 6.7890000 1.3580000 12.2200000 - 95 95 1 0.0000000 6.7890000 4.0730000 14.9350000 - 96 96 1 0.0000000 9.5040000 4.0730000 12.2200000 - 97 97 1 0.0000000 5.4310000 5.4310000 0.0000000 - 98 98 1 0.0000000 5.4310000 8.1460000 2.7160000 - 99 99 1 0.0000000 8.1460000 8.1460000 0.0000000 - 100 100 1 0.0000000 8.1460000 5.4310000 2.7160000 - 101 101 1 0.0000000 9.5040000 6.7890000 4.0730000 - 102 102 1 0.0000000 6.7890000 6.7890000 1.3580000 - 103 103 1 0.0000000 6.7890000 9.5040000 4.0730000 - 104 104 1 0.0000000 9.5040000 9.5040000 1.3580000 - 105 105 1 0.0000000 5.4310000 5.4310000 5.4310000 - 106 106 1 0.0000000 5.4310000 8.1460000 8.1460000 - 107 107 1 0.0000000 8.1460000 8.1460000 5.4310000 - 108 108 1 0.0000000 8.1460000 5.4310000 8.1460000 - 109 109 1 0.0000000 9.5040000 6.7890000 9.5040000 - 110 110 1 0.0000000 6.7890000 6.7890000 6.7890000 - 111 111 1 0.0000000 6.7890000 9.5040000 9.5040000 - 112 112 1 0.0000000 9.5040000 9.5040000 6.7890000 - 113 113 1 0.0000000 5.4310000 5.4310000 10.8620000 - 114 114 1 0.0000000 5.4310000 8.1460000 13.5780000 - 115 115 1 0.0000000 8.1460000 8.1460000 10.8620000 - 116 116 1 0.0000000 8.1460000 5.4310000 13.5780000 - 117 117 1 0.0000000 9.5040000 6.7890000 14.9350000 - 118 118 1 0.0000000 6.7890000 6.7890000 12.2200000 - 119 119 1 0.0000000 6.7890000 9.5040000 14.9350000 - 120 120 1 0.0000000 9.5040000 9.5040000 12.2200000 - 121 121 1 0.0000000 5.4310000 10.8620000 0.0000000 - 122 122 1 0.0000000 5.4310000 13.5780000 2.7160000 - 123 123 1 0.0000000 8.1460000 13.5780000 0.0000000 - 124 124 1 0.0000000 8.1460000 10.8620000 2.7160000 - 125 125 1 0.0000000 9.5040000 12.2200000 4.0730000 - 126 126 1 0.0000000 6.7890000 12.2200000 1.3580000 - 127 127 1 0.0000000 6.7890000 14.9350000 4.0730000 - 128 128 1 0.0000000 9.5040000 14.9350000 1.3580000 - 129 129 1 0.0000000 5.4310000 10.8620000 5.4310000 - 130 130 1 0.0000000 5.4310000 13.5780000 8.1460000 - 131 131 1 0.0000000 8.1460000 13.5780000 5.4310000 - 132 132 1 0.0000000 8.1460000 10.8620000 8.1460000 - 133 133 1 0.0000000 9.5040000 12.2200000 9.5040000 - 134 134 1 0.0000000 6.7890000 12.2200000 6.7890000 - 135 135 1 0.0000000 6.7890000 14.9350000 9.5040000 - 136 136 1 0.0000000 9.5040000 14.9350000 6.7890000 - 137 137 1 0.0000000 5.4310000 10.8620000 10.8620000 - 138 138 1 0.0000000 5.4310000 13.5780000 13.5780000 - 139 139 1 0.0000000 8.1460000 13.5780000 10.8620000 - 140 140 1 0.0000000 8.1460000 10.8620000 13.5780000 - 141 141 1 0.0000000 9.5040000 12.2200000 14.9350000 - 142 142 1 0.0000000 6.7890000 12.2200000 12.2200000 - 143 143 1 0.0000000 6.7890000 14.9350000 14.9350000 - 144 144 1 0.0000000 9.5040000 14.9350000 12.2200000 - 145 145 1 0.0000000 10.8620000 0.0000000 0.0000000 - 146 146 1 0.0000000 10.8620000 2.7160000 2.7160000 - 147 147 1 0.0000000 13.5780000 2.7160000 0.0000000 - 148 148 1 0.0000000 13.5780000 0.0000000 2.7160000 - 149 149 1 0.0000000 14.9350000 1.3580000 4.0730000 - 150 150 1 0.0000000 12.2200000 1.3580000 1.3580000 - 151 151 1 0.0000000 12.2200000 4.0730000 4.0730000 - 152 152 1 0.0000000 14.9350000 4.0730000 1.3580000 - 153 153 1 0.0000000 10.8620000 0.0000000 5.4310000 - 154 154 1 0.0000000 10.8620000 2.7160000 8.1460000 - 155 155 1 0.0000000 13.5780000 2.7160000 5.4310000 - 156 156 1 0.0000000 13.5780000 0.0000000 8.1460000 - 157 157 1 0.0000000 14.9350000 1.3580000 9.5040000 - 158 158 1 0.0000000 12.2200000 1.3580000 6.7890000 - 159 159 1 0.0000000 12.2200000 4.0730000 9.5040000 - 160 160 1 0.0000000 14.9350000 4.0730000 6.7890000 - 161 161 1 0.0000000 10.8620000 0.0000000 10.8620000 - 162 162 1 0.0000000 10.8620000 2.7160000 13.5780000 - 163 163 1 0.0000000 13.5780000 2.7160000 10.8620000 - 164 164 1 0.0000000 13.5780000 0.0000000 13.5780000 - 165 165 1 0.0000000 14.9350000 1.3580000 14.9350000 - 166 166 1 0.0000000 12.2200000 1.3580000 12.2200000 - 167 167 1 0.0000000 12.2200000 4.0730000 14.9350000 - 168 168 1 0.0000000 14.9350000 4.0730000 12.2200000 - 169 169 1 0.0000000 10.8620000 5.4310000 0.0000000 - 170 170 1 0.0000000 10.8620000 8.1460000 2.7160000 - 171 171 1 0.0000000 13.5780000 8.1460000 0.0000000 - 172 172 1 0.0000000 13.5780000 5.4310000 2.7160000 - 173 173 1 0.0000000 14.9350000 6.7890000 4.0730000 - 174 174 1 0.0000000 12.2200000 6.7890000 1.3580000 - 175 175 1 0.0000000 12.2200000 9.5040000 4.0730000 - 176 176 1 0.0000000 14.9350000 9.5040000 1.3580000 - 177 177 1 0.0000000 10.8620000 5.4310000 5.4310000 - 178 178 1 0.0000000 10.8620000 8.1460000 8.1460000 - 179 179 1 0.0000000 13.5780000 8.1460000 5.4310000 - 180 180 1 0.0000000 13.5780000 5.4310000 8.1460000 - 181 181 1 0.0000000 14.9350000 6.7890000 9.5040000 - 182 182 1 0.0000000 12.2200000 6.7890000 6.7890000 - 183 183 1 0.0000000 12.2200000 9.5040000 9.5040000 - 184 184 1 0.0000000 14.9350000 9.5040000 6.7890000 - 185 185 1 0.0000000 10.8620000 5.4310000 10.8620000 - 186 186 1 0.0000000 10.8620000 8.1460000 13.5780000 - 187 187 1 0.0000000 13.5780000 8.1460000 10.8620000 - 188 188 1 0.0000000 13.5780000 5.4310000 13.5780000 - 189 189 1 0.0000000 14.9350000 6.7890000 14.9350000 - 190 190 1 0.0000000 12.2200000 6.7890000 12.2200000 - 191 191 1 0.0000000 12.2200000 9.5040000 14.9350000 - 192 192 1 0.0000000 14.9350000 9.5040000 12.2200000 - 193 193 1 0.0000000 10.8620000 10.8620000 0.0000000 - 194 194 1 0.0000000 10.8620000 13.5780000 2.7160000 - 195 195 1 0.0000000 13.5780000 13.5780000 0.0000000 - 196 196 1 0.0000000 13.5780000 10.8620000 2.7160000 - 197 197 1 0.0000000 14.9350000 12.2200000 4.0730000 - 198 198 1 0.0000000 12.2200000 12.2200000 1.3580000 - 199 199 1 0.0000000 12.2200000 14.9350000 4.0730000 - 200 200 1 0.0000000 14.9350000 14.9350000 1.3580000 - 201 201 1 0.0000000 10.8620000 10.8620000 5.4310000 - 202 202 1 0.0000000 10.8620000 13.5780000 8.1460000 - 203 203 1 0.0000000 13.5780000 13.5780000 5.4310000 - 204 204 1 0.0000000 13.5780000 10.8620000 8.1460000 - 205 205 1 0.0000000 14.9350000 12.2200000 9.5040000 - 206 206 1 0.0000000 12.2200000 12.2200000 6.7890000 - 207 207 1 0.0000000 12.2200000 14.9350000 9.5040000 - 208 208 1 0.0000000 14.9350000 14.9350000 6.7890000 - 209 209 1 0.0000000 10.8620000 10.8620000 10.8620000 - 210 210 1 0.0000000 10.8620000 13.5780000 13.5780000 - 211 211 1 0.0000000 13.5780000 13.5780000 10.8620000 - 212 212 1 0.0000000 13.5780000 10.8620000 13.5780000 - 213 213 1 0.0000000 14.9350000 12.2200000 14.9350000 - 214 214 1 0.0000000 12.2200000 12.2200000 12.2200000 - 215 215 1 0.0000000 12.2200000 14.9350000 14.9350000 - 216 216 1 0.0000000 14.9350000 14.9350000 12.2200000 - diff --git a/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_512.lmp b/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_512.lmp deleted file mode 100755 index 8c1ecd30bd..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_512.lmp +++ /dev/null @@ -1,534 +0,0 @@ -LAMMPS description - - 512 atoms - 0 bonds - 0 angles - 0 dihedrals - 0 impropers - - 1 atom types - 0 bond types - 0 angle types - 0 dihedral types - 0 improper types - - - 0.0000000 21.724000 xlo xhi - 0.0000000 21.724000 ylo yhi - 0.0000000 21.724000 zlo zhi - - Atoms - - 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 - 2 2 1 0.0000000 0.0000000 2.7150000 2.7150000 - 3 3 1 0.0000000 2.7150000 2.7150000 0.0000000 - 4 4 1 0.0000000 2.7150000 0.0000000 2.7150000 - 5 5 1 0.0000000 4.0730000 1.3580000 4.0730000 - 6 6 1 0.0000000 1.3580000 1.3580000 1.3580000 - 7 7 1 0.0000000 1.3580000 4.0730000 4.0730000 - 8 8 1 0.0000000 4.0730000 4.0730000 1.3580000 - 9 9 1 0.0000000 0.0000000 0.0000000 5.4310000 - 10 10 1 0.0000000 0.0000000 2.7150000 8.1460000 - 11 11 1 0.0000000 2.7150000 2.7150000 5.4310000 - 12 12 1 0.0000000 2.7150000 0.0000000 8.1460000 - 13 13 1 0.0000000 4.0730000 1.3580000 9.5040000 - 14 14 1 0.0000000 1.3580000 1.3580000 6.7890000 - 15 15 1 0.0000000 1.3580000 4.0730000 9.5040000 - 16 16 1 0.0000000 4.0730000 4.0730000 6.7890000 - 17 17 1 0.0000000 0.0000000 0.0000000 10.8620000 - 18 18 1 0.0000000 0.0000000 2.7150000 13.5770000 - 19 19 1 0.0000000 2.7150000 2.7150000 10.8620000 - 20 20 1 0.0000000 2.7150000 0.0000000 13.5770000 - 21 21 1 0.0000000 4.0730000 1.3580000 14.9350000 - 22 22 1 0.0000000 1.3580000 1.3580000 12.2200000 - 23 23 1 0.0000000 1.3580000 4.0730000 14.9350000 - 24 24 1 0.0000000 4.0730000 4.0730000 12.2200000 - 25 25 1 0.0000000 0.0000000 0.0000000 16.2930000 - 26 26 1 0.0000000 0.0000000 2.7150000 19.0080000 - 27 27 1 0.0000000 2.7150000 2.7150000 16.2930000 - 28 28 1 0.0000000 2.7150000 0.0000000 19.0080000 - 29 29 1 0.0000000 4.0730000 1.3580000 20.3660000 - 30 30 1 0.0000000 1.3580000 1.3580000 17.6510000 - 31 31 1 0.0000000 1.3580000 4.0730000 20.3660000 - 32 32 1 0.0000000 4.0730000 4.0730000 17.6510000 - 33 33 1 0.0000000 0.0000000 5.4310000 0.0000000 - 34 34 1 0.0000000 0.0000000 8.1460000 2.7150000 - 35 35 1 0.0000000 2.7150000 8.1460000 0.0000000 - 36 36 1 0.0000000 2.7150000 5.4310000 2.7150000 - 37 37 1 0.0000000 4.0730000 6.7890000 4.0730000 - 38 38 1 0.0000000 1.3580000 6.7890000 1.3580000 - 39 39 1 0.0000000 1.3580000 9.5040000 4.0730000 - 40 40 1 0.0000000 4.0730000 9.5040000 1.3580000 - 41 41 1 0.0000000 0.0000000 5.4310000 5.4310000 - 42 42 1 0.0000000 0.0000000 8.1460000 8.1460000 - 43 43 1 0.0000000 2.7150000 8.1460000 5.4310000 - 44 44 1 0.0000000 2.7150000 5.4310000 8.1460000 - 45 45 1 0.0000000 4.0730000 6.7890000 9.5040000 - 46 46 1 0.0000000 1.3580000 6.7890000 6.7890000 - 47 47 1 0.0000000 1.3580000 9.5040000 9.5040000 - 48 48 1 0.0000000 4.0730000 9.5040000 6.7890000 - 49 49 1 0.0000000 0.0000000 5.4310000 10.8620000 - 50 50 1 0.0000000 0.0000000 8.1460000 13.5770000 - 51 51 1 0.0000000 2.7150000 8.1460000 10.8620000 - 52 52 1 0.0000000 2.7150000 5.4310000 13.5770000 - 53 53 1 0.0000000 4.0730000 6.7890000 14.9350000 - 54 54 1 0.0000000 1.3580000 6.7890000 12.2200000 - 55 55 1 0.0000000 1.3580000 9.5040000 14.9350000 - 56 56 1 0.0000000 4.0730000 9.5040000 12.2200000 - 57 57 1 0.0000000 0.0000000 5.4310000 16.2930000 - 58 58 1 0.0000000 0.0000000 8.1460000 19.0080000 - 59 59 1 0.0000000 2.7150000 8.1460000 16.2930000 - 60 60 1 0.0000000 2.7150000 5.4310000 19.0080000 - 61 61 1 0.0000000 4.0730000 6.7890000 20.3660000 - 62 62 1 0.0000000 1.3580000 6.7890000 17.6510000 - 63 63 1 0.0000000 1.3580000 9.5040000 20.3660000 - 64 64 1 0.0000000 4.0730000 9.5040000 17.6510000 - 65 65 1 0.0000000 0.0000000 10.8620000 0.0000000 - 66 66 1 0.0000000 0.0000000 13.5770000 2.7150000 - 67 67 1 0.0000000 2.7150000 13.5770000 0.0000000 - 68 68 1 0.0000000 2.7150000 10.8620000 2.7150000 - 69 69 1 0.0000000 4.0730000 12.2200000 4.0730000 - 70 70 1 0.0000000 1.3580000 12.2200000 1.3580000 - 71 71 1 0.0000000 1.3580000 14.9350000 4.0730000 - 72 72 1 0.0000000 4.0730000 14.9350000 1.3580000 - 73 73 1 0.0000000 0.0000000 10.8620000 5.4310000 - 74 74 1 0.0000000 0.0000000 13.5770000 8.1460000 - 75 75 1 0.0000000 2.7150000 13.5770000 5.4310000 - 76 76 1 0.0000000 2.7150000 10.8620000 8.1460000 - 77 77 1 0.0000000 4.0730000 12.2200000 9.5040000 - 78 78 1 0.0000000 1.3580000 12.2200000 6.7890000 - 79 79 1 0.0000000 1.3580000 14.9350000 9.5040000 - 80 80 1 0.0000000 4.0730000 14.9350000 6.7890000 - 81 81 1 0.0000000 0.0000000 10.8620000 10.8620000 - 82 82 1 0.0000000 0.0000000 13.5770000 13.5770000 - 83 83 1 0.0000000 2.7150000 13.5770000 10.8620000 - 84 84 1 0.0000000 2.7150000 10.8620000 13.5770000 - 85 85 1 0.0000000 4.0730000 12.2200000 14.9350000 - 86 86 1 0.0000000 1.3580000 12.2200000 12.2200000 - 87 87 1 0.0000000 1.3580000 14.9350000 14.9350000 - 88 88 1 0.0000000 4.0730000 14.9350000 12.2200000 - 89 89 1 0.0000000 0.0000000 10.8620000 16.2930000 - 90 90 1 0.0000000 0.0000000 13.5770000 19.0080000 - 91 91 1 0.0000000 2.7150000 13.5770000 16.2930000 - 92 92 1 0.0000000 2.7150000 10.8620000 19.0080000 - 93 93 1 0.0000000 4.0730000 12.2200000 20.3660000 - 94 94 1 0.0000000 1.3580000 12.2200000 17.6510000 - 95 95 1 0.0000000 1.3580000 14.9350000 20.3660000 - 96 96 1 0.0000000 4.0730000 14.9350000 17.6510000 - 97 97 1 0.0000000 0.0000000 16.2930000 0.0000000 - 98 98 1 0.0000000 0.0000000 19.0080000 2.7150000 - 99 99 1 0.0000000 2.7150000 19.0080000 0.0000000 - 100 100 1 0.0000000 2.7150000 16.2930000 2.7150000 - 101 101 1 0.0000000 4.0730000 17.6510000 4.0730000 - 102 102 1 0.0000000 1.3580000 17.6510000 1.3580000 - 103 103 1 0.0000000 1.3580000 20.3660000 4.0730000 - 104 104 1 0.0000000 4.0730000 20.3660000 1.3580000 - 105 105 1 0.0000000 0.0000000 16.2930000 5.4310000 - 106 106 1 0.0000000 0.0000000 19.0080000 8.1460000 - 107 107 1 0.0000000 2.7150000 19.0080000 5.4310000 - 108 108 1 0.0000000 2.7150000 16.2930000 8.1460000 - 109 109 1 0.0000000 4.0730000 17.6510000 9.5040000 - 110 110 1 0.0000000 1.3580000 17.6510000 6.7890000 - 111 111 1 0.0000000 1.3580000 20.3660000 9.5040000 - 112 112 1 0.0000000 4.0730000 20.3660000 6.7890000 - 113 113 1 0.0000000 0.0000000 16.2930000 10.8620000 - 114 114 1 0.0000000 0.0000000 19.0080000 13.5770000 - 115 115 1 0.0000000 2.7150000 19.0080000 10.8620000 - 116 116 1 0.0000000 2.7150000 16.2930000 13.5770000 - 117 117 1 0.0000000 4.0730000 17.6510000 14.9350000 - 118 118 1 0.0000000 1.3580000 17.6510000 12.2200000 - 119 119 1 0.0000000 1.3580000 20.3660000 14.9350000 - 120 120 1 0.0000000 4.0730000 20.3660000 12.2200000 - 121 121 1 0.0000000 0.0000000 16.2930000 16.2930000 - 122 122 1 0.0000000 0.0000000 19.0080000 19.0080000 - 123 123 1 0.0000000 2.7150000 19.0080000 16.2930000 - 124 124 1 0.0000000 2.7150000 16.2930000 19.0080000 - 125 125 1 0.0000000 4.0730000 17.6510000 20.3660000 - 126 126 1 0.0000000 1.3580000 17.6510000 17.6510000 - 127 127 1 0.0000000 1.3580000 20.3660000 20.3660000 - 128 128 1 0.0000000 4.0730000 20.3660000 17.6510000 - 129 129 1 0.0000000 5.4310000 0.0000000 0.0000000 - 130 130 1 0.0000000 5.4310000 2.7150000 2.7150000 - 131 131 1 0.0000000 8.1460000 2.7150000 0.0000000 - 132 132 1 0.0000000 8.1460000 0.0000000 2.7150000 - 133 133 1 0.0000000 9.5040000 1.3580000 4.0730000 - 134 134 1 0.0000000 6.7890000 1.3580000 1.3580000 - 135 135 1 0.0000000 6.7890000 4.0730000 4.0730000 - 136 136 1 0.0000000 9.5040000 4.0730000 1.3580000 - 137 137 1 0.0000000 5.4310000 0.0000000 5.4310000 - 138 138 1 0.0000000 5.4310000 2.7150000 8.1460000 - 139 139 1 0.0000000 8.1460000 2.7150000 5.4310000 - 140 140 1 0.0000000 8.1460000 0.0000000 8.1460000 - 141 141 1 0.0000000 9.5040000 1.3580000 9.5040000 - 142 142 1 0.0000000 6.7890000 1.3580000 6.7890000 - 143 143 1 0.0000000 6.7890000 4.0730000 9.5040000 - 144 144 1 0.0000000 9.5040000 4.0730000 6.7890000 - 145 145 1 0.0000000 5.4310000 0.0000000 10.8620000 - 146 146 1 0.0000000 5.4310000 2.7150000 13.5770000 - 147 147 1 0.0000000 8.1460000 2.7150000 10.8620000 - 148 148 1 0.0000000 8.1460000 0.0000000 13.5770000 - 149 149 1 0.0000000 9.5040000 1.3580000 14.9350000 - 150 150 1 0.0000000 6.7890000 1.3580000 12.2200000 - 151 151 1 0.0000000 6.7890000 4.0730000 14.9350000 - 152 152 1 0.0000000 9.5040000 4.0730000 12.2200000 - 153 153 1 0.0000000 5.4310000 0.0000000 16.2930000 - 154 154 1 0.0000000 5.4310000 2.7150000 19.0080000 - 155 155 1 0.0000000 8.1460000 2.7150000 16.2930000 - 156 156 1 0.0000000 8.1460000 0.0000000 19.0080000 - 157 157 1 0.0000000 9.5040000 1.3580000 20.3660000 - 158 158 1 0.0000000 6.7890000 1.3580000 17.6510000 - 159 159 1 0.0000000 6.7890000 4.0730000 20.3660000 - 160 160 1 0.0000000 9.5040000 4.0730000 17.6510000 - 161 161 1 0.0000000 5.4310000 5.4310000 0.0000000 - 162 162 1 0.0000000 5.4310000 8.1460000 2.7150000 - 163 163 1 0.0000000 8.1460000 8.1460000 0.0000000 - 164 164 1 0.0000000 8.1460000 5.4310000 2.7150000 - 165 165 1 0.0000000 9.5040000 6.7890000 4.0730000 - 166 166 1 0.0000000 6.7890000 6.7890000 1.3580000 - 167 167 1 0.0000000 6.7890000 9.5040000 4.0730000 - 168 168 1 0.0000000 9.5040000 9.5040000 1.3580000 - 169 169 1 0.0000000 5.4310000 5.4310000 5.4310000 - 170 170 1 0.0000000 5.4310000 8.1460000 8.1460000 - 171 171 1 0.0000000 8.1460000 8.1460000 5.4310000 - 172 172 1 0.0000000 8.1460000 5.4310000 8.1460000 - 173 173 1 0.0000000 9.5040000 6.7890000 9.5040000 - 174 174 1 0.0000000 6.7890000 6.7890000 6.7890000 - 175 175 1 0.0000000 6.7890000 9.5040000 9.5040000 - 176 176 1 0.0000000 9.5040000 9.5040000 6.7890000 - 177 177 1 0.0000000 5.4310000 5.4310000 10.8620000 - 178 178 1 0.0000000 5.4310000 8.1460000 13.5770000 - 179 179 1 0.0000000 8.1460000 8.1460000 10.8620000 - 180 180 1 0.0000000 8.1460000 5.4310000 13.5770000 - 181 181 1 0.0000000 9.5040000 6.7890000 14.9350000 - 182 182 1 0.0000000 6.7890000 6.7890000 12.2200000 - 183 183 1 0.0000000 6.7890000 9.5040000 14.9350000 - 184 184 1 0.0000000 9.5040000 9.5040000 12.2200000 - 185 185 1 0.0000000 5.4310000 5.4310000 16.2930000 - 186 186 1 0.0000000 5.4310000 8.1460000 19.0080000 - 187 187 1 0.0000000 8.1460000 8.1460000 16.2930000 - 188 188 1 0.0000000 8.1460000 5.4310000 19.0080000 - 189 189 1 0.0000000 9.5040000 6.7890000 20.3660000 - 190 190 1 0.0000000 6.7890000 6.7890000 17.6510000 - 191 191 1 0.0000000 6.7890000 9.5040000 20.3660000 - 192 192 1 0.0000000 9.5040000 9.5040000 17.6510000 - 193 193 1 0.0000000 5.4310000 10.8620000 0.0000000 - 194 194 1 0.0000000 5.4310000 13.5770000 2.7150000 - 195 195 1 0.0000000 8.1460000 13.5770000 0.0000000 - 196 196 1 0.0000000 8.1460000 10.8620000 2.7150000 - 197 197 1 0.0000000 9.5040000 12.2200000 4.0730000 - 198 198 1 0.0000000 6.7890000 12.2200000 1.3580000 - 199 199 1 0.0000000 6.7890000 14.9350000 4.0730000 - 200 200 1 0.0000000 9.5040000 14.9350000 1.3580000 - 201 201 1 0.0000000 5.4310000 10.8620000 5.4310000 - 202 202 1 0.0000000 5.4310000 13.5770000 8.1460000 - 203 203 1 0.0000000 8.1460000 13.5770000 5.4310000 - 204 204 1 0.0000000 8.1460000 10.8620000 8.1460000 - 205 205 1 0.0000000 9.5040000 12.2200000 9.5040000 - 206 206 1 0.0000000 6.7890000 12.2200000 6.7890000 - 207 207 1 0.0000000 6.7890000 14.9350000 9.5040000 - 208 208 1 0.0000000 9.5040000 14.9350000 6.7890000 - 209 209 1 0.0000000 5.4310000 10.8620000 10.8620000 - 210 210 1 0.0000000 5.4310000 13.5770000 13.5770000 - 211 211 1 0.0000000 8.1460000 13.5770000 10.8620000 - 212 212 1 0.0000000 8.1460000 10.8620000 13.5770000 - 213 213 1 0.0000000 9.5040000 12.2200000 14.9350000 - 214 214 1 0.0000000 6.7890000 12.2200000 12.2200000 - 215 215 1 0.0000000 6.7890000 14.9350000 14.9350000 - 216 216 1 0.0000000 9.5040000 14.9350000 12.2200000 - 217 217 1 0.0000000 5.4310000 10.8620000 16.2930000 - 218 218 1 0.0000000 5.4310000 13.5770000 19.0080000 - 219 219 1 0.0000000 8.1460000 13.5770000 16.2930000 - 220 220 1 0.0000000 8.1460000 10.8620000 19.0080000 - 221 221 1 0.0000000 9.5040000 12.2200000 20.3660000 - 222 222 1 0.0000000 6.7890000 12.2200000 17.6510000 - 223 223 1 0.0000000 6.7890000 14.9350000 20.3660000 - 224 224 1 0.0000000 9.5040000 14.9350000 17.6510000 - 225 225 1 0.0000000 5.4310000 16.2930000 0.0000000 - 226 226 1 0.0000000 5.4310000 19.0080000 2.7150000 - 227 227 1 0.0000000 8.1460000 19.0080000 0.0000000 - 228 228 1 0.0000000 8.1460000 16.2930000 2.7150000 - 229 229 1 0.0000000 9.5040000 17.6510000 4.0730000 - 230 230 1 0.0000000 6.7890000 17.6510000 1.3580000 - 231 231 1 0.0000000 6.7890000 20.3660000 4.0730000 - 232 232 1 0.0000000 9.5040000 20.3660000 1.3580000 - 233 233 1 0.0000000 5.4310000 16.2930000 5.4310000 - 234 234 1 0.0000000 5.4310000 19.0080000 8.1460000 - 235 235 1 0.0000000 8.1460000 19.0080000 5.4310000 - 236 236 1 0.0000000 8.1460000 16.2930000 8.1460000 - 237 237 1 0.0000000 9.5040000 17.6510000 9.5040000 - 238 238 1 0.0000000 6.7890000 17.6510000 6.7890000 - 239 239 1 0.0000000 6.7890000 20.3660000 9.5040000 - 240 240 1 0.0000000 9.5040000 20.3660000 6.7890000 - 241 241 1 0.0000000 5.4310000 16.2930000 10.8620000 - 242 242 1 0.0000000 5.4310000 19.0080000 13.5770000 - 243 243 1 0.0000000 8.1460000 19.0080000 10.8620000 - 244 244 1 0.0000000 8.1460000 16.2930000 13.5770000 - 245 245 1 0.0000000 9.5040000 17.6510000 14.9350000 - 246 246 1 0.0000000 6.7890000 17.6510000 12.2200000 - 247 247 1 0.0000000 6.7890000 20.3660000 14.9350000 - 248 248 1 0.0000000 9.5040000 20.3660000 12.2200000 - 249 249 1 0.0000000 5.4310000 16.2930000 16.2930000 - 250 250 1 0.0000000 5.4310000 19.0080000 19.0080000 - 251 251 1 0.0000000 8.1460000 19.0080000 16.2930000 - 252 252 1 0.0000000 8.1460000 16.2930000 19.0080000 - 253 253 1 0.0000000 9.5040000 17.6510000 20.3660000 - 254 254 1 0.0000000 6.7890000 17.6510000 17.6510000 - 255 255 1 0.0000000 6.7890000 20.3660000 20.3660000 - 256 256 1 0.0000000 9.5040000 20.3660000 17.6510000 - 257 257 1 0.0000000 10.8620000 0.0000000 0.0000000 - 258 258 1 0.0000000 10.8620000 2.7150000 2.7150000 - 259 259 1 0.0000000 13.5770000 2.7150000 0.0000000 - 260 260 1 0.0000000 13.5770000 0.0000000 2.7150000 - 261 261 1 0.0000000 14.9350000 1.3580000 4.0730000 - 262 262 1 0.0000000 12.2200000 1.3580000 1.3580000 - 263 263 1 0.0000000 12.2200000 4.0730000 4.0730000 - 264 264 1 0.0000000 14.9350000 4.0730000 1.3580000 - 265 265 1 0.0000000 10.8620000 0.0000000 5.4310000 - 266 266 1 0.0000000 10.8620000 2.7150000 8.1460000 - 267 267 1 0.0000000 13.5770000 2.7150000 5.4310000 - 268 268 1 0.0000000 13.5770000 0.0000000 8.1460000 - 269 269 1 0.0000000 14.9350000 1.3580000 9.5040000 - 270 270 1 0.0000000 12.2200000 1.3580000 6.7890000 - 271 271 1 0.0000000 12.2200000 4.0730000 9.5040000 - 272 272 1 0.0000000 14.9350000 4.0730000 6.7890000 - 273 273 1 0.0000000 10.8620000 0.0000000 10.8620000 - 274 274 1 0.0000000 10.8620000 2.7150000 13.5770000 - 275 275 1 0.0000000 13.5770000 2.7150000 10.8620000 - 276 276 1 0.0000000 13.5770000 0.0000000 13.5770000 - 277 277 1 0.0000000 14.9350000 1.3580000 14.9350000 - 278 278 1 0.0000000 12.2200000 1.3580000 12.2200000 - 279 279 1 0.0000000 12.2200000 4.0730000 14.9350000 - 280 280 1 0.0000000 14.9350000 4.0730000 12.2200000 - 281 281 1 0.0000000 10.8620000 0.0000000 16.2930000 - 282 282 1 0.0000000 10.8620000 2.7150000 19.0080000 - 283 283 1 0.0000000 13.5770000 2.7150000 16.2930000 - 284 284 1 0.0000000 13.5770000 0.0000000 19.0080000 - 285 285 1 0.0000000 14.9350000 1.3580000 20.3660000 - 286 286 1 0.0000000 12.2200000 1.3580000 17.6510000 - 287 287 1 0.0000000 12.2200000 4.0730000 20.3660000 - 288 288 1 0.0000000 14.9350000 4.0730000 17.6510000 - 289 289 1 0.0000000 10.8620000 5.4310000 0.0000000 - 290 290 1 0.0000000 10.8620000 8.1460000 2.7150000 - 291 291 1 0.0000000 13.5770000 8.1460000 0.0000000 - 292 292 1 0.0000000 13.5770000 5.4310000 2.7150000 - 293 293 1 0.0000000 14.9350000 6.7890000 4.0730000 - 294 294 1 0.0000000 12.2200000 6.7890000 1.3580000 - 295 295 1 0.0000000 12.2200000 9.5040000 4.0730000 - 296 296 1 0.0000000 14.9350000 9.5040000 1.3580000 - 297 297 1 0.0000000 10.8620000 5.4310000 5.4310000 - 298 298 1 0.0000000 10.8620000 8.1460000 8.1460000 - 299 299 1 0.0000000 13.5770000 8.1460000 5.4310000 - 300 300 1 0.0000000 13.5770000 5.4310000 8.1460000 - 301 301 1 0.0000000 14.9350000 6.7890000 9.5040000 - 302 302 1 0.0000000 12.2200000 6.7890000 6.7890000 - 303 303 1 0.0000000 12.2200000 9.5040000 9.5040000 - 304 304 1 0.0000000 14.9350000 9.5040000 6.7890000 - 305 305 1 0.0000000 10.8620000 5.4310000 10.8620000 - 306 306 1 0.0000000 10.8620000 8.1460000 13.5770000 - 307 307 1 0.0000000 13.5770000 8.1460000 10.8620000 - 308 308 1 0.0000000 13.5770000 5.4310000 13.5770000 - 309 309 1 0.0000000 14.9350000 6.7890000 14.9350000 - 310 310 1 0.0000000 12.2200000 6.7890000 12.2200000 - 311 311 1 0.0000000 12.2200000 9.5040000 14.9350000 - 312 312 1 0.0000000 14.9350000 9.5040000 12.2200000 - 313 313 1 0.0000000 10.8620000 5.4310000 16.2930000 - 314 314 1 0.0000000 10.8620000 8.1460000 19.0080000 - 315 315 1 0.0000000 13.5770000 8.1460000 16.2930000 - 316 316 1 0.0000000 13.5770000 5.4310000 19.0080000 - 317 317 1 0.0000000 14.9350000 6.7890000 20.3660000 - 318 318 1 0.0000000 12.2200000 6.7890000 17.6510000 - 319 319 1 0.0000000 12.2200000 9.5040000 20.3660000 - 320 320 1 0.0000000 14.9350000 9.5040000 17.6510000 - 321 321 1 0.0000000 10.8620000 10.8620000 0.0000000 - 322 322 1 0.0000000 10.8620000 13.5770000 2.7150000 - 323 323 1 0.0000000 13.5770000 13.5770000 0.0000000 - 324 324 1 0.0000000 13.5770000 10.8620000 2.7150000 - 325 325 1 0.0000000 14.9350000 12.2200000 4.0730000 - 326 326 1 0.0000000 12.2200000 12.2200000 1.3580000 - 327 327 1 0.0000000 12.2200000 14.9350000 4.0730000 - 328 328 1 0.0000000 14.9350000 14.9350000 1.3580000 - 329 329 1 0.0000000 10.8620000 10.8620000 5.4310000 - 330 330 1 0.0000000 10.8620000 13.5770000 8.1460000 - 331 331 1 0.0000000 13.5770000 13.5770000 5.4310000 - 332 332 1 0.0000000 13.5770000 10.8620000 8.1460000 - 333 333 1 0.0000000 14.9350000 12.2200000 9.5040000 - 334 334 1 0.0000000 12.2200000 12.2200000 6.7890000 - 335 335 1 0.0000000 12.2200000 14.9350000 9.5040000 - 336 336 1 0.0000000 14.9350000 14.9350000 6.7890000 - 337 337 1 0.0000000 10.8620000 10.8620000 10.8620000 - 338 338 1 0.0000000 10.8620000 13.5770000 13.5770000 - 339 339 1 0.0000000 13.5770000 13.5770000 10.8620000 - 340 340 1 0.0000000 13.5770000 10.8620000 13.5770000 - 341 341 1 0.0000000 14.9350000 12.2200000 14.9350000 - 342 342 1 0.0000000 12.2200000 12.2200000 12.2200000 - 343 343 1 0.0000000 12.2200000 14.9350000 14.9350000 - 344 344 1 0.0000000 14.9350000 14.9350000 12.2200000 - 345 345 1 0.0000000 10.8620000 10.8620000 16.2930000 - 346 346 1 0.0000000 10.8620000 13.5770000 19.0080000 - 347 347 1 0.0000000 13.5770000 13.5770000 16.2930000 - 348 348 1 0.0000000 13.5770000 10.8620000 19.0080000 - 349 349 1 0.0000000 14.9350000 12.2200000 20.3660000 - 350 350 1 0.0000000 12.2200000 12.2200000 17.6510000 - 351 351 1 0.0000000 12.2200000 14.9350000 20.3660000 - 352 352 1 0.0000000 14.9350000 14.9350000 17.6510000 - 353 353 1 0.0000000 10.8620000 16.2930000 0.0000000 - 354 354 1 0.0000000 10.8620000 19.0080000 2.7150000 - 355 355 1 0.0000000 13.5770000 19.0080000 0.0000000 - 356 356 1 0.0000000 13.5770000 16.2930000 2.7150000 - 357 357 1 0.0000000 14.9350000 17.6510000 4.0730000 - 358 358 1 0.0000000 12.2200000 17.6510000 1.3580000 - 359 359 1 0.0000000 12.2200000 20.3660000 4.0730000 - 360 360 1 0.0000000 14.9350000 20.3660000 1.3580000 - 361 361 1 0.0000000 10.8620000 16.2930000 5.4310000 - 362 362 1 0.0000000 10.8620000 19.0080000 8.1460000 - 363 363 1 0.0000000 13.5770000 19.0080000 5.4310000 - 364 364 1 0.0000000 13.5770000 16.2930000 8.1460000 - 365 365 1 0.0000000 14.9350000 17.6510000 9.5040000 - 366 366 1 0.0000000 12.2200000 17.6510000 6.7890000 - 367 367 1 0.0000000 12.2200000 20.3660000 9.5040000 - 368 368 1 0.0000000 14.9350000 20.3660000 6.7890000 - 369 369 1 0.0000000 10.8620000 16.2930000 10.8620000 - 370 370 1 0.0000000 10.8620000 19.0080000 13.5770000 - 371 371 1 0.0000000 13.5770000 19.0080000 10.8620000 - 372 372 1 0.0000000 13.5770000 16.2930000 13.5770000 - 373 373 1 0.0000000 14.9350000 17.6510000 14.9350000 - 374 374 1 0.0000000 12.2200000 17.6510000 12.2200000 - 375 375 1 0.0000000 12.2200000 20.3660000 14.9350000 - 376 376 1 0.0000000 14.9350000 20.3660000 12.2200000 - 377 377 1 0.0000000 10.8620000 16.2930000 16.2930000 - 378 378 1 0.0000000 10.8620000 19.0080000 19.0080000 - 379 379 1 0.0000000 13.5770000 19.0080000 16.2930000 - 380 380 1 0.0000000 13.5770000 16.2930000 19.0080000 - 381 381 1 0.0000000 14.9350000 17.6510000 20.3660000 - 382 382 1 0.0000000 12.2200000 17.6510000 17.6510000 - 383 383 1 0.0000000 12.2200000 20.3660000 20.3660000 - 384 384 1 0.0000000 14.9350000 20.3660000 17.6510000 - 385 385 1 0.0000000 16.2930000 0.0000000 0.0000000 - 386 386 1 0.0000000 16.2930000 2.7150000 2.7150000 - 387 387 1 0.0000000 19.0080000 2.7150000 0.0000000 - 388 388 1 0.0000000 19.0080000 0.0000000 2.7150000 - 389 389 1 0.0000000 20.3660000 1.3580000 4.0730000 - 390 390 1 0.0000000 17.6510000 1.3580000 1.3580000 - 391 391 1 0.0000000 17.6510000 4.0730000 4.0730000 - 392 392 1 0.0000000 20.3660000 4.0730000 1.3580000 - 393 393 1 0.0000000 16.2930000 0.0000000 5.4310000 - 394 394 1 0.0000000 16.2930000 2.7150000 8.1460000 - 395 395 1 0.0000000 19.0080000 2.7150000 5.4310000 - 396 396 1 0.0000000 19.0080000 0.0000000 8.1460000 - 397 397 1 0.0000000 20.3660000 1.3580000 9.5040000 - 398 398 1 0.0000000 17.6510000 1.3580000 6.7890000 - 399 399 1 0.0000000 17.6510000 4.0730000 9.5040000 - 400 400 1 0.0000000 20.3660000 4.0730000 6.7890000 - 401 401 1 0.0000000 16.2930000 0.0000000 10.8620000 - 402 402 1 0.0000000 16.2930000 2.7150000 13.5770000 - 403 403 1 0.0000000 19.0080000 2.7150000 10.8620000 - 404 404 1 0.0000000 19.0080000 0.0000000 13.5770000 - 405 405 1 0.0000000 20.3660000 1.3580000 14.9350000 - 406 406 1 0.0000000 17.6510000 1.3580000 12.2200000 - 407 407 1 0.0000000 17.6510000 4.0730000 14.9350000 - 408 408 1 0.0000000 20.3660000 4.0730000 12.2200000 - 409 409 1 0.0000000 16.2930000 0.0000000 16.2930000 - 410 410 1 0.0000000 16.2930000 2.7150000 19.0080000 - 411 411 1 0.0000000 19.0080000 2.7150000 16.2930000 - 412 412 1 0.0000000 19.0080000 0.0000000 19.0080000 - 413 413 1 0.0000000 20.3660000 1.3580000 20.3660000 - 414 414 1 0.0000000 17.6510000 1.3580000 17.6510000 - 415 415 1 0.0000000 17.6510000 4.0730000 20.3660000 - 416 416 1 0.0000000 20.3660000 4.0730000 17.6510000 - 417 417 1 0.0000000 16.2930000 5.4310000 0.0000000 - 418 418 1 0.0000000 16.2930000 8.1460000 2.7150000 - 419 419 1 0.0000000 19.0080000 8.1460000 0.0000000 - 420 420 1 0.0000000 19.0080000 5.4310000 2.7150000 - 421 421 1 0.0000000 20.3660000 6.7890000 4.0730000 - 422 422 1 0.0000000 17.6510000 6.7890000 1.3580000 - 423 423 1 0.0000000 17.6510000 9.5040000 4.0730000 - 424 424 1 0.0000000 20.3660000 9.5040000 1.3580000 - 425 425 1 0.0000000 16.2930000 5.4310000 5.4310000 - 426 426 1 0.0000000 16.2930000 8.1460000 8.1460000 - 427 427 1 0.0000000 19.0080000 8.1460000 5.4310000 - 428 428 1 0.0000000 19.0080000 5.4310000 8.1460000 - 429 429 1 0.0000000 20.3660000 6.7890000 9.5040000 - 430 430 1 0.0000000 17.6510000 6.7890000 6.7890000 - 431 431 1 0.0000000 17.6510000 9.5040000 9.5040000 - 432 432 1 0.0000000 20.3660000 9.5040000 6.7890000 - 433 433 1 0.0000000 16.2930000 5.4310000 10.8620000 - 434 434 1 0.0000000 16.2930000 8.1460000 13.5770000 - 435 435 1 0.0000000 19.0080000 8.1460000 10.8620000 - 436 436 1 0.0000000 19.0080000 5.4310000 13.5770000 - 437 437 1 0.0000000 20.3660000 6.7890000 14.9350000 - 438 438 1 0.0000000 17.6510000 6.7890000 12.2200000 - 439 439 1 0.0000000 17.6510000 9.5040000 14.9350000 - 440 440 1 0.0000000 20.3660000 9.5040000 12.2200000 - 441 441 1 0.0000000 16.2930000 5.4310000 16.2930000 - 442 442 1 0.0000000 16.2930000 8.1460000 19.0080000 - 443 443 1 0.0000000 19.0080000 8.1460000 16.2930000 - 444 444 1 0.0000000 19.0080000 5.4310000 19.0080000 - 445 445 1 0.0000000 20.3660000 6.7890000 20.3660000 - 446 446 1 0.0000000 17.6510000 6.7890000 17.6510000 - 447 447 1 0.0000000 17.6510000 9.5040000 20.3660000 - 448 448 1 0.0000000 20.3660000 9.5040000 17.6510000 - 449 449 1 0.0000000 16.2930000 10.8620000 0.0000000 - 450 450 1 0.0000000 16.2930000 13.5770000 2.7150000 - 451 451 1 0.0000000 19.0080000 13.5770000 0.0000000 - 452 452 1 0.0000000 19.0080000 10.8620000 2.7150000 - 453 453 1 0.0000000 20.3660000 12.2200000 4.0730000 - 454 454 1 0.0000000 17.6510000 12.2200000 1.3580000 - 455 455 1 0.0000000 17.6510000 14.9350000 4.0730000 - 456 456 1 0.0000000 20.3660000 14.9350000 1.3580000 - 457 457 1 0.0000000 16.2930000 10.8620000 5.4310000 - 458 458 1 0.0000000 16.2930000 13.5770000 8.1460000 - 459 459 1 0.0000000 19.0080000 13.5770000 5.4310000 - 460 460 1 0.0000000 19.0080000 10.8620000 8.1460000 - 461 461 1 0.0000000 20.3660000 12.2200000 9.5040000 - 462 462 1 0.0000000 17.6510000 12.2200000 6.7890000 - 463 463 1 0.0000000 17.6510000 14.9350000 9.5040000 - 464 464 1 0.0000000 20.3660000 14.9350000 6.7890000 - 465 465 1 0.0000000 16.2930000 10.8620000 10.8620000 - 466 466 1 0.0000000 16.2930000 13.5770000 13.5770000 - 467 467 1 0.0000000 19.0080000 13.5770000 10.8620000 - 468 468 1 0.0000000 19.0080000 10.8620000 13.5770000 - 469 469 1 0.0000000 20.3660000 12.2200000 14.9350000 - 470 470 1 0.0000000 17.6510000 12.2200000 12.2200000 - 471 471 1 0.0000000 17.6510000 14.9350000 14.9350000 - 472 472 1 0.0000000 20.3660000 14.9350000 12.2200000 - 473 473 1 0.0000000 16.2930000 10.8620000 16.2930000 - 474 474 1 0.0000000 16.2930000 13.5770000 19.0080000 - 475 475 1 0.0000000 19.0080000 13.5770000 16.2930000 - 476 476 1 0.0000000 19.0080000 10.8620000 19.0080000 - 477 477 1 0.0000000 20.3660000 12.2200000 20.3660000 - 478 478 1 0.0000000 17.6510000 12.2200000 17.6510000 - 479 479 1 0.0000000 17.6510000 14.9350000 20.3660000 - 480 480 1 0.0000000 20.3660000 14.9350000 17.6510000 - 481 481 1 0.0000000 16.2930000 16.2930000 0.0000000 - 482 482 1 0.0000000 16.2930000 19.0080000 2.7150000 - 483 483 1 0.0000000 19.0080000 19.0080000 0.0000000 - 484 484 1 0.0000000 19.0080000 16.2930000 2.7150000 - 485 485 1 0.0000000 20.3660000 17.6510000 4.0730000 - 486 486 1 0.0000000 17.6510000 17.6510000 1.3580000 - 487 487 1 0.0000000 17.6510000 20.3660000 4.0730000 - 488 488 1 0.0000000 20.3660000 20.3660000 1.3580000 - 489 489 1 0.0000000 16.2930000 16.2930000 5.4310000 - 490 490 1 0.0000000 16.2930000 19.0080000 8.1460000 - 491 491 1 0.0000000 19.0080000 19.0080000 5.4310000 - 492 492 1 0.0000000 19.0080000 16.2930000 8.1460000 - 493 493 1 0.0000000 20.3660000 17.6510000 9.5040000 - 494 494 1 0.0000000 17.6510000 17.6510000 6.7890000 - 495 495 1 0.0000000 17.6510000 20.3660000 9.5040000 - 496 496 1 0.0000000 20.3660000 20.3660000 6.7890000 - 497 497 1 0.0000000 16.2930000 16.2930000 10.8620000 - 498 498 1 0.0000000 16.2930000 19.0080000 13.5770000 - 499 499 1 0.0000000 19.0080000 19.0080000 10.8620000 - 500 500 1 0.0000000 19.0080000 16.2930000 13.5770000 - 501 501 1 0.0000000 20.3660000 17.6510000 14.9350000 - 502 502 1 0.0000000 17.6510000 17.6510000 12.2200000 - 503 503 1 0.0000000 17.6510000 20.3660000 14.9350000 - 504 504 1 0.0000000 20.3660000 20.3660000 12.2200000 - 505 505 1 0.0000000 16.2930000 16.2930000 16.2930000 - 506 506 1 0.0000000 16.2930000 19.0080000 19.0080000 - 507 507 1 0.0000000 19.0080000 19.0080000 16.2930000 - 508 508 1 0.0000000 19.0080000 16.2930000 19.0080000 - 509 509 1 0.0000000 20.3660000 17.6510000 20.3660000 - 510 510 1 0.0000000 17.6510000 17.6510000 17.6510000 - 511 511 1 0.0000000 17.6510000 20.3660000 20.3660000 - 512 512 1 0.0000000 20.3660000 20.3660000 17.6510000 - diff --git a/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_8.lmp b/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_8.lmp deleted file mode 100755 index 5066049895..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/lmp_bank/silicon_8.lmp +++ /dev/null @@ -1,29 +0,0 @@ -LAMMPS description - - 8 atoms - 0 bonds - 0 angles - 0 dihedrals - 0 impropers - - 1 atom types - 0 bond types - 0 angle types - 0 dihedral types - 0 improper types - - - 0.0000000 5.4310000 xlo xhi - 0.0000000 5.4310000 ylo yhi - 0.0000000 5.4310000 zlo zhi - - Atoms - - 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 - 2 2 1 0.0000000 1.3577500 1.3577500 1.3572000 - 3 3 1 0.0000000 2.7155000 2.7155000 0.0000000 - 4 4 1 0.0000000 4.0732500 4.0732500 1.3572000 - 5 5 1 0.0000000 2.7155000 0.0000000 2.7144000 - 6 6 1 0.0000000 4.0732500 1.3577500 4.0732500 - 7 7 1 0.0000000 0.0000000 2.7155000 2.7155000 - 8 8 1 0.0000000 1.3577500 4.0732500 4.0732500 diff --git a/examples/USER/phonon/third_order_command/silicon/results/out.silicon b/examples/USER/phonon/third_order_command/silicon/results/out.silicon deleted file mode 100755 index 0729dc549c..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/results/out.silicon +++ /dev/null @@ -1,58 +0,0 @@ -LAMMPS (16 Jul 2018) -Reading data file ... - orthogonal box = (0 0 0) to (5.431 5.431 5.431) - 2 by 2 by 1 MPI processor grid - reading atoms ... - 8 atoms -Finding 1-2 1-3 1-4 neighbors ... - special bond factors lj: 0 0 0 - special bond factors coul: 0 0 0 - 0 = max # of 1-2 neighbors - 0 = max # of 1-3 neighbors - 0 = max # of 1-4 neighbors - 1 = max # of special neighbors -Neighbor list info ... - update every 1 steps, delay 10 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 4 - ghost atom cutoff = 4 - binsize = 2, bins = 3 3 3 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair tersoff, perpetual - attributes: full, newton on - pair build: full/bin - stencil: full/bin/3d - bin: standard -Calculating Anharmonic Dynamical Matrix... -Third Order calculation took 0.043923 seconds -Finished Calculating Third Order Tensor -Loop time of 1.22619e+06 on 4 procs for 0 steps with 8 atoms - -0.0% CPU use with 4 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.013707 | 0.016582 | 0.019588 | 2.2 | 0.00 -Bond | 8.1341e-05 | 8.7207e-05 | 9.3228e-05 | 0.0 | 0.00 -Neigh | 0 | 0 | 0 | 0.0 | 0.00 -Comm | 0.019285 | 0.022435 | 0.025684 | 2.0 | 0.00 -Output | 0 | 0 | 0 | 0.0 | 0.00 -Modify | 0 | 0 | 0 | 0.0 | 0.00 -Other | | 1.226e+06 | | |100.00 - -Nlocal: 2 ave 2 max 2 min -Histogram: 4 0 0 0 0 0 0 0 0 0 -Nghost: 56 ave 56 max 56 min -Histogram: 4 0 0 0 0 0 0 0 0 0 -Neighs: 0 ave 0 max 0 min -Histogram: 4 0 0 0 0 0 0 0 0 0 -FullNghs: 32 ave 32 max 32 min -Histogram: 4 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 128 -Ave neighs/atom = 16 -Ave special neighs/atom = 0 -Neighbor list builds = 0 -Dangerous builds = 0 -Total wall time: 0:00:00 diff --git a/examples/USER/phonon/third_order_command/silicon/results/third_order b/examples/USER/phonon/third_order_command/silicon/results/third_order deleted file mode 100755 index 276896aa1f..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/results/third_order +++ /dev/null @@ -1,4608 +0,0 @@ -1 1 1 1 1 -0.08569589 0.16067980 137.35980742 -1 1 1 1 2 -74170.35399415 -67130.60762609 -67084.85673024 -1 1 1 1 3 -0.10711987 -0.00000000 -5.61308111 -1 1 1 1 4 74170.34328216 67130.75759390 -67084.54608262 -1 1 1 1 5 -0.00000000 -0.00000000 -15.01820557 -1 1 1 1 6 74116.35486843 -67012.24017136 67025.88724261 -1 1 1 1 7 -0.00000000 -0.00000000 1.11404663 -1 1 1 1 8 -74116.23703657 67011.98308368 67025.60873095 -1 1 1 2 1 -0.23566371 -0.27851166 329269.69018077 -1 1 1 2 2 -72106.38979127 -72095.95631608 -80899.99905481 -1 1 1 2 3 -0.05355993 -0.00000000 -11783.78540967 -1 1 1 2 4 72106.62545498 72096.21340376 -80900.41682229 -1 1 1 2 5 -0.03213596 -0.00000000 2960.49323056 -1 1 1 2 6 -71998.20943604 72010.66747675 -80803.98751664 -1 1 1 2 7 0.02142397 -0.00000000 2961.59656521 -1 1 1 2 8 71998.19872405 -72010.69961271 -80803.91253273 -1 1 1 3 1 141.59104222 329281.45194233 0.41776749 -1 1 1 3 2 -72074.53234237 -80911.53586465 -72064.09886718 -1 1 1 3 3 3.98485911 2969.85550707 0.02142397 -1 1 1 3 4 -72074.54305436 -80911.38589683 72064.09886718 -1 1 1 3 5 -9.64078817 -11781.34307667 0.02142397 -1 1 1 3 6 72006.30769810 -80801.86654325 72002.14073522 -1 1 1 3 7 0.14996782 2957.19393861 0.04284795 -1 1 1 3 8 72006.66119367 -80802.35929464 -72002.55850270 -1 2 1 1 1 -0.40705550 -0.47132742 329270.04367633 -1 2 1 1 2 -72106.28267140 -72095.84919621 -80899.90264692 -1 2 1 1 3 -0.01071199 0.02142397 -11783.93537749 -1 2 1 1 4 72106.66830293 72096.21340376 -80900.26685448 -1 2 1 1 5 0.02142397 -0.04284795 2960.53607851 -1 2 1 1 6 -71998.40225180 72010.90314046 -80804.15890843 -1 2 1 1 7 0.02142397 -0.00000000 2961.59656521 -1 2 1 1 8 71998.34869187 -72010.95670040 -80804.09463651 -1 2 1 2 1 -0.04284795 0.67485517 115.02531483 -1 2 1 2 2 -67122.33797224 -74173.02127888 -67083.27135618 -1 2 1 2 3 -0.02142397 -0.00000000 -9.94072380 -1 2 1 2 4 67121.93091674 74172.77490318 -67083.11067638 -1 2 1 2 5 0.05355993 0.06427192 9.89787585 -1 2 1 2 6 67020.89545674 -74109.38136498 67027.62258448 -1 2 1 2 7 0.02142397 0.05355993 -3.84560328 -1 2 1 2 8 -67020.63836905 74109.15641326 67027.31193686 -1 2 1 3 1 329282.72666877 112.65796573 -0.08569589 -1 2 1 3 2 -80915.37075594 -72065.54498540 -72064.36666685 -1 2 1 3 3 2970.09117078 3.04220427 0.14996782 -1 2 1 3 4 -80913.63541407 -72065.98417686 72064.89155420 -1 2 1 3 5 2958.71504075 -9.59794022 -0.14996782 -1 2 1 3 6 -80800.75249661 72013.73110499 -72002.46209482 -1 2 1 3 7 -11780.59323759 -2.52802890 -0.67485517 -1 2 1 3 8 -80801.13812814 72014.00961665 72002.82630238 -1 3 1 1 1 140.26275585 329282.54456499 0.53559934 -1 3 1 1 2 -72074.61803826 -80911.60013657 -72064.25954698 -1 3 1 1 3 3.90987520 2969.74838720 -0.02142397 -1 3 1 1 4 -72074.26454270 -80911.32162491 72063.88462744 -1 3 1 1 5 -9.58722823 -11781.32165269 0.04284795 -1 3 1 1 6 72007.00397725 -80802.53068643 72002.74060648 -1 3 1 1 7 0.06427192 2957.16180265 -0.00000000 -1 3 1 1 8 72007.17536904 -80802.77706213 -72002.90128628 -1 3 1 2 1 329282.94090850 111.04045572 0.63200722 -1 3 1 2 2 -80915.52072376 -72065.59854533 -72064.48449870 -1 3 1 2 3 2969.99476290 2.93508440 -0.04284795 -1 3 1 2 4 -80913.01411883 -72065.17006586 72064.14171512 -1 3 1 2 5 2958.13659346 -10.43347519 0.42847947 -1 3 1 2 6 -80801.11670417 72014.05246460 -72002.80487840 -1 3 1 2 7 -11780.50754169 -2.72084466 -0.54631133 -1 3 1 2 8 -80800.85961648 72016.01275819 72002.63348661 -1 3 1 3 1 0.29993563 0.22495172 -12.59729654 -1 3 1 3 2 -67096.11502842 -67094.33683860 -74102.86847698 -1 3 1 3 3 -0.02142397 -0.04284795 1.13547061 -1 3 1 3 4 67095.81509279 67094.12259887 -74102.69708519 -1 3 1 3 5 -0.01071199 0.02142397 6.64143185 -1 3 1 3 6 67033.98550467 -67031.45747577 74105.22511409 -1 3 1 3 7 0.06427192 0.04284795 -0.27851166 -1 3 1 3 8 -67033.98550467 67031.28608399 74105.19297812 -1 1 2 1 1 -74175.17438824 -72109.17490785 -72075.08936569 -1 1 2 1 2 74174.06034160 72107.35387009 72071.88648162 -1 1 2 1 3 -0.43919146 538.62012295 1558.31557547 -1 1 2 1 4 -0.35349557 -538.98433050 -1559.15111044 -1 1 2 1 5 -0.36420755 1559.70813376 538.94148255 -1 1 2 1 6 -0.12854384 -1560.65078860 -539.26284216 -1 1 2 1 7 -9470.57469669 -3063.11406462 -3059.55768498 -1 1 2 1 8 9472.97418175 3066.31694869 3063.78891979 -1 1 2 2 1 -67136.04931541 -72094.55304580 -80912.33926366 -1 1 2 2 2 72108.78927633 67119.37075188 80912.66062327 -1 1 2 2 3 0.12854384 -537.80601195 3074.38307479 -1 1 2 2 4 538.66297089 -0.51417537 -3074.31880286 -1 1 2 2 5 -888.64500536 3068.44863407 94.71538776 -1 1 2 2 6 -1558.04777580 -0.68556716 -3077.83233455 -1 1 2 2 7 -1.34971034 1557.43719255 3075.86132897 -1 1 2 2 8 -3063.41400025 888.27008582 -93.10858973 -1 1 2 3 1 -67090.58764320 -80900.65248600 -72062.44922120 -1 1 2 3 2 72070.46178737 80911.33233690 67094.67962218 -1 1 2 3 3 -893.59394329 83.29640977 3055.78706561 -1 1 2 3 4 -1559.26894230 -3074.61873850 -0.59987126 -1 1 2 3 5 0.09640788 3080.91738677 -536.26348584 -1 1 2 3 6 535.97426219 -3081.11020253 0.40705550 -1 1 2 3 7 2.59230082 3075.91488891 1559.82596561 -1 1 2 3 8 -3065.72778941 -94.97247544 888.65571735 -1 2 2 1 1 -72106.94681459 -67126.03360770 -80913.12123870 -1 2 2 1 2 67141.76951639 72094.19955023 80912.06075200 -1 2 2 1 3 -539.33782607 0.81411100 3074.21168300 -1 2 2 1 4 -0.52488736 538.66297089 -3074.36165081 -1 2 2 1 5 1559.22609435 1.82103777 3080.51033127 -1 2 2 1 6 888.24866185 -3063.37115230 -93.06574178 -1 2 2 1 7 3058.20797464 -887.99157416 91.65175952 -1 2 2 1 8 -0.68556716 -1558.01563984 -3077.80019859 -1 2 2 2 1 -72096.51333939 -74176.32057083 -72068.06230231 -1 2 2 2 2 72097.11321066 74179.99478232 72069.75479623 -1 2 2 2 3 539.58420176 0.83553497 1559.92237350 -1 2 2 2 4 -539.03789043 -0.38563153 -1559.19395839 -1 2 2 2 5 -3068.12727446 -9477.28040046 -3066.73471617 -1 2 2 2 6 3066.27410074 9473.03845367 3063.79963178 -1 2 2 2 7 1561.40062768 0.28922365 539.62704971 -1 2 2 2 8 -1560.62936463 -0.13925583 -539.18785825 -1 2 2 3 1 -80898.98141606 -67086.42068032 -72061.12093483 -1 2 2 3 2 80909.30777138 72063.89533942 67096.43638803 -1 2 2 3 3 82.96433818 -893.33685560 3055.82991356 -1 2 2 3 4 -3074.65087446 -1559.32250223 -0.51417537 -1 2 2 3 5 3079.44984457 2.18524532 1557.22295281 -1 2 2 3 6 -94.92962749 -3065.77063736 888.60215741 -1 2 2 3 7 3077.91803045 2.61372479 -536.88478108 -1 2 2 3 8 -3081.11020253 535.98497418 0.33207159 -1 3 2 1 1 -72074.61803826 -80912.03932803 -67095.49373318 -1 3 2 1 2 67095.17237358 80902.98769914 72062.60990100 -1 3 2 1 3 1560.09376528 3074.55446658 0.55702332 -1 3 2 1 4 893.75462309 -83.27498580 -3055.65852177 -1 3 2 1 5 -535.98497418 3081.32444227 0.36420755 -1 3 2 1 6 -1.04977471 -3079.24631682 536.43487763 -1 3 2 1 7 3063.56396806 94.23334835 -889.21274066 -1 3 2 1 8 -1.07119869 -3078.63573357 -1559.47247005 -1 3 2 2 1 -80910.85029749 -72067.94447046 -67097.26121101 -1 3 2 2 2 80903.20193888 67084.63177851 72063.35974008 -1 3 2 2 3 3074.38307479 1558.70120699 0.29993563 -1 3 2 2 4 -83.26427381 893.74391110 -3055.63709779 -1 3 2 2 5 95.32597101 3067.67737102 -887.93801423 -1 3 2 2 6 -3078.63573357 -1.07119869 -1559.49389402 -1 3 2 2 7 3079.13919695 -534.68882377 0.25708768 -1 3 2 2 8 -3079.24631682 -1.03906272 536.42416564 -1 3 2 3 1 -72064.05601923 -72064.52734665 -74113.78399158 -1 3 2 3 2 72063.22048425 72066.00560083 74113.03415250 -1 3 2 3 3 -3055.10149845 -3055.55140190 -9478.75865465 -1 3 2 3 4 3055.31573819 3055.31573819 9478.65153478 -1 3 2 3 5 539.07002640 1555.42333902 -1.69249392 -1 3 2 3 6 -538.30947533 -1556.36599386 2.82796453 -1 3 2 3 7 1556.32314591 538.11665957 -3.12790016 -1 3 2 3 8 -1556.38741783 -538.30947533 2.82796453 -1 1 3 1 1 -0.04284795 -0.11783186 8.28036584 -1 1 3 1 2 -0.59987126 -0.00000000 -897.62165034 -1 1 3 1 3 0.01071199 0.02142397 8.03399014 -1 1 3 1 4 0.71770312 -0.08569589 -897.27886676 -1 1 3 1 5 0.05355993 0.04284795 2.27094121 -1 1 3 1 6 -0.68556716 -0.10711987 887.72377449 -1 1 3 1 7 -0.02142397 -0.00000000 1.26401445 -1 1 3 1 8 0.66414318 0.06427192 887.68092654 -1 1 3 2 1 -0.02142397 0.08569589 2968.58078064 -1 1 3 2 2 538.32018732 -538.32018732 85.43880714 -1 1 3 2 3 0.01071199 0.02142397 2968.54864468 -1 1 3 2 4 -538.30947533 538.32018732 85.52450304 -1 1 3 2 5 -0.06427192 -0.06427192 -3372.04776546 -1 1 3 2 6 538.38445924 538.25591539 89.29512241 -1 1 3 2 7 0.02142397 0.02142397 -2914.08890352 -1 1 3 2 8 -538.27733937 -538.30947533 89.25227446 -1 1 3 3 1 -6.23437635 -11785.64929538 -0.03213596 -1 1 3 3 2 1558.93687070 3074.91867413 3058.37936643 -1 1 3 3 3 5.55952118 2970.56249821 -0.04284795 -1 1 3 3 4 1559.02256660 3074.85440221 -3058.22939861 -1 1 3 3 5 0.74983908 -2915.35291796 -0.00000000 -1 1 3 3 6 -1559.30107826 3076.86825574 -3062.21425772 -1 1 3 3 7 0.62129524 -573.29482439 -0.01071199 -1 1 3 3 8 -1559.38677415 3076.90039170 3062.23568169 -1 2 3 1 1 -0.04284795 0.05355993 2968.54864468 -1 2 3 1 2 -539.11287434 538.98433050 85.03175164 -1 2 3 1 3 0.03213596 -0.02142397 2968.54864468 -1 2 3 1 4 539.09145037 -539.02717845 85.09602356 -1 2 3 1 5 0.01071199 0.02142397 -2914.00320762 -1 2 3 1 6 -537.57034824 -537.63462016 89.59505804 -1 2 3 1 7 0.02142397 -0.00000000 -3372.06918943 -1 2 3 1 8 537.61319618 537.57034824 89.45580221 -1 2 3 2 1 -0.02142397 -0.08569589 8.09826206 -1 2 3 2 2 0.04284795 0.68556716 -897.55737842 -1 2 3 2 3 0.04284795 -0.00000000 8.29107782 -1 2 3 2 4 -0.04284795 -0.66414318 -897.45025855 -1 2 3 2 5 -0.09640788 0.06427192 2.22809327 -1 2 3 2 6 -0.12854384 -0.66414318 887.76662244 -1 2 3 2 7 -0.00000000 -0.04284795 1.24259047 -1 2 3 2 8 0.12854384 0.57844729 887.45597482 -1 2 3 3 1 -11785.58502346 -11.39755401 0.05355993 -1 2 3 3 2 3074.81155426 1560.56509271 3058.33651848 -1 2 3 3 3 2970.42324238 5.74162495 -0.02142397 -1 2 3 3 4 3074.92938612 1560.54366873 -3058.18655066 -1 2 3 3 5 -573.21984048 -0.64271921 -0.04284795 -1 2 3 3 6 3076.93252766 -1557.95136791 3062.29995362 -1 2 3 3 7 -2915.35291796 0.93194286 0.03213596 -1 2 3 3 8 3076.99679958 -1557.88709599 -3062.38564951 -1 3 3 1 1 5.84874482 2970.57321019 -0.05355993 -1 3 3 1 2 1560.52224476 3074.89725015 -3058.31509451 -1 3 3 1 3 -11.38684202 -11785.64929538 0.02142397 -1 3 3 1 4 1560.46868482 3074.89725015 3058.22939861 -1 3 3 1 5 -0.64271921 -573.24126446 -0.04284795 -1 3 3 1 6 -1557.92994394 3076.95395163 3062.29995362 -1 3 3 1 7 0.87838292 -2915.31007002 0.01071199 -1 3 3 1 8 -1557.84424805 3077.00751156 -3062.35351355 -1 3 3 2 1 2970.51965026 5.62379310 0.02142397 -1 3 3 2 2 3075.02579400 1559.04399057 -3058.50791027 -1 3 3 2 3 -11785.63858339 -6.36292019 -0.02142397 -1 3 3 2 4 3074.98294605 1559.00114263 3058.40079040 -1 3 3 2 5 -2915.36362995 0.68556716 0.02142397 -1 3 3 2 6 3076.86825574 -1559.45104607 -3062.29995362 -1 3 3 2 7 -573.30553638 0.65343120 0.07498391 -1 3 3 2 8 3076.82540779 -1559.41891011 3062.05357792 -1 3 3 3 1 0.02142397 -0.02142397 3.99557110 -1 3 3 3 2 0.12854384 -0.14996782 -9480.12978896 -1 3 3 3 3 0.01071199 -0.04284795 4.11340295 -1 3 3 3 4 -0.11783186 0.21423974 -9480.02266909 -1 3 3 3 5 -0.03213596 -0.04284795 2.63514877 -1 3 3 3 6 0.17139179 0.17139179 9473.93826056 -1 3 3 3 7 -0.04284795 -0.01071199 1.81032578 -1 3 3 3 8 -0.12854384 -0.18210378 9473.88470063 -1 1 4 1 1 74175.53859579 72109.64623527 -72075.37858933 -1 1 4 1 2 0.38563153 539.01646646 -1559.19395839 -1 1 4 1 3 0.43919146 -538.55585103 1558.25130355 -1 1 4 1 4 -74174.42454916 -72107.78234956 72072.32567308 -1 1 4 1 5 0.35349557 -1559.70813376 538.96290653 -1 1 4 1 6 -9473.02774168 -3066.32766067 3063.77820780 -1 1 4 1 7 9470.57469669 3063.09264064 -3059.56839697 -1 1 4 1 8 0.12854384 1560.64007661 -539.19857024 -1 1 4 2 1 67136.69203462 72095.08864514 -80912.77845512 -1 1 4 2 2 -538.66297089 0.54631133 -3074.35093883 -1 1 4 2 3 -0.11783186 537.82743592 3074.51161863 -1 1 4 2 4 -72109.31416368 -67119.98133513 80913.20693460 -1 1 4 2 5 888.67714132 -3068.49148202 94.73681173 -1 1 4 2 6 3063.40328826 -888.25937383 -93.10858973 -1 1 4 2 7 1.32828637 -1557.45861652 3075.82919301 -1 1 4 2 8 1558.01563984 0.65343120 -3077.82162257 -1 1 4 3 1 -67090.65191512 -80900.84530177 72062.58847703 -1 1 4 3 2 -1559.32250223 -3074.66158644 0.51417537 -1 1 4 3 3 -893.62607925 83.29640977 -3055.78706561 -1 1 4 3 4 72070.57961922 80911.49301670 -67094.76531808 -1 1 4 3 5 0.07498391 3080.85311485 536.26348584 -1 1 4 3 6 -3065.74921338 -94.95105147 -888.66642933 -1 1 4 3 7 2.59230082 3075.91488891 -1559.81525363 -1 1 4 3 8 535.96355021 -3081.13162650 -0.33207159 -1 2 4 1 1 72107.56810982 67126.64419095 -80913.82822983 -1 2 4 1 2 0.53559934 -538.63083493 -3074.35093883 -1 2 4 1 3 539.32711408 -0.79268703 3074.16883505 -1 2 4 1 4 -67142.43365957 -72094.82084547 80912.58563936 -1 2 4 1 5 -1559.23680634 -1.79961379 3080.44605934 -1 2 4 1 6 0.68556716 1558.03706381 -3077.81091058 -1 2 4 1 7 -3058.22939861 888.00228615 91.66247150 -1 2 4 1 8 -888.25937383 3063.38186429 -93.10858973 -1 2 4 2 1 72096.32052363 74176.06348314 -72067.88019853 -1 2 4 2 2 539.00575447 0.38563153 -1559.21538236 -1 2 4 2 3 -539.56277779 -0.83553497 1560.00806939 -1 2 4 2 4 -72096.73829112 -74179.71627066 72069.56198047 -1 2 4 2 5 3068.15941042 9477.28040046 -3066.62759630 -1 2 4 2 6 1560.67221257 0.08569589 -539.17714626 -1 2 4 2 7 -1561.46489960 -0.25708768 539.63776170 -1 2 4 2 8 -3066.32766067 -9473.00631771 3063.81034376 -1 2 4 3 1 -80898.55293658 -67086.00291283 72060.77815125 -1 2 4 3 2 -3074.66158644 -1559.30107826 0.52488736 -1 2 4 3 3 82.97505016 -893.35827957 -3055.91560945 -1 2 4 3 4 80908.90071588 72063.49899591 -67096.11502842 -1 2 4 3 5 3079.44984457 2.18524532 -1557.20152883 -1 2 4 3 6 -3081.11020253 535.98497418 -0.29993563 -1 2 4 3 7 3077.91803045 2.60301281 536.90620505 -1 2 4 3 8 -94.95105147 -3065.73850140 -888.68785331 -1 3 4 1 1 -72074.72515813 -80912.17858386 67095.54729312 -1 3 4 1 2 893.78675905 -83.20000189 3055.80848958 -1 3 4 1 3 1560.10447727 3074.55446658 -0.51417537 -1 3 4 1 4 67095.30091742 80903.13766695 -72062.59918902 -1 3 4 1 5 -535.98497418 3081.32444227 -0.29993563 -1 3 4 1 6 -1.08191067 -3078.64644555 1559.45104607 -1 3 4 1 7 3063.58539204 94.23334835 889.22345265 -1 3 4 1 8 -1.09262266 -3079.24631682 -536.45630160 -1 3 4 2 1 -80910.78602557 -72067.71951873 67097.07910724 -1 3 4 2 2 -83.18928990 893.78675905 3055.80848958 -1 3 4 2 3 3074.40449876 1558.70120699 -0.34278358 -1 3 4 2 4 80903.01983510 67084.28899493 -72063.26333220 -1 3 4 2 5 95.28312306 3067.72021896 887.87374231 -1 3 4 2 6 -3079.25702880 -1.09262266 -536.43487763 -1 3 4 2 7 3079.16062092 -534.65668781 -0.28922365 -1 3 4 2 8 -3078.60359761 -1.07119869 1559.44033409 -1 3 4 3 1 72063.67038770 72064.06673121 -74113.23768025 -1 3 4 3 2 -3055.27289024 -3055.28360223 9478.69438273 -1 3 4 3 3 3055.10149845 3055.52997792 -9478.73723067 -1 3 4 3 4 -72062.68488491 -72065.59854533 74112.61638501 -1 3 4 3 5 -539.04860242 -1555.38049107 -1.75676584 -1 3 4 3 6 1556.38741783 538.34161129 2.87081248 -1 3 4 3 7 -1556.32314591 -538.12737155 -3.14932413 -1 3 4 3 8 538.36303526 1556.38741783 2.82796453 -1 1 5 1 1 -0.04284795 0.12854384 -9.14803677 -1 1 5 1 2 -0.85695895 -890.25180339 -0.25708768 -1 1 5 1 3 -0.04284795 -0.04284795 0.94265484 -1 1 5 1 4 0.83553497 890.23037941 -0.08569589 -1 1 5 1 5 -0.01071199 -0.02142397 13.26143972 -1 1 5 1 6 -0.55702332 -889.58766020 -2.52802890 -1 1 5 1 7 0.02142397 0.02142397 0.41776749 -1 1 5 1 8 0.53559934 889.57694822 -2.50660492 -1 1 5 2 1 -0.04284795 -0.02142397 -11786.34557453 -1 1 5 2 2 1560.77933244 3069.28416904 3081.34586624 -1 1 5 2 3 0.01071199 -0.06427192 -2915.33149399 -1 1 5 2 4 -1560.81146840 -3069.32701699 3081.62437790 -1 1 5 2 5 -0.05355993 0.02142397 2966.14915962 -1 1 5 2 6 1558.05848778 -3056.34408893 3073.69750763 -1 1 5 2 7 0.10711987 -0.04284795 -574.38744705 -1 1 5 2 8 -1558.07991176 3056.32266495 3073.71893160 -1 1 5 3 1 -12.89723217 2960.13973500 -0.01071199 -1 1 5 3 2 538.34161129 94.00839662 -536.54199750 -1 1 5 3 3 1.45683021 -3372.02634149 0.12854384 -1 1 5 3 4 538.25591539 93.98697265 536.71338929 -1 1 5 3 5 14.45047026 2963.40689099 -0.02142397 -1 1 5 3 6 -539.51992984 87.23842093 536.11351802 -1 1 5 3 7 -0.47132742 -2914.42097511 0.07498391 -1 1 5 3 8 -539.51992984 87.42052471 -536.00639816 -1 2 5 1 1 -0.00000000 0.07498391 2959.63627162 -1 2 5 1 2 1560.45797284 -3069.54125673 3080.44605934 -1 2 5 1 3 0.06427192 -0.00000000 -573.09129664 -1 2 5 1 4 -1560.52224476 3069.45556083 3080.29609153 -1 2 5 1 5 0.01071199 -0.02142397 -11776.30844285 -1 2 5 1 6 1553.10954986 3059.40771717 3071.89789384 -1 2 5 1 7 -0.02142397 -0.00000000 -2914.77447067 -1 2 5 1 8 -1553.08812588 -3059.43985313 3071.76934999 -1 2 5 2 1 -0.00000000 -0.04284795 -8.79454121 -1 2 5 2 2 0.89980690 -9474.64525169 0.83553497 -1 2 5 2 3 0.02142397 -0.04284795 -0.25708768 -1 2 5 2 4 -0.86767094 9474.60240375 0.98550279 -1 2 5 2 5 0.08569589 0.02142397 13.41140754 -1 2 5 2 6 -0.06427192 -9456.17778636 -3.12790016 -1 2 5 2 7 0.04284795 0.03213596 -0.11783186 -1 2 5 2 8 -0.06427192 9456.22063431 -2.93508440 -1 2 5 3 1 2960.70747030 14.27907848 0.02142397 -1 2 5 3 2 3081.15305048 -3068.66287381 1558.33699944 -1 2 5 3 3 -2913.87466378 2.05670148 0.02142397 -1 2 5 3 4 3081.18518644 -3068.62002586 -1558.12275970 -1 2 5 3 5 -11774.21960541 16.62500360 0.02142397 -1 2 5 3 6 3069.88404031 3053.00194903 1560.52224476 -1 2 5 3 7 -574.69809467 -1.49967816 0.01071199 -1 2 5 3 8 3069.88404031 3053.05550896 -1560.61865264 -1 3 5 1 1 -12.49017667 2960.33255076 -0.07498391 -1 3 5 1 2 -536.09209405 94.73681173 538.32018732 -1 3 5 1 3 -0.23566371 -2914.62450286 -0.02142397 -1 3 5 1 4 -536.08138206 94.86535557 -538.42730718 -1 3 5 1 5 16.60357962 2963.59970675 -0.10711987 -1 3 5 1 6 534.72095973 87.49550862 -537.61319618 -1 3 5 1 7 -1.15689458 -3373.67598746 -0.03213596 -1 3 5 1 8 534.69953576 87.46337266 537.66675612 -1 3 5 2 1 -11787.12754957 -8.03399014 0.01071199 -1 3 5 2 2 3081.77434571 3069.28416904 1556.34456989 -1 3 5 2 3 -572.91990485 0.87838292 -0.02142397 -1 3 5 2 4 3081.74220975 3069.32701699 -1556.32314591 -1 3 5 2 5 2963.80323450 -7.96971822 0.10711987 -1 3 5 2 6 3074.42592273 -3061.35729877 1557.22295281 -1 3 5 2 7 -2916.01706115 -0.79268703 0.03213596 -1 3 5 2 8 3074.34022684 -3061.43228268 -1557.42648056 -1 3 5 3 1 -0.02142397 0.06427192 8.23751789 -1 3 5 3 2 -0.12854384 -886.35264017 -2.12097340 -1 3 5 3 3 -0.03213596 -0.06427192 2.54945287 -1 3 5 3 4 0.13925583 886.43833607 -2.22809327 -1 3 5 3 5 0.03213596 0.02142397 -10.17638751 -1 3 5 3 6 0.14996782 -891.38727399 3.04220427 -1 3 5 3 7 -0.00000000 -0.01071199 -2.17453333 -1 3 5 3 8 -0.14996782 891.26944214 2.83867652 -1 1 6 1 1 74116.23703657 -72002.14073522 72008.75003111 -1 1 6 1 2 0.40705550 -1558.13347169 535.67432656 -1 1 6 1 3 -1.28543842 538.64154692 -1558.85117481 -1 1 6 1 4 -9473.03845367 3064.52804688 -3066.00630107 -1 1 6 1 5 -1.07119869 1557.56573639 -539.66989766 -1 1 6 1 6 -74108.24589438 71998.04875624 -71998.13445213 -1 1 6 1 7 9466.48271771 -3061.73221831 3061.35729877 -1 1 6 1 8 0.44990345 -536.77766121 1556.92301718 -1 1 6 2 1 -67015.21810371 72015.84136640 -80796.89618135 -1 1 6 2 2 -1561.93622702 -1.75676584 -3081.76363373 -1 1 6 2 3 -0.53559934 538.51300308 3077.36100713 -1 1 6 2 4 -3066.00630107 -889.33057252 -95.12244326 -1 1 6 2 5 -891.70863360 -3053.55897234 86.12437430 -1 1 6 2 6 71998.32726790 -67051.53173914 80811.14312386 -1 1 6 2 7 0.42847947 -1557.60858433 3076.37550434 -1 1 6 2 8 536.67054134 -0.59987126 -3076.98608759 -1 1 6 3 1 67029.42219827 -80800.94531238 72003.74753324 -1 1 6 3 2 -540.03410521 -3079.38557265 -0.87838292 -1 1 6 3 3 888.95565298 90.49486493 -3062.77128104 -1 1 6 3 4 3063.40328826 -93.02289383 -888.83782112 -1 1 6 3 5 -1.48896617 3074.85440221 536.71338929 -1 1 6 3 6 -71997.32034113 80808.37943125 -67028.09391190 -1 1 6 3 7 -0.62129524 3076.85754375 -1559.46175806 -1 1 6 3 8 1557.69428023 -3077.28602322 -0.32135961 -1 2 6 1 1 -72004.24028464 67024.60180419 -80796.21061419 -1 2 6 1 2 889.39484444 3065.98487709 -95.07959531 -1 2 6 1 3 -537.82743592 0.36420755 3077.46812700 -1 2 6 1 4 1.75676584 1561.87195510 -3081.75292174 -1 2 6 1 5 1553.38806151 0.21423974 3070.18397594 -1 2 6 1 6 67035.54945475 -72006.46837791 80811.48590744 -1 2 6 1 7 3061.37872275 889.96257974 90.79480057 -1 2 6 1 8 0.59987126 -536.63840538 -3077.00751156 -1 2 6 2 1 72013.43116936 -74113.97680734 72014.96298348 -1 2 6 2 2 -3064.50662291 9473.03845367 -3065.95274113 -1 2 6 2 3 -537.93455579 -0.02142397 -1557.37292062 -1 2 6 2 4 1558.11204772 -0.40705550 535.68503855 -1 2 6 2 5 3057.04036807 -9458.66296731 3055.05865050 -1 2 6 2 6 -72005.10795558 74101.32595087 -72001.66940780 -1 2 6 2 7 -1557.77997612 -0.73912709 -537.59177221 -1 2 6 2 8 536.77766121 -0.43919146 1556.92301718 -1 2 6 3 1 -80801.90939119 67032.57152241 -72004.34740451 -1 2 6 3 2 -93.04431781 3063.43542422 888.84853311 -1 2 6 3 3 90.76266461 889.07348483 3062.79270501 -1 2 6 3 4 -3079.39628463 -540.05552919 0.87838292 -1 2 6 3 5 3072.65844490 -1.92815763 1561.37920371 -1 2 6 3 6 80810.32901286 -72001.45516806 67026.44426593 -1 2 6 3 7 3077.85375853 0.82482299 -536.22063789 -1 2 6 3 8 -3077.29673521 1557.70499222 0.35349557 -1 3 6 1 1 72007.60384851 -80795.10727954 67033.68556904 -1 3 6 1 2 -1.41398226 -3078.11084621 -538.18093149 -1 3 6 1 3 -1558.01563984 3077.59667084 0.34278358 -1 3 6 1 4 -2.82796453 -3080.16754769 1557.11583294 -1 3 6 1 5 536.20992591 3076.73971189 1.84246174 -1 3 6 1 6 -67028.08319992 80799.85268972 -72006.44695393 -1 3 6 1 7 -3061.97859401 91.86599925 890.54102703 -1 3 6 1 8 -891.51581784 -92.62655032 3061.14305904 -1 3 6 2 1 -80797.28181287 72014.55592798 -67032.51796247 -1 3 6 2 2 -3080.16754769 -2.82796453 -1557.07298499 -1 3 6 2 3 3077.28602322 -1559.83667760 -0.21423974 -1 3 6 2 4 -3078.13227018 -1.45683021 538.25591539 -1 3 6 2 5 89.83072175 -3058.57218219 -892.13711307 -1 3 6 2 6 80803.91253273 -67036.53495754 72005.35433127 -1 3 6 2 7 3077.12534342 536.01711014 -0.62129524 -1 3 6 2 8 -92.61583833 -891.49439386 -3061.14305904 -1 3 6 3 1 72000.76960090 -72000.16972964 74100.53326384 -1 3 6 3 2 536.32775776 -1559.33321422 2.37806108 -1 3 6 3 3 3063.01765673 -3062.57846527 9469.52492198 -1 3 6 3 4 1559.33321422 -536.32775776 2.35663711 -1 3 6 3 5 -536.91691704 1558.61551110 3.59922758 -1 3 6 3 6 -72003.52258152 72000.74817693 -74115.18726186 -1 3 6 3 7 -1557.73712818 537.81672393 2.24951724 -1 3 6 3 8 -3061.31445083 3061.36801076 -9465.42223101 -1 1 7 1 1 -0.10711987 -0.01071199 -5.12032972 -1 1 7 1 2 -9468.71081098 0.10711987 2.99935632 -1 1 7 1 3 -0.00000000 -0.00000000 0.53559934 -1 1 7 1 4 9468.73223495 -0.00000000 2.99935632 -1 1 7 1 5 0.05355993 -0.02142397 -0.19281576 -1 1 7 1 6 9470.91748027 0.92123087 -0.85695895 -1 1 7 1 7 -0.02142397 0.03213596 0.44990345 -1 1 7 1 8 -9470.85320835 -0.80339901 -0.84624696 -1 1 7 2 1 -0.00000000 -0.04284795 2957.22607457 -1 1 7 2 2 -3063.56396806 1556.47311373 3075.77563308 -1 1 7 2 3 0.01071199 -0.06427192 -573.32696035 -1 1 7 2 4 3063.56396806 -1556.53738565 3075.68993718 -1 1 7 2 5 -0.00000000 -0.06427192 -2914.26029531 -1 1 7 2 6 -3061.01451519 -1557.18010486 3076.39692831 -1 1 7 2 7 -0.00000000 0.07498391 -11773.68400607 -1 1 7 2 8 3061.03593917 1557.23366480 3076.37550434 -1 1 7 3 1 -1.04977471 2959.47559181 0.04284795 -1 1 7 3 2 -3058.85069385 3075.02579400 1559.60101389 -1 1 7 3 3 0.29993563 -2913.63900007 0.02142397 -1 1 7 3 4 -3058.91496577 3075.04721797 -1559.49389402 -1 1 7 3 5 0.48203941 -574.78379056 -0.00000000 -1 1 7 3 6 3060.60745969 3075.98987281 -1559.06541455 -1 1 7 3 7 -3.06362824 -11773.01986288 0.02142397 -1 1 7 3 8 3060.58603572 3075.97916083 1559.27965428 -1 2 7 1 1 -0.10711987 -0.03213596 -11783.72113775 -1 2 7 1 2 3060.50033982 1561.37920371 3077.55382289 -1 2 7 1 3 0.04284795 0.04284795 -2915.07440631 -1 2 7 1 4 -3060.44677989 -1561.40062768 3077.46812700 -1 2 7 1 5 0.03213596 -0.00000000 -574.65524672 -1 2 7 1 6 3060.82169943 -1557.45861652 3077.57524687 -1 2 7 1 7 0.04284795 -0.09640788 2963.47116291 -1 2 7 1 8 -3060.84312340 1557.54431241 3077.50026296 -1 2 7 2 1 -0.00000000 0.01071199 -2.18524532 -1 2 7 2 2 -888.96636496 0.55702332 2.37806108 -1 2 7 2 3 0.03213596 0.08569589 0.83553497 -1 2 7 2 4 888.97707695 -0.55702332 2.52802890 -1 2 7 2 5 -0.00000000 0.04284795 -1.97100558 -1 2 7 2 6 888.60215741 -0.89980690 0.21423974 -1 2 7 2 7 -0.08569589 -0.00000000 -1.89602167 -1 2 7 2 8 -888.62358139 0.88909491 0.26779967 -1 2 7 3 1 2962.01433270 -2.46375698 -0.12854384 -1 2 7 3 2 89.68075393 539.79844150 -536.49914955 -1 2 7 3 3 -3371.56572605 0.44990345 -0.00000000 -1 2 7 3 4 89.60577003 539.69132163 536.62769339 -1 2 7 3 5 -2914.09961550 0.04284795 -0.00000000 -1 2 7 3 6 89.63790599 -537.97740374 -536.15636597 -1 2 7 3 7 2965.29220067 -1.54252611 0.04284795 -1 2 7 3 8 89.55221009 -538.00953970 536.02782213 -1 3 7 1 1 -1.77818982 -11783.09984251 -0.00000000 -1 3 7 1 2 3062.98552077 3079.58910040 1556.38741783 -1 3 7 1 3 0.77126305 -573.54120009 0.08569589 -1 3 7 1 4 3062.95338481 3079.65337232 -1556.38741783 -1 3 7 1 5 -0.80339901 -2915.58858168 0.14996782 -1 3 7 1 6 -3061.20733096 3076.65401600 -1557.30864870 -1 3 7 1 7 -1.71391790 2959.94691923 0.02142397 -1 3 7 1 8 -3061.16448301 3076.60045606 1557.14796890 -1 3 7 2 1 2960.34326275 -1.67106995 -0.01071199 -1 3 7 2 2 91.99454309 -534.93519947 538.25591539 -1 3 7 2 3 -2914.64592683 0.72841511 -0.00000000 -1 3 7 2 4 91.96240713 -534.91377550 -538.06309963 -1 3 7 2 5 -3373.75097137 -1.11404663 0.08569589 -1 3 7 2 6 90.36632109 535.96355021 537.76316400 -1 3 7 2 7 2963.53543483 -0.08569589 0.02142397 -1 3 7 2 8 90.36632109 535.98497418 -537.92384380 -1 3 7 3 1 -0.02142397 -0.00000000 4.86324203 -1 3 7 3 2 -890.89452260 -0.10711987 -2.91366042 -1 3 7 3 3 -0.03213596 -0.04284795 2.18524532 -1 3 7 3 4 890.90523459 0.17139179 -2.82796453 -1 3 7 3 5 0.02142397 0.04284795 -2.48518095 -1 3 7 3 6 889.00921291 -0.14996782 1.97100558 -1 3 7 3 7 0.02142397 -0.04284795 -2.76369261 -1 3 7 3 8 -888.96636496 0.13925583 1.91744565 -1 1 8 1 1 -74116.62266810 72002.53707873 72009.10352667 -1 1 8 1 2 9473.05987764 -3064.52804688 -3065.97416511 -1 1 8 1 3 1.28543842 -538.62012295 -1558.87259878 -1 1 8 1 4 -0.41776749 1558.14418368 535.68503855 -1 1 8 1 5 1.00692676 -1557.63000831 -539.62704971 -1 1 8 1 6 -0.41776749 536.77766121 1556.98728910 -1 1 8 1 7 -9466.52556566 3061.68937036 3061.34658679 -1 1 8 1 8 74108.63152590 -71998.39153982 -71998.71289942 -1 1 8 2 1 67015.38949550 -72015.88421435 -80797.08899711 -1 1 8 2 2 3066.00630107 889.36270848 -95.13315524 -1 1 8 2 3 0.56773530 -538.55585103 3077.31815918 -1 1 8 2 4 1561.91480305 1.67106995 -3081.79576969 -1 1 8 2 5 891.70863360 3053.51612440 86.14579827 -1 1 8 2 6 -536.63840538 0.57844729 -3076.95395163 -1 1 8 2 7 -0.44990345 1557.65143228 3076.38621633 -1 1 8 2 8 -71998.52008366 67051.57458708 80811.05742797 -1 1 8 3 1 67029.10083867 -80800.48469694 -72003.19050993 -1 1 8 3 2 3063.39257627 -93.01218185 888.82710914 -1 1 8 3 3 888.99850093 90.55913686 3062.74985706 -1 1 8 3 4 -540.04481720 -3079.41770861 0.81411100 -1 1 8 3 5 -1.53181412 3074.76870631 -536.79908518 -1 1 8 3 6 1557.69428023 -3077.27531124 0.32135961 -1 1 8 3 7 -0.64271921 3076.84683176 1559.45104607 -1 1 8 3 8 -71997.02040550 80807.99379973 67027.80468826 -1 2 8 1 1 72004.28313259 -67024.49468432 -80796.04993438 -1 2 8 1 2 -1.73534187 -1561.94693901 -3081.76363373 -1 2 8 1 3 537.80601195 -0.38563153 3077.48955097 -1 2 8 1 4 -889.36270848 -3066.02772504 -95.10101928 -1 2 8 1 5 -1553.37734953 -0.27851166 3070.09828004 -1 2 8 1 6 -0.62129524 536.64911737 -3076.95395163 -1 2 8 1 7 -3061.31445083 -889.93044378 90.81622454 -1 2 8 1 8 -67035.54945475 72006.25413817 80811.43234751 -1 2 8 2 1 -72014.20243241 74114.51240669 72015.47715885 -1 2 8 2 2 -1558.14418368 0.41776749 535.66361458 -1 2 8 2 3 537.76316400 -0.06427192 -1557.28722473 -1 2 8 2 4 3064.53875887 -9473.01702969 -3065.98487709 -1 2 8 2 5 -3057.19033589 9458.79151115 3054.95153063 -1 2 8 2 6 -536.78837320 0.42847947 1557.00871307 -1 2 8 2 7 1556.85874526 0.08569589 -538.25591539 -1 2 8 2 8 72007.26106493 -74101.13313511 -72001.42303210 -1 2 8 3 1 -80801.50233569 67032.10019499 72003.81180517 -1 2 8 3 2 -3079.43913258 -540.07695316 -0.84624696 -1 2 8 3 3 90.75195262 889.07348483 -3062.79270501 -1 2 8 3 4 -93.02289383 3063.43542422 -888.81639715 -1 2 8 3 5 3072.60488497 -1.92815763 -1561.42205165 -1 2 8 3 6 -3077.27531124 1557.69428023 -0.29993563 -1 2 8 3 7 3077.81091058 0.83553497 536.22063789 -1 2 8 3 8 80809.98622928 -72001.19808037 -67025.84439466 -1 3 8 1 1 72007.94663209 -80795.42863915 -67033.99621666 -1 3 8 1 2 -2.82796453 -3080.16754769 -1557.09440897 -1 3 8 1 3 -1558.07991176 3077.55382289 -0.34278358 -1 3 8 1 4 -1.44611823 -3078.15369416 538.32018732 -1 3 8 1 5 536.27419783 3076.69686395 -1.90673366 -1 3 8 1 6 -891.52652982 -92.55156641 -3061.16448301 -1 3 8 1 7 -3061.93574606 91.88742323 -890.49817908 -1 3 8 1 8 -67028.43669548 80800.18476131 72006.76831354 -1 3 8 2 1 -80797.49605261 72014.83443964 67032.65721830 -1 3 8 2 2 -3078.11084621 -1.41398226 -538.19164347 -1 3 8 2 3 3077.30744720 -1559.79382965 0.17139179 -1 3 8 2 4 -3080.12469974 -2.82796453 1557.11583294 -1 3 8 2 5 89.78787380 -3058.57218219 892.22280897 -1 3 8 2 6 -92.57299038 -891.53724181 3061.20733096 -1 3 8 2 7 3077.12534342 536.01711014 0.65343120 -1 3 8 2 8 80804.13748446 -67036.68492536 -72005.84708267 -1 3 8 3 1 -72001.69083177 72000.93028070 74101.21883100 -1 3 8 3 2 -1559.32250223 536.32775776 2.39948506 -1 3 8 3 3 -3063.21047250 3062.49276938 9469.61061787 -1 3 8 3 4 -536.31704577 1559.34392621 2.33521313 -1 3 8 3 5 536.70267730 -1558.55123918 3.51353169 -1 3 8 3 6 3061.33587480 -3061.31445083 -9465.39009505 -1 3 8 3 7 1556.79447333 -538.44873116 1.58537405 -1 3 8 3 8 72005.69711485 -72000.76960090 -74115.17654987 -2 1 1 1 1 -74175.43147592 -72109.42128355 -72075.29289344 -2 1 1 1 2 74174.16746147 72107.66451771 72072.25068917 -2 1 1 1 3 -0.44990345 538.62012295 1558.31557547 -2 1 1 1 4 -0.38563153 -538.98433050 -1559.19395839 -2 1 1 1 5 -0.36420755 1559.72955773 539.00575447 -2 1 1 1 6 -0.13925583 -1560.62936463 -539.24141818 -2 1 1 1 7 -9470.57469669 -3063.15691256 -3059.60053293 -2 1 1 1 8 9472.99560572 3066.29552471 3063.75678383 -2 1 1 2 1 -72107.50383790 -67126.57991903 -80913.63541407 -2 1 1 2 2 67142.32653970 72094.79942150 80912.69275923 -2 1 1 2 3 -539.35925004 0.79268703 3074.21168300 -2 1 1 2 4 -0.52488736 538.66297089 -3074.38307479 -2 1 1 2 5 1559.23680634 1.79961379 3080.44605934 -2 1 1 2 6 888.25937383 -3063.39257627 -93.13001370 -2 1 1 2 7 3058.18655066 -887.94872621 91.65175952 -2 1 1 2 8 -0.68556716 -1557.99421586 -3077.84304654 -2 1 1 3 1 -72074.51091840 -80912.05004002 -67095.51515716 -2 1 1 3 2 67095.21522152 80902.98769914 72062.55634107 -2 1 1 3 3 1560.06162932 3074.55446658 0.53559934 -2 1 1 3 4 893.72248713 -83.25356182 -3055.63709779 -2 1 1 3 5 -536.00639816 3081.32444227 0.25708768 -2 1 1 3 6 -1.09262266 -3079.24631682 536.52057352 -2 1 1 3 7 3063.60681601 94.22263636 -889.20202868 -2 1 1 3 8 -1.11404663 -3078.61430959 -1559.44033409 -2 2 1 1 1 -67136.54206680 -72095.02437322 -80912.89628698 -2 2 1 1 2 72109.26060375 67119.83136731 80913.26049453 -2 2 1 1 3 0.13925583 -537.76316400 3074.46877068 -2 2 1 1 4 538.63083493 -0.51417537 -3074.34022684 -2 2 1 1 5 -888.67714132 3068.44863407 94.67253981 -2 2 1 1 6 -1558.04777580 -0.70699113 -3077.81091058 -2 2 1 1 7 -1.32828637 1557.44790453 3075.85061698 -2 2 1 1 8 -3063.41400025 888.24866185 -93.06574178 -2 2 1 2 1 -72096.40621952 -74176.12775507 -72067.75165469 -2 2 1 2 2 72096.74900310 74179.82339053 72069.50842054 -2 2 1 2 3 539.56277779 0.83553497 1560.05091734 -2 2 1 2 4 -538.98433050 -0.36420755 -1559.23680634 -2 2 1 2 5 -3068.15941042 -9477.25897649 -3066.69186823 -2 2 1 2 6 3066.30623670 9473.01702969 3063.77820780 -2 2 1 2 7 1561.42205165 0.23566371 539.62704971 -2 2 1 2 8 -1560.67221257 -0.13925583 -539.17714626 -2 2 1 3 1 -80910.72175365 -72067.80521463 -67097.01483532 -2 2 1 3 2 80903.07339503 67084.37469083 72063.07051644 -2 2 1 3 3 3074.41521075 1558.65835905 0.38563153 -2 2 1 3 4 -83.23213785 893.78675905 -3055.76564164 -2 2 1 3 5 95.28312306 3067.72021896 -887.89516628 -2 2 1 3 6 -3078.63573357 -1.09262266 -1559.47247005 -2 2 1 3 7 3079.16062092 -534.67811179 0.29993563 -2 2 1 3 8 -3079.22489284 -1.09262266 536.44558962 -2 3 1 1 1 -67090.71618705 -80900.89886170 -72062.63132498 -2 3 1 1 2 72070.67602710 80911.55728862 67094.80816602 -2 3 1 1 3 -893.60465527 83.31783374 3055.82991356 -2 3 1 1 4 -1559.30107826 -3074.68301042 -0.51417537 -2 3 1 1 5 0.05355993 3080.78884292 -536.26348584 -2 3 1 1 6 535.98497418 -3081.15305048 0.38563153 -2 3 1 1 7 2.59230082 3075.90417692 1559.79382965 -2 3 1 1 8 -3065.68494146 -94.96176345 888.66642933 -2 3 1 2 1 -80900.00976679 -67087.20265536 -72062.08501365 -2 3 1 2 2 80911.66440849 72064.10957916 67096.63991578 -2 3 1 2 3 82.79294639 -893.25115971 3055.78706561 -2 3 1 2 4 -3074.65087446 -1559.34392621 -0.51417537 -2 3 1 2 5 3079.28916476 2.07812545 1557.43719255 -2 3 1 2 6 -94.96176345 -3065.72778941 888.64500536 -2 3 1 2 7 3076.95395163 3.31000394 -536.24206187 -2 3 1 2 8 -3081.13162650 535.98497418 0.33207159 -2 3 1 3 1 -72064.22741102 -72064.68802645 -74113.93395940 -2 3 1 3 2 72063.41330002 72066.18770461 74113.30195217 -2 3 1 3 3 -3055.08007448 -3055.48712998 -9478.78007862 -2 3 1 3 4 3055.25146627 3055.23004229 9478.69438273 -2 3 1 3 5 539.02717845 1555.42333902 -1.73534187 -2 3 1 3 6 -538.32018732 -1556.40884181 2.84938850 -2 3 1 3 7 1556.32314591 538.10594758 -3.12790016 -2 3 1 3 8 -1556.36599386 -538.32018732 2.84938850 -2 1 2 1 1 74168.12590089 67132.22513610 67087.80252662 -2 1 2 1 2 112.32589414 -216.86417384 -124.98746260 -2 1 2 1 3 -74173.55687822 -67116.61777126 67078.07604256 -2 1 2 1 4 -1.77818982 5.63450508 6.59858390 -2 1 2 1 5 -74164.99800073 67112.22585665 -67087.88822252 -2 1 2 1 6 0.67485517 7.73405451 8.56958948 -2 1 2 1 7 74056.16421430 -66920.70624370 -66963.33995138 -2 1 2 1 8 2.95650837 -3.65278752 -4.61686633 -2 1 2 2 1 72106.96823856 72098.22725729 80899.65627123 -2 1 2 2 2 -223.10926218 223.90194920 -329274.64983068 -2 1 2 2 3 -72098.58075286 -72107.33244611 80900.26685448 -2 1 2 2 4 0.94265484 -0.83553497 11785.47790359 -2 1 2 2 5 72111.43513708 -72111.33872920 80901.83080456 -2 1 2 2 6 2.34592512 0.06427192 -2959.91478327 -2 1 2 2 7 -71899.86268474 71899.95909263 80707.23685139 -2 1 2 2 8 -0.08569589 -2.36734909 -2959.85051135 -2 1 2 3 1 72073.58968753 80913.77466990 72065.05223400 -2 1 2 3 2 -129.25083337 -329284.87977812 109.93712107 -2 1 2 3 3 72069.91547604 80913.33547844 -72064.80585831 -2 1 2 3 4 -4.45618653 -2968.84858031 8.54816551 -2 1 2 3 5 -72080.29539130 80898.51008863 -72064.18456307 -2 1 2 3 6 6.60929589 11783.18553841 1.22116650 -2 1 2 3 7 -71939.00428470 80702.24506551 71944.24244628 -2 1 2 3 8 2.91366042 -2957.46173828 -0.27851166 -2 2 2 1 1 72107.07535843 72098.53790491 80899.89193494 -2 2 2 1 2 -221.71670389 221.02042474 -329275.43180572 -2 2 2 1 3 -72098.35580113 -72107.09678240 80899.68840719 -2 2 2 1 4 0.74983908 -1.32828637 11785.19939193 -2 2 2 1 5 72110.97452164 -72110.84597780 80901.35947714 -2 2 2 1 6 1.10333465 -1.79961379 -2958.58649690 -2 2 2 1 7 -71900.09834845 71904.34029525 80707.24756337 -2 2 2 1 8 0.14996782 -2.78511658 -2959.80766341 -2 2 2 2 1 67116.29641165 74173.12839875 67077.72254699 -2 2 2 2 2 217.71042080 -112.00453454 -125.21241433 -2 2 2 2 3 -67132.45008783 -74168.27586870 67088.12388623 -2 2 2 2 4 -5.64521707 1.84246174 6.72712774 -2 2 2 2 5 -67112.09731280 74164.95515278 -67087.80252662 -2 2 2 2 6 3.51353169 -3.04220427 -4.62757832 -2 2 2 2 7 66920.43844403 -74055.76787078 -66963.14713561 -2 2 2 2 8 -7.81975040 -0.80339901 8.59101346 -2 2 2 3 1 80913.27120652 72067.65524681 72064.59161857 -2 2 2 3 2 -329283.26226811 -127.06558805 -110.50485638 -2 2 2 3 3 80914.07460553 72073.86819919 -72060.86384715 -2 2 2 3 4 -2970.25185059 -5.52738522 -10.28350738 -2 2 2 3 5 80898.42439274 -72080.25254335 72063.94889936 -2 2 2 3 6 -2958.29727326 4.04913103 -0.66414318 -2 2 2 3 7 80702.52357717 -71939.23994842 -71944.44597403 -2 2 2 3 8 11783.42120212 6.55573595 -1.66035796 -2 3 2 1 1 72073.86819919 80913.86036579 72065.34145765 -2 3 2 1 2 -125.65160579 -329281.95540571 105.93083799 -2 3 2 1 3 72066.89469574 80912.24285578 -72059.55698475 -2 3 2 1 4 -5.29172151 -2970.13401873 6.57715993 -2 3 2 1 5 -72080.32752726 80898.31727287 -72064.14171512 -2 3 2 1 6 6.70570377 11783.33550622 1.04977471 -2 3 2 1 7 -71941.01813823 80701.88085796 71944.09247846 -2 3 2 1 8 4.82039408 -2957.61170610 0.61058325 -2 3 2 2 1 80913.22835857 72069.79764418 72064.60233056 -2 3 2 2 2 -329283.45508387 -126.72280447 -111.57605506 -2 3 2 2 3 80914.07460553 72071.57583400 -72060.90669509 -2 3 2 2 4 -2970.28398655 -5.46311330 -10.45489917 -2 3 2 2 5 80898.46724069 -72080.12399951 72063.75608360 -2 3 2 2 6 -2958.27584929 3.96343514 0.59987126 -2 3 2 2 7 80702.69496896 -71939.53988405 -71944.78875761 -2 3 2 2 8 11783.37835417 6.53431198 -1.54252611 -2 3 2 3 1 67092.85858442 67093.52272760 74101.72229438 -2 3 2 3 2 105.49164653 -104.55970367 5.58094515 -2 3 2 3 3 -67093.96191906 -67093.15852005 74102.09721392 -2 3 2 3 4 -2.28165320 2.35663711 -4.45618653 -2 3 2 3 5 -67082.33941333 67082.38226127 -74073.73187274 -2 3 2 3 6 -0.74983908 -1.71391790 -4.79897011 -2 3 2 3 7 66979.46149159 -66979.44006762 -74121.37879026 -2 3 2 3 8 1.69249392 0.78197504 -4.72398620 -2 1 3 1 1 -0.81411100 -539.53064183 1559.94379747 -2 1 3 1 2 -74179.75911861 -72096.84541098 72069.47628458 -2 1 3 1 3 74176.10633109 72096.36337158 -72067.86948655 -2 1 3 1 4 0.36420755 538.96290653 -1559.23680634 -2 1 3 1 5 9477.30182443 3068.12727446 -3066.67044425 -2 1 3 1 6 0.10711987 1560.65078860 -539.11287434 -2 1 3 1 7 -0.29993563 -1561.43276364 539.63776170 -2 1 3 1 8 -9473.01702969 -3066.29552471 3063.76749581 -2 1 3 2 1 537.82743592 -0.10711987 3074.36165081 -2 1 3 2 2 -67119.78851937 -72109.14277189 80913.09981473 -2 1 3 2 3 72095.00294925 67136.52064283 -80912.71418320 -2 1 3 2 4 0.51417537 -538.70581884 -3074.34022684 -2 1 3 2 5 -3068.48077003 888.68785331 94.62969186 -2 1 3 2 6 -888.27008582 3063.37115230 -93.15143767 -2 1 3 2 7 -1557.45861652 1.38184630 3075.86132897 -2 1 3 2 8 0.64271921 1558.00492785 -3077.81091058 -2 1 3 3 1 1558.67978302 3074.40449876 -0.31064762 -2 1 3 3 2 67084.31041891 80902.81630735 -72062.98482054 -2 1 3 3 3 -72067.65524681 -80910.63605775 67096.88629147 -2 1 3 3 4 893.78675905 -83.23213785 3055.74421766 -2 1 3 3 5 3067.72021896 95.31525902 887.93801423 -2 1 3 3 6 -1.03906272 -3079.24631682 -536.52057352 -2 1 3 3 7 -534.67811179 3079.13919695 -0.26779967 -2 1 3 3 8 -1.04977471 -3078.61430959 1559.45104607 -2 2 3 1 1 -0.81411100 539.36996203 3074.26524293 -2 2 3 1 2 -72094.99223726 -67142.54077944 80912.70347121 -2 2 3 1 3 67126.66561492 72107.61095777 -80913.99962162 -2 2 3 1 4 -538.63083493 0.53559934 -3074.29737889 -2 2 3 1 5 -1.76747783 -1559.27965428 3080.53175524 -2 2 3 1 6 1557.99421586 0.70699113 -3077.81091058 -2 2 3 1 7 888.00228615 -3058.19726265 91.65175952 -2 2 3 1 8 3063.43542422 -888.25937383 -93.09787774 -2 2 3 2 1 -538.62012295 0.42847947 1558.30486348 -2 2 3 2 2 -72107.71807764 -74174.33885326 72072.29353712 -2 2 3 2 3 72109.50697945 74175.47432387 -72075.34645337 -2 2 3 2 4 538.97361851 0.36420755 -1559.19395839 -2 2 3 2 5 -1559.68670978 0.34278358 538.98433050 -2 2 3 2 6 -3066.29552471 -9473.05987764 3063.77820780 -2 2 3 2 7 3063.11406462 9470.57469669 -3059.60053293 -2 2 3 2 8 1560.62936463 0.12854384 -539.20928222 -2 2 3 3 1 3074.55446658 1560.10447727 -0.53559934 -2 2 3 3 2 80902.88057927 67095.07596570 -72062.42779723 -2 2 3 3 3 -80911.90007220 -72074.42522250 67095.40803729 -2 2 3 3 4 -83.26427381 893.74391110 3055.74421766 -2 2 3 3 5 3081.32444227 -535.96355021 -0.36420755 -2 2 3 3 6 -3078.63573357 -1.02835074 1559.47247005 -2 2 3 3 7 94.22263636 3063.62823999 889.23416464 -2 2 3 3 8 -3079.26774079 -1.04977471 -536.49914955 -2 3 3 1 1 -893.35827957 82.95362619 -3055.86204952 -2 3 3 1 2 72064.09886718 80909.45773920 -67096.52208392 -2 3 3 1 3 -67086.40996833 -80898.98141606 72061.18520675 -2 3 3 1 4 -1559.30107826 -3074.68301042 0.47132742 -2 3 3 1 5 2.18524532 3079.41770861 -1557.30864870 -2 3 3 1 6 535.95283822 -3081.13162650 -0.36420755 -2 3 3 1 7 2.63514877 3077.89660647 536.88478108 -2 3 3 1 8 -3065.72778941 -94.96176345 -888.60215741 -2 3 3 2 1 83.25356182 -893.61536726 -3055.86204952 -2 3 3 2 2 80911.12880915 72070.21541167 -67094.42253450 -2 3 3 2 3 -80900.47038223 -67090.39482744 72062.25640544 -2 3 3 2 4 -3074.67229843 -1559.34392621 0.47132742 -2 3 3 2 5 3080.84240286 0.10711987 536.26348584 -2 3 3 2 6 -94.96176345 -3065.70636543 -888.62358139 -2 3 3 2 7 3075.90417692 2.62443678 -1559.80454164 -2 3 3 2 8 -3081.13162650 535.95283822 -0.34278358 -2 3 3 3 1 3055.44428203 3055.24075428 -9478.87648650 -2 3 3 3 2 -72065.91990494 -72065.25576176 74112.89489667 -2 3 3 3 3 72065.13792990 72064.93440215 -74114.18033509 -2 3 3 3 4 -3055.29431421 -3055.29431421 9478.69438273 -2 3 3 3 5 -1555.32693114 -538.83436268 -1.73534187 -2 3 3 3 6 538.34161129 1556.38741783 2.76369261 -2 3 3 3 7 -538.72724282 -1555.42333902 -2.48518095 -2 3 3 3 8 1556.36599386 538.34161129 2.78511658 -2 1 4 1 1 -0.04284795 0.04284795 897.62165034 -2 1 4 1 2 -0.68556716 0.47132742 -5.48453727 -2 1 4 1 3 -0.06427192 0.12854384 897.66449829 -2 1 4 1 4 0.81411100 -0.44990345 -5.59165714 -2 1 4 1 5 -0.00000000 -0.00000000 -894.83653376 -2 1 4 1 6 -0.07498391 -0.32135961 -1.19974253 -2 1 4 1 7 0.04284795 -0.00000000 -886.58830388 -2 1 4 1 8 -0.00000000 0.27851166 -1.17831855 -2 1 4 2 1 -538.68439487 538.70581884 -83.01789811 -2 1 4 2 2 6.76997569 -1.42469425 -2969.41631561 -2 1 4 2 3 538.57727500 -538.59869897 -80.72553292 -2 1 4 2 4 -2.81725254 5.44168932 -2969.55557144 -2 1 4 2 5 -540.24834495 -540.24834495 -83.12501798 -2 1 4 2 6 -0.27851166 -0.06427192 3371.85494970 -2 1 4 2 7 535.55649471 535.55649471 -99.79286952 -2 1 4 2 8 0.98550279 0.85695895 2913.94964769 -2 1 4 3 1 -1559.83667760 -3074.96152208 -3058.42221437 -2 1 4 3 2 8.82667717 11785.60644743 6.17010443 -2 1 4 3 3 -1559.79382965 -3074.87582618 3058.40079040 -2 1 4 3 4 -5.74162495 -2970.54107423 0.85695895 -2 1 4 3 5 1560.82218039 -3075.15433784 3060.02901240 -2 1 4 3 6 -0.81411100 2915.31007002 -1.07119869 -2 1 4 3 7 1556.38741783 -3078.66786953 -3064.48519893 -2 1 4 3 8 -0.02142397 573.20912850 -1.28543842 -2 2 4 1 1 538.62012295 -538.70581884 -83.03932209 -2 2 4 1 2 2.20666929 -4.78825812 -2970.38039443 -2 2 4 1 3 -538.55585103 538.66297089 -80.89692471 -2 2 4 1 4 -6.07369655 0.92123087 -2970.34825847 -2 2 4 1 5 540.26976892 540.24834495 -80.89692471 -2 2 4 1 6 -0.94265484 -0.66414318 2913.74611994 -2 2 4 1 7 -535.66361458 -535.62076663 -99.94283734 -2 2 4 1 8 0.17139179 -0.06427192 3371.72640585 -2 2 4 2 1 -0.00000000 0.02142397 897.60022637 -2 2 4 2 2 -0.44990345 0.69627915 -5.50596124 -2 2 4 2 3 0.06427192 0.08569589 897.57880239 -2 2 4 2 4 0.51417537 -0.85695895 -5.46311330 -2 2 4 2 5 0.04284795 0.02142397 -895.00792555 -2 2 4 2 6 -0.26779967 -0.00000000 -1.19974253 -2 2 4 2 7 -0.04284795 0.08569589 -886.48118401 -2 2 4 2 8 0.27851166 -0.06427192 -1.29615041 -2 2 4 3 1 -3074.87582618 -1559.92237350 -3058.22939861 -2 2 4 3 2 11785.64929538 8.88023710 -6.13796847 -2 2 4 3 3 -3074.85440221 -1559.79382965 3058.35794245 -2 2 4 3 4 -2970.40181840 -5.69877701 -0.77126305 -2 2 4 3 5 -3075.21860976 1560.77933244 -3059.77192472 -2 2 4 3 6 573.08058465 -0.06427192 1.19974253 -2 2 4 3 7 -3078.62502158 1556.51596168 3064.54947085 -2 2 4 3 8 2915.22437412 -0.71770312 1.04977471 -2 3 4 1 1 -1559.75098171 -3074.94009810 3058.29367053 -2 3 4 1 2 -5.67735303 -2970.50893827 -0.72841511 -2 3 4 1 3 -1559.77240568 -3074.81155426 -3058.31509451 -2 3 4 1 4 8.76240525 11785.60644743 -6.14868045 -2 3 4 1 5 1560.75790847 -3075.21860976 -3059.81477267 -2 3 4 1 6 -0.04284795 573.19841651 1.24259047 -2 3 4 1 7 1556.49453770 -3078.73214145 3064.46377496 -2 3 4 1 8 -0.74983908 2915.35291796 1.03906272 -2 3 4 2 1 -3074.96152208 -1559.81525363 3058.29367053 -2 3 4 2 2 -2970.47680231 -5.67735303 0.63200722 -2 3 4 2 3 -3074.94009810 -1559.79382965 -3058.22939861 -2 3 4 2 4 11785.60644743 8.84810114 6.10583251 -2 3 4 2 5 -3075.19718579 1560.75790847 3059.81477267 -2 3 4 2 6 2915.33149399 -0.79268703 -1.09262266 -2 3 4 2 7 -3078.66786953 1556.51596168 -3064.46377496 -2 3 4 2 8 573.19841651 0.04284795 -1.30686240 -2 3 4 3 1 -0.04284795 -0.02142397 9480.08694102 -2 3 4 3 2 9.46939638 -9.45868439 -6.74855172 -2 3 4 3 3 -0.04284795 -0.02142397 9480.27975678 -2 3 4 3 4 -9.41583644 9.55509227 -6.66285582 -2 3 4 3 5 0.04284795 0.04284795 -9484.05037615 -2 3 4 3 6 -1.27472644 -1.32828637 -2.61372479 -2 3 4 3 7 -0.04284795 0.04284795 -9457.20613710 -2 3 4 3 8 1.24259047 1.33899836 -2.63514877 -2 1 5 1 1 -1.37113432 1559.48318203 -536.74552525 -2 1 5 1 2 -74173.56759021 72113.86675809 -72082.25568489 -2 1 5 1 3 9477.44108026 -3068.12727446 3067.24889154 -2 1 5 1 4 0.21423974 -540.84821621 1560.26515707 -2 1 5 1 5 74163.21981091 -72101.89075679 72063.22048425 -2 1 5 1 6 -1.04977471 -1561.03642013 541.72659913 -2 1 5 1 7 -1.13547061 538.39517122 -1558.10133573 -2 1 5 1 8 -9463.80472100 3060.09328432 -3055.18719435 -2 1 5 2 1 1560.02949336 -0.37491954 3080.53175524 -2 1 5 2 2 67117.81751378 -72109.50697945 80902.50565973 -2 1 5 2 3 3068.91996149 888.06655807 94.88677954 -2 1 5 2 4 -0.52488736 -540.18407303 -3074.68301042 -2 1 5 2 5 -72100.32680671 67159.12293509 -80923.66183376 -2 1 5 2 6 889.54481225 3054.26596348 -86.85278940 -2 1 5 2 7 -533.90684873 -3.63136354 3077.32887117 -2 1 5 2 8 -1.56395008 1552.14547104 -3070.03400812 -2 1 5 3 1 537.93455579 3080.68172306 -0.39634351 -2 1 5 3 2 -67092.28013713 80902.75203543 -72062.01002974 -2 1 5 3 3 -3066.95966790 94.73681173 888.06655807 -2 1 5 3 4 -891.08733836 -81.19686035 3057.41528761 -2 1 5 3 5 72059.81407243 -80921.73367613 67085.81009707 -2 1 5 3 6 3.05291625 -3077.59667084 -534.78523165 -2 1 5 3 7 -1556.53738565 3074.92938612 3.52424367 -2 1 5 3 8 6.08440853 -3072.58346099 1562.17189073 -2 2 5 1 1 -888.08798204 -3068.91996149 94.89749153 -2 2 5 1 2 72109.53911541 -67117.89249769 80902.48423576 -2 2 5 1 3 0.39634351 -1560.05091734 3080.57460319 -2 2 5 1 4 540.16264905 0.55702332 -3074.64016247 -2 2 5 1 5 -67159.14435906 72100.39107863 -80923.83322555 -2 2 5 1 6 -1552.10262309 1.60679803 -3070.05543210 -2 2 5 1 7 3.64207553 533.90684873 3077.29673521 -2 2 5 1 8 -3054.30881142 -889.57694822 -86.90634934 -2 2 5 2 1 3068.10585049 -9477.40894430 3067.23817955 -2 2 5 2 2 -72113.93103002 74173.47118233 -72082.21283694 -2 2 5 2 3 -1559.47247005 1.43540624 -536.73481326 -2 2 5 2 4 540.79465628 -0.23566371 1560.30800502 -2 2 5 2 5 72101.93360474 -74163.28408283 72063.02766849 -2 2 5 2 6 -3060.05043638 9463.82614497 -3055.18719435 -2 2 5 2 7 -538.38445924 1.13547061 -1558.10133573 -2 2 5 2 8 1560.99357218 1.01763875 541.66232721 -2 2 5 3 1 94.71538776 -3066.95966790 -888.12011800 -2 2 5 3 2 80902.81630735 -67092.44081693 72062.11714961 -2 2 5 3 3 3080.68172306 537.91313182 0.36420755 -2 2 5 3 4 -81.17543637 -891.10876234 -3057.45813556 -2 2 5 3 5 -80921.89435593 72059.87834435 -67085.87436899 -2 2 5 3 6 -3072.57274901 6.08440853 -1562.15046676 -2 2 5 3 7 3074.94009810 -1556.53738565 -3.53495566 -2 2 5 3 8 -3077.61809482 3.05291625 534.84950358 -2 3 5 1 1 -0.94265484 3079.87832404 538.45944314 -2 3 5 1 2 -72076.28910821 80899.54915136 -67091.74453778 -2 3 5 1 3 -0.27851166 3080.51033127 -1555.12340339 -2 3 5 1 4 1560.82218039 -3074.44734671 0.47132742 -2 3 5 1 5 67094.89386192 -80910.01476251 72055.57212564 -2 3 5 1 6 -530.70396466 -3076.84683176 0.51417537 -2 3 5 1 7 889.63050815 93.59062914 -3056.76185641 -2 3 5 1 8 3062.81412898 -92.15522290 -891.29086611 -2 3 5 2 1 3080.51033127 -0.26779967 1555.09126742 -2 3 5 2 2 80899.49559142 -72076.25697225 67091.74453778 -2 3 5 2 3 3079.86761205 -1.00692676 -538.44873116 -2 3 5 2 4 -3074.42592273 1560.86502834 -0.42847947 -2 3 5 2 5 -80910.05761046 67094.85101397 -72055.33646193 -2 3 5 2 6 -92.11237495 3062.77128104 891.32300207 -2 3 5 2 7 93.60134112 889.66264411 3056.79399237 -2 3 5 2 8 -3076.86825574 -530.67182870 -0.50346338 -2 3 5 3 1 -536.90620505 1557.46932851 -2.82796453 -2 3 5 3 2 -72066.43408031 72066.63760806 -74083.89754826 -2 3 5 3 3 -1557.42648056 536.90620505 -2.82796453 -2 3 5 3 4 -3056.79399237 3057.11535198 -9483.08629733 -2 3 5 3 5 72059.12850528 -72061.37802251 74120.17904773 -2 3 5 3 6 540.67682442 -1552.85246217 -6.34149622 -2 3 5 3 7 3064.05671946 -3064.05671946 9465.69003069 -2 3 5 3 8 1553.62372523 -539.85200144 -6.90923152 -2 1 6 1 1 0.12854384 886.41691209 -1.15689458 -2 1 6 1 2 0.08569589 2.37806108 8.83738915 -2 1 6 1 3 -0.21423974 -886.45976004 -1.19974253 -2 1 6 1 4 0.08569589 -0.04284795 -0.29993563 -2 1 6 1 5 -0.47132742 891.28015412 3.34213990 -2 1 6 1 6 0.20352775 -2.29236519 -8.86952511 -2 1 6 1 7 -0.08569589 -891.30157810 -1.09262266 -2 1 6 1 8 0.19281576 0.04284795 0.33207159 -2 1 6 2 1 -1561.16496397 -3065.98487709 -3079.41770861 -2 1 6 2 2 6.98421543 -0.08569589 11784.99586418 -2 1 6 2 3 1561.14354000 3065.92060517 -3079.22489284 -2 1 6 2 4 -0.18210378 -0.10711987 2915.26722207 -2 1 6 2 5 -1560.37227694 3055.76564164 -3077.03964753 -2 1 6 2 6 -2.32450115 3.83489129 -2964.86372120 -2 1 6 2 7 1555.18767531 -3059.10778153 -3074.06171518 -2 1 6 2 8 0.79268703 -0.23566371 574.52670288 -2 1 6 3 1 -539.04860242 -90.73052865 536.58484545 -2 1 6 3 2 6.42719211 -2961.02882991 -0.50346338 -2 1 6 3 3 -539.09145037 -90.75195262 -536.54199750 -2 1 6 3 4 -0.80339901 3371.85494970 -0.53559934 -2 1 6 3 5 542.28362245 -86.98133325 -534.31390423 -2 1 6 3 6 -5.13104170 -2964.30669788 -1.39255829 -2 1 6 3 7 535.36367894 -92.25163078 537.76316400 -2 1 6 3 8 -0.00000000 2914.30314325 -1.11404663 -2 2 6 1 1 -1558.52981520 3063.30688038 -3078.06799826 -2 2 6 1 2 1.75676584 4.67042627 -2955.29791694 -2 2 6 1 3 1558.44411931 -3063.19976051 -3078.15369416 -2 2 6 1 4 -0.67485517 -0.06427192 573.66974393 -2 2 6 1 5 -1552.65964641 -3060.92881930 -3072.66915689 -2 2 6 1 6 -6.28793628 0.74983908 11771.78798439 -2 2 6 1 7 1557.77997612 3055.33716216 -3075.58281731 -2 2 6 1 8 0.08569589 0.12854384 2914.09961550 -2 2 6 2 1 -0.42847947 9471.68874332 -1.97100558 -2 2 6 2 2 -0.02142397 -3.06362824 6.94136748 -2 2 6 2 3 0.44990345 -9471.62447140 -1.97100558 -2 2 6 2 4 -0.81411100 0.10711987 -0.21423974 -2 2 6 2 5 1.17831855 9463.44051345 5.78447290 -2 2 6 2 6 0.01071199 3.14932413 -6.98421543 -2 2 6 2 7 0.36420755 -9463.44051345 -1.94958161 -2 2 6 2 8 -0.79268703 -0.10711987 0.12854384 -2 2 6 3 1 -3078.11084621 3061.63581043 -1559.04399057 -2 2 6 3 2 -2959.50772777 -3.92058719 1.53181412 -2 2 6 3 3 -3078.15369416 3061.59296248 1559.06541455 -2 2 6 3 4 2913.71398398 -0.62129524 1.00692676 -2 2 6 3 5 -3070.37679170 -3054.33023540 -1562.40755445 -2 2 6 3 6 11772.96630295 -4.02770706 1.54252611 -2 2 6 3 7 -3075.56139334 -3061.35729877 1557.35149665 -2 2 6 3 8 574.78379056 1.11404663 1.03906272 -2 3 6 1 1 535.49222279 -94.37260418 -538.34161129 -2 3 6 1 2 5.12032972 -2955.72639641 -2.58158883 -2 3 6 1 3 535.57791868 -94.39402815 538.29876334 -2 3 6 1 4 0.03213596 2915.50288578 -1.28543842 -2 3 6 1 5 -531.78587534 -98.05752765 539.75559355 -2 3 6 1 6 -6.44861609 -2959.05782433 0.83553497 -2 3 6 1 7 -538.77009076 -88.41673949 -536.04924610 -2 3 6 1 8 0.79268703 3374.69362621 -0.55702332 -2 3 6 2 1 -3080.61745113 -3069.39128891 -1556.34456989 -2 3 6 2 2 11786.37771049 8.56958948 -3.54566765 -2 3 6 2 3 -3080.70314703 -3069.43413686 1556.32314591 -2 3 6 2 4 572.99488876 -0.14996782 -1.26401445 -2 3 6 2 5 -3078.08942224 3060.28610009 -1554.73777186 -2 3 6 2 6 -2963.12837933 8.44104564 0.36420755 -2 3 6 2 7 -3073.01194047 3060.07186035 1559.85810157 -2 3 6 2 8 2916.01706115 1.43540624 -0.68556716 -2 3 6 3 1 0.12854384 885.32428943 2.46375698 -2 3 6 3 2 -2.39948506 3.48139573 -2.67799671 -2 3 6 3 3 -0.17139179 -885.36713738 2.48518095 -2 3 6 3 4 1.07119869 -0.08569589 -1.86388571 -2 3 6 3 5 -0.42847947 890.10183557 -7.45554285 -2 3 6 3 6 1.42469425 1.94958161 2.63514877 -2 3 6 3 7 -0.34278358 -896.80753934 2.50660492 -2 3 6 3 8 0.66414318 1.27472644 1.84246174 -2 1 7 1 1 -9469.58919390 3060.51105181 3063.71393588 -2 1 7 1 2 74060.92033646 -71905.42220592 -71940.73962657 -2 1 7 1 3 -0.19281576 -1555.80897054 -535.51364676 -2 1 7 1 4 -0.69627915 535.94212623 1555.65900273 -2 1 7 1 5 -1.01763875 -534.44244807 -1556.40884181 -2 1 7 1 6 -0.96407882 1554.24502046 535.79215842 -2 1 7 1 7 -74051.60090790 71902.41213761 71937.42962264 -2 1 7 1 8 9463.16200179 -3057.43671158 -3059.97545247 -2 1 7 2 1 -3065.19219007 -890.86238664 93.19428562 -2 1 7 2 2 -66918.29604666 71901.25524303 80696.62127241 -2 1 7 2 3 -1561.19709993 0.66414318 3079.20346887 -2 1 7 2 4 0.35349557 535.42795087 -3078.30366197 -2 1 7 2 5 538.17021950 -2.74226863 3075.53996937 -2 1 7 2 6 -890.29465133 -3058.82926988 -90.85907249 -2 1 7 2 7 71896.13491332 -66927.43337144 -80700.32761986 -2 1 7 2 8 0.12854384 -1557.40505658 -3075.04721797 -2 1 7 3 1 -3060.50033982 90.22706526 -890.13397153 -2 1 7 3 2 -66969.62788766 80709.22928094 71950.99099799 -2 1 7 3 3 540.01268124 3075.39000155 -0.49275140 -2 1 7 3 4 -884.81011407 -101.65675524 -3065.12791814 -2 1 7 3 5 -1559.93308548 3079.56767642 1.77818982 -2 1 7 3 6 -0.85695895 -3073.03336444 537.46322837 -2 1 7 3 7 71939.62557994 -80702.99490459 -66976.26931951 -2 1 7 3 8 -3.96343514 -3076.83611978 -1558.30486348 -2 2 7 1 1 0.21423974 1561.78625921 3079.80334013 -2 2 7 1 2 -71903.80469591 66918.51028640 80696.89978407 -2 2 7 1 3 891.04449041 3065.10649417 93.32282946 -2 2 7 1 4 -535.42795087 -0.42847947 -3078.34650992 -2 2 7 1 5 2.99935632 -538.12737155 3075.41142552 -2 2 7 1 6 1557.39434460 -0.14996782 -3075.04721797 -2 2 7 1 7 66928.72952185 -71897.00258425 -80701.29169868 -2 2 7 1 8 3058.76499795 890.24109140 -90.79480057 -2 2 7 2 1 1555.83039452 0.23566371 -535.47079881 -2 2 7 2 2 71905.26152612 -74060.84535255 -71940.55752280 -2 2 7 2 3 -3060.53247578 9469.65346582 3063.69251191 -2 2 7 2 4 -535.97426219 0.70699113 1555.59473081 -2 2 7 2 5 534.44244807 0.96407882 -1556.51596168 -2 2 7 2 6 3057.43671158 -9463.14057781 -3060.02901240 -2 2 7 2 7 -71902.24074582 74051.44022810 71937.32250277 -2 2 7 2 8 -1554.18074854 1.02835074 535.80287040 -2 2 7 3 1 3075.39000155 539.99125726 0.47132742 -2 2 7 3 2 80709.40067273 -66969.85283938 -71951.14096581 -2 2 7 3 3 90.21635328 -3060.52176380 890.12325954 -2 2 7 3 4 -101.65675524 -884.78869009 3065.04222225 -2 2 7 3 5 3079.64266033 -1559.90094952 -1.79961379 -2 2 7 3 6 -3076.85754375 -4.02770706 1558.31557547 -2 2 7 3 7 -80703.27341625 71939.86124365 66976.37643938 -2 2 7 3 8 -3073.03336444 -0.83553497 -537.45251638 -2 3 7 1 1 3.53495566 3077.93945442 1556.83732128 -2 3 7 1 2 -71942.21788076 80699.11716535 66981.27181737 -2 3 7 1 3 2.48518095 3075.53996937 -537.99882771 -2 3 7 1 4 1556.86945724 -3078.90353324 0.51417537 -2 3 7 1 5 891.39798598 92.57299038 3063.88532767 -2 3 7 1 6 -538.50229109 -3072.51918907 -0.29993563 -2 3 7 1 7 66969.13513626 -80705.09445401 -71954.82588929 -2 3 7 1 8 3057.32959172 -88.63097922 890.76597876 -2 3 7 2 1 3075.51854539 2.47446896 538.03096367 -2 3 7 2 2 80699.28855714 -71942.34642460 -66981.41107320 -2 3 7 2 3 3077.88589449 3.51353169 -1556.85874526 -2 3 7 2 4 -3078.93566920 1556.83732128 -0.47132742 -2 3 7 2 5 92.50871846 891.38727399 -3063.79963178 -2 3 7 2 6 -88.57741929 3057.39386364 -890.72313081 -2 3 7 2 7 -80705.30869375 66969.18869620 71955.05084101 -2 3 7 2 8 -3072.51918907 -538.44873116 0.36420755 -2 3 7 3 1 1559.10826249 -536.75623723 -3.21359606 -2 3 7 3 2 71946.24558782 -71946.22416384 -74126.15633640 -2 3 7 3 3 536.79908518 -1559.08683852 -3.21359606 -2 3 7 3 4 3067.70950698 -3067.69879499 -9458.19163989 -2 3 7 3 5 -3058.14370272 3058.20797464 9466.35417387 -2 3 7 3 6 -536.20992591 1559.45104607 2.91366042 -2 3 7 3 7 -71955.95064791 71956.00420784 74118.46512984 -2 3 7 3 8 -1559.42962210 536.20992591 2.99935632 -2 1 8 1 1 9471.64589538 -0.38563153 -1.99242955 -2 1 8 1 2 3.02078029 0.02142397 6.95207947 -2 1 8 1 3 -9471.53877551 0.38563153 -1.97100558 -2 1 8 1 4 -0.08569589 0.81411100 -0.23566371 -2 1 8 1 5 -9463.50478537 -1.19974253 5.74162495 -2 1 8 1 6 0.13925583 0.77126305 0.25708768 -2 1 8 1 7 9463.48336139 -0.49275140 -1.99242955 -2 1 8 1 8 -3.08505221 0.06427192 -6.88780755 -2 1 8 2 1 3063.32830435 -1558.52981520 -3077.98230237 -2 1 8 2 2 -4.69185024 -1.77818982 -2955.30862893 -2 1 8 2 3 -3063.22118448 1558.50839123 -3078.17511813 -2 1 8 2 4 0.08569589 0.68556716 573.75543983 -2 1 8 2 5 3060.84312340 1552.55252654 -3072.58346099 -2 1 8 2 6 -0.04284795 -0.19281576 2914.04605557 -2 1 8 2 7 -3055.20861832 -1557.71570420 -3075.58281731 -2 1 8 2 8 -0.81411100 6.39505615 11771.69157651 -2 1 8 3 1 3061.50726659 -3078.08942224 -1559.04399057 -2 1 8 3 2 -4.77754614 -2958.82216061 -0.83553497 -2 1 8 3 3 3061.61438646 -3078.08942224 1558.89402276 -2 1 8 3 4 -0.79268703 2913.66042404 -0.85695895 -2 1 8 3 5 -3054.39450732 -3070.33394376 1562.55752226 -2 1 8 3 6 0.95336683 574.82663851 -1.11404663 -2 1 8 3 7 -3059.08635756 -3075.43284950 -1557.28722473 -2 1 8 3 8 -4.94893793 11772.39856764 -2.31378916 -2 2 8 1 1 -3065.96345312 -1561.10069205 -3079.46055655 -2 2 8 1 2 0.10711987 -6.98421543 11784.98515220 -2 2 8 1 3 3066.00630107 1561.12211602 -3079.16062092 -2 2 8 1 4 0.05355993 0.17139179 2915.28864604 -2 2 8 1 5 -3055.74421766 1560.26515707 -3076.99679958 -2 2 8 1 6 0.17139179 -0.77126305 574.46243096 -2 2 8 1 7 3059.12920551 -1555.18767531 -3074.14741108 -2 2 8 1 8 -3.79204335 2.48518095 -2964.81016127 -2 2 8 2 1 886.39548812 0.17139179 -1.09262266 -2 2 8 2 2 -2.42090903 -0.13925583 8.76240525 -2 2 8 2 3 -886.45976004 -0.25708768 -1.17831855 -2 2 8 2 4 -0.00000000 -0.06427192 -0.32135961 -2 2 8 2 5 -891.21588220 0.40705550 3.34213990 -2 2 8 2 6 -0.05355993 -0.06427192 0.27851166 -2 2 8 2 7 891.36585002 0.23566371 -1.09262266 -2 2 8 2 8 2.37806108 -0.18210378 -8.86952511 -2 2 8 3 1 -90.75195262 -539.02717845 536.60626942 -2 2 8 3 2 -2961.97148475 7.03777536 -0.23566371 -2 2 8 3 3 -90.81622454 -539.13429832 -536.62769339 -2 2 8 3 4 3371.66213393 -0.96407882 0.53559934 -2 2 8 3 5 -84.90320780 542.19792656 534.14251244 -2 2 8 3 6 2914.08890352 0.14996782 1.24259047 -2 2 8 3 7 -92.23020681 535.29940702 -537.78458797 -2 2 8 3 8 -2965.14223286 -5.70948899 1.94958161 -2 3 8 1 1 -3069.34844096 -3080.59602716 -1556.32314591 -2 3 8 1 2 8.50531756 11786.39913446 2.34592512 -2 3 8 1 3 -3069.26274507 -3080.59602716 1556.43026578 -2 3 8 1 4 -0.19281576 573.02702472 1.00692676 -2 3 8 1 5 3062.55704130 -3078.02515032 1554.60922802 -2 3 8 1 6 1.45683021 2916.01706115 1.04977471 -2 3 8 1 7 3057.84376708 -3072.90482060 -1559.90094952 -2 3 8 1 8 8.39819769 -2963.10695536 0.92123087 -2 3 8 2 1 -94.43687610 535.57791868 -538.32018732 -2 3 8 2 2 -2955.75853237 5.20602561 2.49589294 -2 3 8 2 3 -94.52257199 535.53507073 538.25591539 -2 3 8 2 4 2915.46003783 -0.02142397 1.28543842 -2 3 8 2 5 -98.03610368 -531.82872328 -539.62704971 -2 3 8 2 6 3374.60793032 0.74983908 0.47132742 -2 3 8 2 7 -88.45958743 -538.83436268 536.02782213 -2 3 8 2 8 -2958.99355240 -6.39505615 -0.91051888 -2 3 8 3 1 885.30286546 0.17139179 2.37806108 -2 3 8 3 2 -1.73534187 1.22116650 -2.57087684 -2 3 8 3 3 -885.36713738 -0.19281576 2.46375698 -2 3 8 3 4 0.52488736 -0.92123087 -1.79961379 -2 3 8 3 5 -892.24423294 0.40705550 -7.45554285 -2 3 8 3 6 -0.86767094 -0.72841511 1.75676584 -2 3 8 3 7 894.47232621 0.17139179 2.42090903 -2 3 8 3 8 -0.19281576 -0.09640788 2.64586075 -3 1 1 1 1 -0.04284795 0.08569589 4.69185024 -3 1 1 1 2 -0.64271921 -0.00000000 -897.66449829 -3 1 1 1 3 0.01071199 0.02142397 4.54188243 -3 1 1 1 4 0.67485517 -0.08569589 -897.49310650 -3 1 1 1 5 0.04284795 0.02142397 1.60679803 -3 1 1 1 6 -0.70699113 0.06427192 891.92287334 -3 1 1 1 7 -0.00000000 0.06427192 0.55702332 -3 1 1 1 8 0.62129524 -0.00000000 891.86931340 -3 1 1 2 1 0.06427192 0.02142397 2970.18757867 -3 1 1 2 2 -539.11287434 539.09145037 80.63983703 -3 1 1 2 3 0.06427192 0.08569589 2970.36968244 -3 1 1 2 4 538.97361851 -538.89863461 80.68268498 -3 1 1 2 5 0.02142397 -0.12854384 -2913.72469596 -3 1 1 2 6 -537.54892426 -537.63462016 91.65175952 -3 1 1 2 7 0.04284795 0.01071199 -3371.82281374 -3 1 1 2 8 537.61319618 537.65604413 91.69460746 -3 1 1 3 1 7.02706338 2969.23421184 0.11783186 -3 1 1 3 2 1560.54366873 3074.81155426 -3058.35794245 -3 1 1 3 3 -12.64014449 -11784.25673709 0.02142397 -3 1 1 3 4 1560.58651668 3074.83297823 3058.40079040 -3 1 1 3 5 -0.71770312 -573.39123227 0.08569589 -3 1 1 3 6 -1557.95136791 3077.01822355 3060.07186035 -3 1 1 3 7 1.00692676 -2915.16010220 -0.02142397 -3 1 1 3 8 -1557.84424805 3076.98608759 -3059.95402849 -3 2 1 1 1 0.04284795 -0.11783186 2970.23042661 -3 2 1 1 2 538.27733937 -538.34161129 81.04689253 -3 2 1 1 3 0.04284795 -0.00000000 2970.15544271 -3 2 1 1 4 -538.26662738 538.34161129 81.19686035 -3 2 1 1 5 -0.01071199 0.04284795 -3371.81210175 -3 2 1 1 6 538.19164347 538.32018732 91.52321567 -3 2 1 1 7 0.02142397 0.03213596 -2913.68184802 -3 2 1 1 8 -538.29876334 -538.34161129 91.42680779 -3 2 1 2 1 -0.14996782 -0.05355993 4.53117044 -3 2 1 2 2 -0.00000000 0.74983908 -897.49310650 -3 2 1 2 3 0.05355993 -0.08569589 4.71327422 -3 2 1 2 4 0.07498391 -0.72841511 -897.32171471 -3 2 1 2 5 0.06427192 0.04284795 1.58537405 -3 2 1 2 6 -0.23566371 -0.59987126 891.92287334 -3 2 1 2 7 0.02142397 0.03213596 0.46061543 -3 2 1 2 8 -0.00000000 0.62129524 891.85860142 -3 2 1 3 1 2969.12709197 6.95207947 0.01071199 -3 2 1 3 2 3074.91867413 1559.02256660 -3058.46506232 -3 2 1 3 3 -11784.26744908 -7.66978259 -0.04284795 -3 2 1 3 4 3074.96152208 1559.04399057 3058.31509451 -3 2 1 3 5 -2915.17081419 0.89980690 0.06427192 -3 2 1 3 6 3076.91110368 -1559.25823031 -3059.72907677 -3 2 1 3 7 -573.41265625 0.44990345 0.02142397 -3 2 1 3 8 3076.80398381 -1559.34392621 3059.88975657 -3 3 1 1 1 -7.58408669 -11784.32100901 -0.03213596 -3 3 1 1 2 1559.04399057 3074.96152208 3058.50791027 -3 3 1 1 3 6.89851953 2969.19136389 0.06427192 -3 3 1 1 4 1559.04399057 3075.02579400 -3058.44363835 -3 3 1 1 5 0.88909491 -2915.16010220 0.06427192 -3 3 1 1 6 -1559.38677415 3076.86825574 -3059.94331651 -3 3 1 1 7 0.53559934 -573.32696035 0.01071199 -3 3 1 1 8 -1559.40819813 3076.83611978 3059.93260452 -3 3 1 2 1 -11784.42812888 -12.51160064 0.07498391 -3 3 1 2 2 3074.94009810 1560.47939681 3058.25082259 -3 3 1 2 3 2969.15922793 7.15560722 -0.06427192 -3 3 1 2 4 3074.86511419 1560.58651668 -3058.10085477 -3 3 1 2 5 -573.27340042 -0.72841511 -0.06427192 -3 3 1 2 6 3076.91110368 -1557.95136791 3060.11470830 -3 3 1 2 7 -2915.22437412 1.00692676 -0.05355993 -3 3 1 2 8 3076.97537560 -1557.95136791 -3060.11470830 -3 3 1 3 1 -0.06427192 0.06427192 11.24758620 -3 3 1 3 2 0.10711987 -0.06427192 -9480.12978896 -3 3 1 3 3 0.02142397 -0.06427192 11.16189030 -3 3 1 3 4 -0.07498391 -0.00000000 -9480.06551704 -3 3 1 3 5 0.01071199 0.02142397 3.92058719 -3 3 1 3 6 0.17139179 0.12854384 9465.28297519 -3 3 1 3 7 -0.02142397 -0.02142397 3.11718817 -3 3 1 3 8 -0.21423974 -0.12854384 9465.26155121 -3 1 2 1 1 -0.85695895 -539.56277779 1559.91166151 -3 1 2 1 2 -74179.69484669 -72096.74900310 72069.39058868 -3 1 2 1 3 74175.97778725 72096.19197979 -72067.48385502 -3 1 2 1 4 0.37491954 538.98433050 -1559.15111044 -3 1 2 1 5 9477.31253642 3068.17012241 -3066.67044425 -3 1 2 1 6 0.16067980 1560.65078860 -539.21999421 -3 1 2 1 7 -0.25708768 -1561.43276364 539.66989766 -3 1 2 1 8 -9473.05987764 -3066.27410074 3063.74607184 -3 1 2 2 1 -0.57844729 538.99504249 3074.40449876 -3 1 2 2 2 -72093.98531050 -67136.92769833 80911.73939240 -3 1 2 2 3 67125.08024087 72103.30473906 -80912.20000783 -3 1 2 2 4 -538.69510686 0.74983908 -3074.38307479 -3 1 2 2 5 -1.98171757 -1559.53674197 3080.25324358 -3 1 2 2 6 1557.35149665 1.58537405 -3077.14676739 -3 1 2 2 7 889.24487662 -3060.01830042 90.39845705 -3 1 2 2 8 3063.49969614 -888.05584608 -93.03360582 -3 1 2 3 1 -893.33685560 82.97505016 -3055.85133753 -3 1 2 3 2 72063.69181167 80909.16851555 -67096.30784418 -3 1 2 3 3 -67086.14216866 -80898.70290440 72061.14235880 -3 1 2 3 4 -1559.26894230 -3074.64016247 0.59987126 -3 1 2 3 5 2.18524532 3079.46055655 -1557.26580076 -3 1 2 3 6 536.02782213 -3081.17447445 -0.34278358 -3 1 2 3 7 2.63514877 3077.88589449 536.89549306 -3 1 2 3 8 -3065.72778941 -94.97247544 -888.66642933 -3 2 2 1 1 537.89170784 -0.31064762 3074.43663472 -3 2 2 1 2 -67119.38146386 -72106.87183068 80913.15337466 -3 2 2 1 3 72091.97145697 67135.51371607 -80913.99962162 -3 2 2 1 4 1.34971034 -538.10594758 -3073.52611584 -3 2 2 1 5 -3068.60931387 888.49503754 94.60826789 -3 2 2 1 6 -887.97015019 3063.41400025 -92.91577396 -3 2 2 1 7 -1556.79447333 0.47132742 3075.22932175 -3 2 2 1 8 1.49967816 1557.42648056 -3076.98608759 -3 2 2 2 1 -538.64154692 0.42847947 1558.26201553 -3 2 2 2 2 -72107.65380572 -74174.14603750 72072.33638507 -3 2 2 2 3 72109.41057156 74175.38862797 -72075.34645337 -3 2 2 2 4 538.97361851 0.38563153 -1559.19395839 -3 2 2 2 5 -1559.71884575 0.36420755 538.92005858 -3 2 2 2 6 -3066.30623670 -9473.01702969 3063.82105575 -3 2 2 2 7 3063.13548859 9470.58540868 -3059.57910895 -3 2 2 2 8 1560.69363655 0.09640788 -539.20928222 -3 2 2 3 1 83.29640977 -893.59394329 -3055.82991356 -3 2 2 3 2 80911.27877696 72070.39751544 -67094.63677423 -3 2 2 3 3 -80900.57750210 -67090.39482744 72062.44922120 -3 2 2 3 4 -3074.67229843 -1559.30107826 0.47132742 -3 2 2 3 5 3080.88525081 0.10711987 536.28490981 -3 2 2 3 6 -94.95105147 -3065.77063736 -888.68785331 -3 2 2 3 7 3075.88275295 2.62443678 -1559.79382965 -3 2 2 3 8 -3081.13162650 535.98497418 -0.35349557 -3 3 2 1 1 1558.74405494 3074.40449876 -0.32135961 -3 3 2 1 2 67084.16045109 80902.76274741 -72062.98482054 -3 3 2 1 3 -72067.52670297 -80910.57178583 67096.80059558 -3 3 2 1 4 893.76533507 -83.21071387 3055.74421766 -3 3 2 1 5 3067.72021896 95.22956312 888.02371012 -3 3 2 1 6 -1.11404663 -3079.20346887 -536.39202968 -3 3 2 1 7 -534.72095973 3079.14990894 -0.26779967 -3 3 2 1 8 -1.02835074 -3078.63573357 1559.50460601 -3 3 2 2 1 3074.59731452 1560.11518926 -0.54631133 -3 3 2 2 2 80902.79488338 67095.00098179 -72062.32067736 -3 3 2 2 3 -80911.81437631 -72074.38237455 67095.25806947 -3 3 2 2 4 -83.22142586 893.78675905 3055.74421766 -3 3 2 2 5 3081.30301829 -535.98497418 -0.38563153 -3 3 2 2 6 -3078.64644555 -1.04977471 1559.49389402 -3 3 2 2 7 94.24406033 3063.59610402 889.20202868 -3 3 2 2 8 -3079.18204490 -1.11404663 -536.40274167 -3 3 2 3 1 3055.48712998 3055.31573819 -9478.86577451 -3 3 2 3 2 -72065.34145765 -72064.62375453 74112.07007368 -3 3 2 3 3 72065.08436997 72064.91297818 -74112.16648157 -3 3 2 3 4 -3055.92632144 -3055.93703342 9477.79457583 -3 3 2 3 5 -1555.29479517 -538.92005858 -1.64964598 -3 3 2 3 6 538.24520341 1556.45168975 2.59230082 -3 3 2 3 7 -538.77009076 -1555.44476299 -2.49589294 -3 3 2 3 8 1556.47311373 538.24520341 2.63514877 -3 1 3 1 1 0.64271921 -0.07498391 -11.75104958 -3 1 3 1 2 74172.21787986 67121.29890951 -67081.84666193 -3 1 3 1 3 3.37427586 -0.42847947 107.03417264 -3 1 3 1 4 -74176.08490712 -67120.94541395 -67081.37533451 -3 1 3 1 5 3.62065156 0.08569589 9.85502790 -3 1 3 1 6 -74114.57667861 67021.68814376 67030.98614835 -3 1 3 1 7 0.74983908 0.03213596 -4.16696289 -3 1 3 1 8 74110.19547598 -67021.61315986 67031.22181206 -3 1 3 2 1 -0.08569589 -0.20352775 -11785.57431147 -3 1 3 2 2 72096.29909966 72106.66830293 -80899.92407090 -3 1 3 2 3 -1.83174975 -3.29929195 329268.90820573 -3 1 3 2 4 -72094.36023004 -72104.91153709 -80898.81002427 -3 1 3 2 5 0.08569589 -0.12854384 2960.08617506 -3 1 3 2 6 72011.81365935 -71998.67005148 -80802.48783848 -3 1 3 2 7 -0.70699113 -0.91051888 2960.71818229 -3 1 3 2 8 -72011.28877199 72001.30520024 -80802.65923027 -3 1 3 3 1 4.69185024 2970.58392218 1.94958161 -3 1 3 3 2 -72069.49770855 -80912.14644790 72059.73908853 -3 1 3 3 3 111.45822321 329278.05624250 2.35663711 -3 1 3 3 4 -72068.66217357 -80911.19308107 -72063.00624452 -3 1 3 3 5 -8.89094909 2954.21600627 -0.29993563 -3 1 3 3 6 72017.66240417 -80799.61702601 -72002.26927906 -3 1 3 3 7 -1.58537405 -11781.05385302 0.28922365 -3 1 3 3 8 72014.75945573 -80798.96359481 72001.43374408 -3 2 3 1 1 -0.04284795 -0.21423974 -11785.60644743 -3 2 3 1 2 72094.69230163 72105.02936894 -80898.76717632 -3 2 3 1 3 0.84624696 -0.53559934 329269.31526123 -3 2 3 1 4 -72094.91725335 -72105.44713643 -80898.98141606 -3 2 3 1 5 0.05355993 -0.10711987 2960.10759904 -3 2 3 1 6 72012.35997067 -71999.78409811 -80803.40906935 -3 2 3 1 7 -0.70699113 -0.97479080 2960.64319838 -3 2 3 1 8 -72012.31712273 72001.85151157 -80803.26981352 -3 2 3 2 1 0.49275140 0.17139179 -6.94136748 -3 2 3 2 2 67130.41481032 74170.00049859 -67084.05333122 -3 2 3 2 3 5.58094515 0.98550279 133.83556374 -3 2 3 2 4 -67134.68889308 -74174.48882108 -67084.07475520 -3 2 3 2 5 3.82417931 0.29993563 -15.36098915 -3 2 3 2 6 -67016.97486955 74116.72978797 67028.92944688 -3 2 3 2 7 -1.19974253 0.93194286 -1.14618259 -3 2 3 2 8 67012.69007481 -74114.59810258 67028.84375098 -3 2 3 3 1 2972.70489558 6.17010443 0.10711987 -3 2 3 3 2 -80912.37139962 -72074.20027078 72059.29989706 -3 2 3 3 3 329275.20685400 138.95589346 0.66414318 -3 2 3 3 4 -80911.60013657 -72073.28975189 -72058.33581825 -3 2 3 3 5 -11779.81126255 -10.71198685 -0.06427192 -3 2 3 3 6 -80800.24903323 72005.41860319 72001.30520024 -3 2 3 3 7 2957.23678656 -0.95336683 -0.65343120 -3 2 3 3 8 -80800.98816032 72008.40724753 -72002.08717528 -3 3 3 1 1 5.93444072 2971.92292054 0.04284795 -3 3 3 1 2 -72069.26204484 -80911.93220816 72059.47128885 -3 3 3 1 3 110.68696015 329276.19235679 0.68556716 -3 3 3 1 4 -72068.94068523 -80911.53586465 -72059.10708130 -3 3 3 1 5 -9.04091690 2954.38739806 -0.66414318 -3 3 3 1 6 72017.40531648 -80799.35993832 -72002.01219137 -3 3 3 1 7 -1.39255829 -11781.28951673 -0.06427192 -3 3 3 1 8 72014.50236805 -80798.67437116 72001.34804819 -3 3 3 2 1 2972.61919968 6.15939244 0.19281576 -3 3 3 2 2 -80912.32855167 -72074.10386290 72059.29989706 -3 3 3 2 3 329275.39966976 139.19155717 0.85695895 -3 3 3 2 4 -80911.87864823 -72073.58968753 -72058.67860183 -3 3 3 2 5 -11779.85411049 -10.71198685 -0.14996782 -3 3 3 2 6 -80800.23832124 72005.37575525 72001.34804819 -3 3 3 2 7 2957.27963451 -0.98550279 -0.67485517 -3 3 3 2 8 -80801.03100827 72008.36439958 -72002.09788727 -3 3 3 3 1 0.62129524 0.04284795 1.09262266 -3 3 3 3 2 67094.78674205 67096.50065995 -74104.17533937 -3 3 3 3 3 3.98485911 0.59987126 -4.52045845 -3 3 3 3 4 -67098.84658507 -67098.38596963 -74104.02537156 -3 3 3 3 5 3.72777142 0.23566371 6.62000788 -3 3 3 3 6 -67033.97479269 67032.44297857 74102.71850916 -3 3 3 3 7 -0.00000000 0.89980690 -0.86767094 -3 3 3 3 8 67029.82925377 -67032.30372274 74103.00773281 -3 1 4 1 1 0.94265484 539.35925004 1559.84738959 -3 1 4 1 2 -0.34278358 -538.98433050 -1559.19395839 -3 1 4 1 3 -74176.69549037 -72097.19890655 -72068.66217357 -3 1 4 1 4 74179.78054258 72098.95567239 72069.56198047 -3 1 4 1 5 -9477.41965629 -3068.34151420 -3066.54190041 -3 1 4 1 6 9473.03845367 3066.28481272 3063.75678383 -3 1 4 1 7 0.89980690 1560.53295675 540.29119290 -3 1 4 1 8 -0.08569589 -1560.72577251 -539.16643428 -3 1 4 2 1 0.57844729 -539.01646646 3074.45805869 -3 1 4 2 2 538.44873116 -0.42847947 -3074.42592273 -3 1 4 2 3 -67122.94855549 -72105.46856040 -80912.30712770 -3 1 4 2 4 72093.73893480 67137.39902575 80911.92149617 -3 1 4 2 5 1.99242955 1559.55816594 3080.27466756 -3 1 4 2 6 -3064.30309516 888.90209304 -92.48729449 -3 1 4 2 7 -889.26630060 3060.01830042 90.38774507 -3 1 4 2 8 -1558.16560765 -0.77126305 -3077.73592667 -3 1 4 3 1 -893.31543163 82.95362619 3055.88347349 -3 1 4 3 2 -1559.40819813 -3074.46877068 -0.42847947 -3 1 4 3 3 -67086.38854436 -80901.01669356 -72061.07808688 -3 1 4 3 4 72064.54877062 80910.14330636 67097.05768326 -3 1 4 3 5 2.20666929 3079.46055655 1557.26580076 -3 1 4 3 6 -3065.64209351 -94.80108365 888.60215741 -3 1 4 3 7 2.63514877 3077.89660647 -536.89549306 -3 1 4 3 8 535.36367894 -3080.22110762 -0.29993563 -3 2 4 1 1 -537.87028387 0.28922365 3074.45805869 -3 2 4 1 2 -1.02835074 537.81672393 -3073.52611584 -3 2 4 1 3 -72094.59589375 -67133.64983035 -80914.49237302 -3 2 4 1 4 67120.01347109 72106.98966253 80913.54971818 -3 2 4 1 5 3068.57717791 -888.49503754 94.60826789 -3 2 4 1 6 -0.65343120 -1558.29415149 -3077.53239892 -3 2 4 1 7 1556.83732128 -0.43919146 3075.20789777 -3 2 4 1 8 888.79497318 -3064.20668728 -92.27305475 -3 2 4 2 1 539.00575447 -0.58915928 1558.46554328 -3 2 4 2 2 -539.00575447 -0.33207159 -1559.20467038 -3 2 4 2 3 -72107.23603823 -74173.80325392 -72073.71823137 -3 2 4 2 4 72102.90839554 74174.06034160 72071.96146553 -3 2 4 2 5 1561.55059550 -1.69249392 537.63462016 -3 2 4 2 6 -1560.68292456 -0.12854384 -539.15572229 -3 2 4 2 7 -3062.74985706 -9470.44615285 -3059.72907677 -3 2 4 2 8 3066.30623670 9473.01702969 3063.77820780 -3 2 4 3 1 83.31783374 -893.60465527 3055.82991356 -3 2 4 3 2 -3074.46877068 -1559.37606217 -0.42847947 -3 2 4 3 3 -80902.91271523 -67090.58764320 -72062.83485273 -3 2 4 3 4 80912.40353558 72071.06165863 67095.81509279 -3 2 4 3 5 3080.87453882 0.08569589 -536.26348584 -3 2 4 3 6 -3080.22110762 535.29940702 -0.27851166 -3 2 4 3 7 3075.90417692 2.62443678 1559.81525363 -3 2 4 3 8 -94.82250762 -3065.60995755 888.58073344 -3 3 4 1 1 1558.67978302 3074.40449876 0.28922365 -3 3 4 1 2 893.42255150 -83.06074606 -3055.91560945 -3 3 4 1 3 -72063.40258803 -80910.85029749 -67097.10053121 -3 3 4 1 4 67082.62863697 80901.74510866 72062.02074173 -3 3 4 1 5 3067.73093095 95.27241107 -887.95943820 -3 3 4 1 6 -2.84938850 -3077.33958316 -1558.14418368 -3 3 4 1 7 -534.67811179 3079.11777297 0.28922365 -3 3 4 1 8 -1.41398226 -3079.41770861 536.58484545 -3 3 4 2 1 3074.55446658 1560.07234131 0.56773530 -3 3 4 2 2 -83.06074606 893.41183951 -3055.93703342 -3 3 4 2 3 -80911.84651227 -72070.09757981 -67095.21522152 -3 3 4 2 4 80901.59514085 67093.32991184 72061.46371841 -3 3 4 2 5 3081.32444227 -535.98497418 0.32135961 -3 3 4 2 6 -3079.41770861 -1.45683021 536.60626942 -3 3 4 2 7 94.24406033 3063.60681601 -889.22345265 -3 3 4 2 8 -3077.31815918 -2.86010049 -1558.18703163 -3 3 4 3 1 -3055.42285806 -3055.26217825 -9478.83363855 -3 3 4 3 2 3056.06557727 3056.03344131 9478.00881557 -3 3 4 3 3 -72067.38744714 -72067.22676734 -74112.38072130 -3 3 4 3 4 72067.00181561 72066.24126455 74113.70900767 -3 3 4 3 5 1555.31621915 538.87721063 -1.69249392 -3 3 4 3 6 -1555.43405100 -538.70581884 1.88530969 -3 3 4 3 7 538.68439487 1555.42333902 -2.52802890 -3 3 4 3 8 -538.68439487 -1555.43405100 1.92815763 -3 1 5 1 1 -0.02142397 0.01071199 -0.12854384 -3 1 5 1 2 9474.64525169 -0.81411100 0.92123087 -3 1 5 1 3 0.09640788 -0.10711987 -8.67670935 -3 1 5 1 4 -9474.69881163 0.89980690 0.89980690 -3 1 5 1 5 0.08569589 0.02142397 13.38998357 -3 1 5 1 6 -9456.28490623 -0.00000000 -3.08505221 -3 1 5 1 7 0.02142397 0.03213596 -0.16067980 -3 1 5 1 8 9456.17778636 0.07498391 -3.09576420 -3 1 5 2 1 0.12854384 0.07498391 -573.11272061 -3 1 5 2 2 3069.58410468 -1560.52224476 3080.36036345 -3 1 5 2 3 0.99621478 -0.64271921 2958.99355240 -3 1 5 2 4 -3069.50912077 1560.52224476 3080.42463537 -3 1 5 2 5 0.88909491 0.55702332 -11775.53717979 -3 1 5 2 6 3057.22247185 1553.23809370 3071.89789384 -3 1 5 2 7 0.23566371 -0.11783186 -2914.66735081 -3 1 5 2 8 -3059.40771717 -1553.18453376 3071.72650205 -3 1 5 3 1 1.99242955 -2913.89608775 -0.04284795 -3 1 5 3 2 -3068.74856970 3081.19589842 -1558.05848778 -3 1 5 3 3 14.17195861 2960.92171004 -0.04284795 -3 1 5 3 4 -3068.69500977 3081.19589842 1558.37984739 -3 1 5 3 5 16.69998750 -11774.25174137 0.02142397 -3 1 5 3 6 3053.10906890 3069.81976839 1560.43654886 -3 1 5 3 7 -1.54252611 -574.69809467 -0.03213596 -3 1 5 3 8 3052.95910108 3069.83048037 -1560.50082079 -3 2 5 1 1 -0.12854384 -0.13925583 -2915.42790187 -3 2 5 1 2 -3069.24132110 -1560.80075642 3081.41013816 -3 2 5 1 3 -0.89980690 0.57844729 -11785.62787141 -3 2 5 1 4 3069.29488103 1560.82218039 3081.23874637 -3 2 5 1 5 -0.93194286 -0.66414318 2965.42074452 -3 2 5 1 6 -3054.05172374 1558.07991176 3073.61181173 -3 2 5 1 7 -0.17139179 0.07498391 -574.35531109 -3 2 5 1 8 3056.21554508 -1558.02635182 3073.75106756 -3 2 5 2 1 0.23566371 0.17139179 0.81411100 -3 2 5 2 2 890.27322736 0.89980690 -0.25708768 -3 2 5 2 3 0.91051888 -0.77126305 -8.41962167 -3 2 5 2 4 -890.25180339 -0.89980690 -0.08569589 -3 2 5 2 5 0.92123087 0.66414318 12.61872051 -3 2 5 2 6 -889.45911636 -0.55702332 -2.31378916 -3 2 5 2 7 0.17139179 -0.08569589 0.37491954 -3 2 5 2 8 887.31671899 0.54631133 -2.52802890 -3 2 5 3 1 -3372.09061341 1.34971034 0.10711987 -3 2 5 3 2 94.02982060 538.23449142 536.43487763 -3 2 5 3 3 2959.25064009 -12.23308899 0.64271921 -3 2 5 3 4 93.96554868 538.25591539 -536.62769339 -3 2 5 3 5 2962.47494813 13.75419112 -0.59987126 -3 2 5 3 6 89.53078612 -539.51992984 536.19921392 -3 2 5 3 7 -2914.66735081 -0.28922365 -0.01071199 -3 2 5 3 8 87.36696477 -539.57348978 -536.02782213 -3 3 5 1 1 0.72841511 -573.03773671 0.17139179 -3 3 5 1 2 3069.26274507 3081.79576969 -1556.45168975 -3 3 5 1 3 -8.98735697 -11786.31343857 0.68556716 -3 3 5 1 4 3069.31630500 3081.62437790 1556.40884181 -3 3 5 1 5 -8.90166107 2963.10695536 -0.66414318 -3 3 5 1 6 -3059.15062948 3074.55446658 1557.39434460 -3 3 5 1 7 -0.94265484 -2915.98492519 -0.07498391 -3 3 5 1 8 -3061.35729877 3074.46877068 -1557.36220864 -3 3 5 2 1 -2915.22437412 -0.32135961 -0.02142397 -3 3 5 2 2 94.71538776 -536.22063789 -538.29876334 -3 3 5 2 3 2957.64384206 -11.84745746 -0.64271921 -3 3 5 2 4 96.90063307 -536.28490981 538.42730718 -3 3 5 2 5 2960.80387818 16.02513233 0.66414318 -3 3 5 2 6 89.70217791 534.78523165 -537.78458797 -3 3 5 2 7 -3374.31870667 -1.07119869 0.09640788 -3 3 5 2 8 89.61648201 534.69953576 537.81672393 -3 3 5 3 1 0.17139179 -0.10711987 2.88152446 -3 3 5 3 2 888.55930946 0.08569589 -2.03527750 -3 3 5 3 3 0.89980690 0.64271921 10.13353956 -3 3 5 3 4 -890.69099485 -0.08569589 -2.27094121 -3 3 5 3 5 0.83553497 -0.66414318 -12.12596912 -3 3 5 3 6 -891.21588220 0.08569589 2.91366042 -3 3 5 3 7 0.17139179 0.05355993 -2.45304499 -3 3 5 3 8 891.32300207 -0.09640788 2.88152446 -3 1 6 1 1 -1.54252611 -536.68125333 -1558.99043064 -3 1 6 1 2 -0.04284795 1558.21916759 536.16707796 -3 1 6 1 3 -74117.21182737 72014.13816049 72010.47466099 -3 1 6 1 4 9473.78829275 -3064.07814343 -3064.99937430 -3 1 6 1 5 -9460.46258110 3056.06557727 3053.38758055 -3 1 6 1 6 74104.98945037 -72006.46837791 -71995.75639105 -3 1 6 1 7 -0.64271921 -1556.90159320 -538.74866679 -3 1 6 1 8 0.98550279 535.57791868 1558.62622309 -3 1 6 2 1 -0.44990345 -537.24898863 3076.66472799 -3 1 6 2 2 1562.06477087 1.86388571 -3081.60295392 -3 1 6 2 3 67024.11976478 -72004.13316477 -80798.58867527 -3 1 6 2 4 3065.93131716 889.26630060 -94.95105147 -3 1 6 2 5 -0.58915928 1552.85246217 3069.32701699 -3 1 6 2 6 -72004.77588398 67036.04220615 80814.39956786 -3 1 6 2 7 889.69478007 3061.36801076 90.54842487 -3 1 6 2 8 -536.00639816 -0.05355993 -3076.03272076 -3 1 6 3 1 888.43076562 91.43751978 3061.92503408 -3 1 6 3 2 -539.92698534 -3079.48198053 0.92123087 -3 1 6 3 3 67030.68621272 -80802.29502272 -72004.69018809 -3 1 6 3 4 3064.37807907 -92.42302257 889.48054033 -3 1 6 3 5 -1.83174975 3072.69058086 1561.12211602 -3 1 6 3 6 -72000.35183341 80809.42920596 67027.49404064 -3 1 6 3 7 0.72841511 3077.75735064 -536.42416564 -3 1 6 3 8 1557.84424805 -3077.17890335 0.23566371 -3 2 6 1 1 537.87028387 0.08569589 3076.40764030 -3 2 6 1 2 -889.22345265 -3065.89918120 -94.94033948 -3 2 6 1 3 72016.49479760 -67015.92509484 -80800.02408151 -3 2 6 1 4 -1.84246174 -1562.02192292 -3081.58152995 -3 2 6 1 5 -3053.48398844 -891.62293770 85.99583046 -3 2 6 1 6 -67052.13161040 71998.99141108 80813.84254455 -3 2 6 1 7 -1557.71570420 0.36420755 3076.20411255 -3 2 6 1 8 0.02142397 536.01711014 -3076.08628070 -3 2 6 2 1 537.39895645 -0.02142397 -1560.56509271 -3 2 6 2 2 3064.72086264 -9472.85634989 -3065.58853358 -3 2 6 2 3 -72000.95170468 74114.99444610 72002.82630238 -3 2 6 2 4 -1558.27272752 0.23566371 535.98497418 -3 2 6 2 5 1557.82282407 -0.85695895 -540.14122508 -3 2 6 2 6 71996.82758974 -74107.02472788 -71992.24285936 -3 2 6 2 7 -3061.95717004 9466.34346188 3060.99309122 -3 2 6 2 8 -535.49222279 -0.82482299 1558.73334295 -3 2 6 3 1 91.03046428 888.21652588 -3061.74293030 -3 2 6 3 2 -92.85150204 3063.33901634 -888.75212523 -3 2 6 3 3 -80804.00894062 67030.08634146 72004.54022027 -3 2 6 3 4 -3078.46434178 -539.39138600 -0.17139179 -3 2 6 3 5 3073.79391551 -2.31378916 536.32775776 -3 2 6 3 6 80810.84318823 -71997.40603703 -67030.32200517 -3 2 6 3 7 3076.76113587 -0.42847947 -1559.37606217 -3 2 6 3 8 -3077.12534342 1557.79068811 -0.36420755 -3 3 6 1 1 -1559.85810157 3077.32887117 -0.18210378 -3 3 6 1 2 -1.37113432 -3078.00372634 538.37374725 -3 3 6 1 3 72014.83443964 -80797.34608479 -67034.79961567 -3 3 6 1 4 -2.93508440 -3080.29609153 -1556.92301718 -3 3 6 1 5 -3058.51862226 89.83072175 -892.22280897 -3 3 6 1 6 -67037.15625278 80804.56596393 72006.40410598 -3 3 6 1 7 536.04924610 3077.12534342 -0.65343120 -3 3 6 1 8 -890.85167465 -93.22642158 -3060.23254015 -3 3 6 2 1 3077.03964753 -1558.29415149 0.54631133 -3 3 6 2 2 -3080.44605934 -2.87081248 1556.85874526 -3 3 6 2 3 -80795.49291107 72009.21064654 67037.41334046 -3 3 6 2 4 -3078.90353324 -1.94958161 -538.98433050 -3 3 6 2 5 3073.93317134 534.22820834 -0.04284795 -3 3 6 2 6 80805.85140235 -67027.64400845 -72006.31841009 -3 3 6 2 7 91.37324786 -3061.65723440 890.20895544 -3 3 6 2 8 -93.40852536 -890.94808253 3060.32894803 -3 3 6 3 1 -3063.00694475 3064.00315953 9468.50728323 -3 3 6 3 2 -536.37060571 1559.31179024 2.42090903 -3 3 6 3 3 -71999.58057036 72000.59820911 74099.69772887 -3 3 6 3 4 -1559.31179024 536.32775776 2.39948506 -3 3 6 3 5 1559.54745396 -535.96355021 3.94201116 -3 3 6 3 6 71998.74503538 -72005.93277856 -74113.02344051 -3 3 6 3 7 538.57727500 -1556.96586512 1.48896617 -3 3 6 3 8 3061.33587480 -3061.36801076 -9465.39009505 -3 1 7 1 1 0.06427192 -0.04284795 0.64271921 -3 1 7 1 2 -0.57844729 889.00921291 2.39948506 -3 1 7 1 3 0.08569589 0.06427192 -2.20666929 -3 1 7 1 4 0.55702332 -889.05206086 2.14239737 -3 1 7 1 5 -0.06427192 0.10711987 -1.92815763 -3 1 7 1 6 -0.83553497 888.60215741 0.21423974 -3 1 7 1 7 0.02142397 -0.04284795 -1.92815763 -3 1 7 1 8 0.85695895 -888.62358139 0.24637570 -3 1 7 2 1 0.06427192 0.18210378 -2915.08511829 -3 1 7 2 2 -1561.33635576 -3058.27224656 3077.57524687 -3 1 7 2 3 -0.62129524 0.87838292 -11783.14269046 -3 1 7 2 4 1561.35777973 3058.22939861 3077.85375853 -3 1 7 2 5 -0.09640788 0.10711987 -574.86948646 -3 1 7 2 6 -1557.37292062 3060.80027546 3077.38243110 -3 1 7 2 7 0.66414318 0.92123087 2962.94627555 -3 1 7 2 8 1557.39434460 -3063.01765673 3077.44670303 -3 1 7 3 1 0.70699113 -3372.07990142 -0.01071199 -3 1 7 3 2 539.79844150 91.80172733 536.58484545 -3 1 7 3 3 -3.94201116 2960.30041480 0.04284795 -3 1 7 3 4 539.83057746 91.84457528 -536.71338929 -3 1 7 3 5 -0.16067980 -2914.49595902 -0.04284795 -3 1 7 3 6 -538.06309963 89.42366625 -536.02782213 -3 1 7 3 7 -0.25708768 2963.38546701 -0.07498391 -3 1 7 3 8 -537.93455579 89.63790599 536.14565398 -3 2 7 1 1 -0.08569589 -0.19281576 -573.42336823 -3 2 7 1 2 -1556.45168975 3063.52112012 3075.66851321 -3 2 7 1 3 0.68556716 -0.96407882 2957.90092975 -3 2 7 1 4 1556.47311373 -3063.56396806 3075.96844884 -3 2 7 1 5 0.07498391 -0.17139179 -2914.53880696 -3 2 7 1 6 -1557.33007268 -3061.10021109 3076.35408037 -3 2 7 1 7 -0.62129524 -0.88909491 -11774.32672528 -3 2 7 1 8 1557.15868089 3063.25332045 3076.33265639 -3 2 7 2 1 -0.02142397 -0.03213596 0.66414318 -3 2 7 2 2 -0.08569589 9468.73223495 2.97793235 -3 2 7 2 3 -0.03213596 -0.02142397 -3.83489129 -3 2 7 2 4 0.12854384 -9468.68938700 2.78511658 -3 2 7 2 5 0.04284795 0.12854384 -0.32135961 -3 2 7 2 6 0.66414318 9468.71081098 -0.94265484 -3 2 7 2 7 -0.02142397 0.02142397 -0.93194286 -3 2 7 2 8 -0.79268703 -9468.67867502 -0.98550279 -3 2 7 3 1 -2913.78896788 0.06427192 0.02142397 -3 2 7 3 2 3074.98294605 -3058.85069385 -1559.68670978 -3 2 7 3 3 2960.15044698 -1.92815763 0.64271921 -3 2 7 3 4 3075.04721797 -3058.87211782 1559.45104607 -3 2 7 3 5 -574.76236659 0.32135961 -0.06427192 -3 2 7 3 6 3076.13984063 3060.54318777 -1559.36535018 -3 2 7 3 7 -11773.78041395 -4.17767487 -0.74983908 -3 2 7 3 8 3076.07556871 3062.82484097 1559.31179024 -3 3 7 1 1 0.85695895 -2914.62450286 0.04284795 -3 3 7 1 2 -534.87092755 92.03739104 -538.27733937 -3 3 7 1 3 -1.67106995 2960.27899083 -0.04284795 -3 3 7 1 4 -534.94591146 91.97311912 538.34161129 -3 3 7 1 5 -1.04977471 -3373.78310733 0.02142397 -3 3 7 1 6 535.89927829 90.40916904 537.91313182 -3 3 7 1 7 -0.00000000 2963.53543483 -0.02142397 -3 3 7 1 8 535.89927829 90.32347315 -537.87028387 -3 3 7 2 1 -573.45550419 1.02835074 -0.13925583 -3 3 7 2 2 3079.56767642 3062.94267283 -1556.38741783 -3 3 7 2 3 -11783.83896960 -0.87838292 -0.70699113 -3 3 7 2 4 3079.59981238 3062.98552077 1556.15175412 -3 3 7 2 5 -2915.63142962 -0.53559934 -0.00000000 -3 3 7 2 6 3076.56832010 -3061.07878711 -1557.18010486 -3 3 7 2 7 2960.57892646 -0.73912709 0.62129524 -3 3 7 2 8 3076.58974408 -3063.37115230 1557.19081685 -3 3 7 3 1 -0.02142397 -0.03213596 2.19595730 -3 3 7 3 2 0.19281576 890.91594657 -2.84938850 -3 3 7 3 3 -0.05355993 -0.00000000 4.77754614 -3 3 7 3 4 -0.10711987 -890.74455478 -2.78511658 -3 3 7 3 5 0.02142397 0.02142397 -2.48518095 -3 3 7 3 6 -0.14996782 888.96636496 1.97100558 -3 3 7 3 7 0.04284795 -0.01071199 -2.77440459 -3 3 7 3 8 0.08569589 -888.95565298 2.00314154 -3 1 8 1 1 1.22116650 536.49914955 -1559.18324640 -3 1 8 1 2 -9472.84563790 3064.68872668 -3065.65280550 -3 1 8 1 3 74113.44120800 -72013.13123373 72009.44631025 -3 1 8 1 4 0.21423974 -1558.31557547 535.98497418 -3 1 8 1 5 9458.56655943 -3057.37243966 3054.60874706 -3 1 8 1 6 -0.85695895 -535.44937484 1558.82975084 -3 1 8 1 7 0.23566371 1557.07298499 -538.60941096 -3 1 8 1 8 -74099.91196861 72006.06132240 -71995.43503145 -3 1 8 2 1 0.23566371 537.18471671 3076.51476017 -3 1 8 2 2 -3065.85633325 -889.27701258 -94.91891551 -3 1 8 2 3 -67025.19096347 72004.77588398 -80799.06000269 -3 1 8 2 4 -1562.04334689 -1.84246174 -3081.53868200 -3 1 8 2 5 -0.31064762 -1553.47375741 3069.92688826 -3 1 8 2 6 536.00639816 0.06427192 -3076.07556871 -3 1 8 2 7 -889.84474789 -3061.26089089 90.63412076 -3 1 8 2 8 72006.98255327 -67036.17074999 80814.66736753 -3 1 8 3 1 888.38791767 91.38395984 -3061.93574606 -3 1 8 3 2 3063.32830435 -92.83007807 -888.75212523 -3 1 8 3 3 67032.96786592 -80804.43742009 72004.60449219 -3 1 8 3 4 -539.45565792 -3078.47505376 -0.21423974 -3 1 8 3 5 -1.83174975 3072.75485278 -1561.20781192 -3 1 8 3 6 1557.79068811 -3077.12534342 -0.47132742 -3 1 8 3 7 0.74983908 3077.77877462 536.42416564 -3 1 8 3 8 -72001.94791945 80810.93959611 -67028.77947906 -3 2 8 1 1 -537.89170784 -0.11783186 3076.42906427 -3 2 8 1 2 1.79961379 1562.04334689 -3081.61366591 -3 2 8 1 3 -72016.45194965 67015.98936676 -80800.19547330 -3 2 8 1 4 889.26630060 3065.87775722 -94.95105147 -3 2 8 1 5 3053.47327645 891.66578565 85.93155854 -3 2 8 1 6 -0.04284795 -536.00639816 -3076.05414473 -3 2 8 1 7 1557.71570420 -0.34278358 3076.19340056 -3 2 8 1 8 67052.13161040 -71999.02354704 80814.09963223 -3 2 8 2 1 -537.46322837 -0.18210378 -1560.51153277 -3 2 8 2 2 1558.16560765 -0.06427192 536.11351802 -3 2 8 2 3 72001.62655985 -74118.18661818 72003.29762980 -3 2 8 2 4 -3064.07814343 9473.76686877 -3064.91367841 -3 2 8 2 5 -1557.73712818 0.66414318 -540.16264905 -3 2 8 2 6 535.57791868 0.96407882 1558.59408713 -3 2 8 2 7 3061.29302685 -9467.27540474 3060.36108400 -3 2 8 2 8 -71997.44888498 74110.18476400 -71992.83201864 -3 2 8 3 1 91.15900812 888.32364575 3061.85005017 -3 2 8 3 2 -3079.48198053 -539.83057746 0.89980690 -3 2 8 3 3 -80800.89175244 67027.19410501 -72003.70468530 -3 2 8 3 4 -92.35875065 3064.35665509 889.48054033 -3 2 8 3 5 3074.72585837 -1.64964598 -536.92762902 -3 2 8 3 6 -3077.16819137 1557.82282407 0.27851166 -3 2 8 3 7 3076.97537560 -0.46061543 1559.29036627 -3 2 8 3 8 80807.07256886 -71995.79923900 67028.83303900 -3 3 8 1 1 -1559.83667760 3077.32887117 0.14996782 -3 3 8 1 2 -2.84938850 -3080.47819531 1556.83732128 -3 3 8 1 3 72014.72731977 -80795.37507921 67034.92815952 -3 3 8 1 4 -1.97100558 -3078.90353324 -539.02717845 -3 3 8 1 5 -3058.50791027 89.78787380 892.22280897 -3 3 8 1 6 -890.95879452 -93.45137331 3060.37179598 -3 3 8 1 7 536.02782213 3077.09320746 0.65343120 -3 3 8 1 8 -67036.74919728 80803.78398889 -72005.93277856 -3 3 8 2 1 3077.21103932 -1558.18703163 -0.43919146 -3 3 8 2 2 -3077.98230237 -1.36042233 538.37374725 -3 3 8 2 3 -80796.64980565 72008.82501501 -67036.85631715 -3 3 8 2 4 -3080.28537954 -2.93508440 -1556.92301718 -3 3 8 2 5 3074.86511419 534.95662344 -0.62129524 -3 3 8 2 6 -93.24784556 -890.87309862 -3060.30752406 -3 3 8 2 7 91.48036773 -3061.79649023 -890.29465133 -3 3 8 2 8 80804.67308380 -67028.64022323 72007.03611321 -3 3 8 3 1 3063.17833654 -3063.88532767 9468.58226714 -3 3 8 3 2 1559.32250223 -536.33846975 2.41019704 -3 3 8 3 3 72000.45895328 -72001.15523243 74100.55468782 -3 3 8 3 4 536.33846975 -1559.30107826 2.39948506 -3 3 8 3 5 -1558.66907103 536.62769339 3.29929195 -3 3 8 3 6 -3061.37872275 3061.33587480 -9465.34724711 -3 3 8 3 7 -538.36303526 1556.91230519 1.42469425 -3 3 8 3 8 -72000.83387282 72005.80423472 -74113.00201654 -4 1 1 1 1 74175.26008413 72107.09678240 -72075.07865370 -4 1 1 1 2 0.32135961 539.16643428 -1559.26894230 -4 1 1 1 3 0.42847947 -538.62012295 1558.20845560 -4 1 1 1 4 -74173.53545425 -72106.60403101 72071.34017029 -4 1 1 1 5 0.37491954 -1559.70813376 538.92005858 -4 1 1 1 6 -9472.92062181 -3066.09199696 3063.86390370 -4 1 1 1 7 9470.53184874 3063.13548859 -3059.60053293 -4 1 1 1 8 -0.53559934 1561.58273146 -538.52371507 -4 1 1 2 1 72106.62545498 67123.79480245 -80913.06767877 -4 1 1 2 2 0.42847947 -538.47015513 -3074.44734671 -4 1 1 2 3 539.15572229 -0.66414318 3074.42592273 -4 1 1 2 4 -67139.60569504 -72093.92103857 80911.96434412 -4 1 1 2 5 -1559.39748614 -1.84246174 3080.44605934 -4 1 1 2 6 0.73912709 1558.20845560 -3077.74663866 -4 1 1 2 7 -3059.08635756 888.61286940 90.98761633 -4 1 1 2 8 -888.92351702 3064.33523112 -92.48729449 -4 1 1 3 1 -72073.35402382 -80911.05382524 67094.51894238 -4 1 1 3 2 893.78675905 -83.22142586 3055.75492965 -4 1 1 3 3 1560.28658105 3074.42592273 -0.59987126 -4 1 1 3 4 67092.82644846 80902.68776351 -72062.34210133 -4 1 1 3 5 -535.78144643 3081.38871419 -0.23566371 -4 1 1 3 6 -1.06048670 -3078.64644555 1559.47247005 -4 1 1 3 7 3064.50662291 93.62276510 889.83403590 -4 1 1 3 8 -1.09262266 -3079.24631682 -536.45630160 -4 2 1 1 1 67134.29254956 72094.91725335 -80912.69275923 -4 2 1 1 2 -538.47015513 0.42847947 -3074.43663472 -4 2 1 1 3 -0.10711987 537.82743592 3074.38307479 -4 2 1 1 4 -72108.24296500 -67119.16722413 80912.73560717 -4 2 1 1 5 888.66642933 -3068.42721010 94.71538776 -4 2 1 1 6 3064.30309516 -888.88066907 -92.46587052 -4 2 1 1 7 1.39255829 -1557.45861652 3075.88275295 -4 2 1 1 8 1558.18703163 0.74983908 -3077.70379071 -4 2 1 2 1 72092.97838373 74174.46739710 -72066.57333614 -4 2 1 2 2 539.17714626 0.26779967 -1559.32250223 -4 2 1 2 3 -539.41280997 -1.19974253 1560.13661323 -4 2 1 2 4 -72096.06343594 -74174.89587658 72068.94068523 -4 2 1 2 5 3069.44484885 9475.43793872 -3067.95588267 -4 2 1 2 6 1561.55059550 -0.47132742 -538.57727500 -4 2 1 2 7 -1561.63629139 -0.63200722 539.44494594 -4 2 1 2 8 -3066.07057299 -9472.96346976 3063.83176774 -4 2 1 3 1 -80907.35818977 -72066.79828786 67095.99719656 -4 2 1 3 2 -83.44637759 893.85103097 3055.82991356 -4 2 1 3 3 3074.57589055 1558.59408713 -0.38563153 -4 2 1 3 4 80899.66698321 67083.49630791 -72062.04216570 -4 2 1 3 5 95.48665081 3067.78449088 888.02371012 -4 2 1 3 6 -3080.15683570 -0.42847947 -537.14186876 -4 2 1 3 7 3080.03900384 -535.31011901 0.35349557 -4 2 1 3 8 -3078.79641337 -1.14618259 1559.37606217 -4 3 1 1 1 -67090.78045897 -80901.40232508 72062.95268458 -4 3 1 1 2 -1559.30107826 -3074.61873850 0.52488736 -4 3 1 1 3 -893.34756759 83.01789811 -3055.87276150 -4 3 1 1 4 72068.69430953 80914.12816547 -67095.10810166 -4 3 1 1 5 0.92123087 3079.99615590 535.68503855 -4 3 1 1 6 -3065.71707742 -94.95105147 -888.64500536 -4 3 1 1 7 3.44925977 3075.04721797 -1559.22609435 -4 3 1 1 8 536.00639816 -3081.11020253 -0.34278358 -4 3 1 2 1 -80900.84530177 -67087.74896669 72062.40637325 -4 3 1 2 2 -3074.61873850 -1559.29036627 0.52488736 -4 3 1 2 3 82.62155460 -893.18688778 -3055.78706561 -4 3 1 2 4 80913.74253394 72064.01317128 -67096.69347571 -4 3 1 2 5 3079.08563701 2.01385353 -1557.41576857 -4 3 1 2 6 -3081.14233849 536.00639816 -0.32135961 -4 3 1 2 7 3076.09699268 3.89916321 535.63147862 -4 3 1 2 8 -94.95105147 -3065.72778941 -888.64500536 -4 3 1 3 1 72061.67795815 72062.13857358 -74113.49476794 -4 3 1 3 2 -3055.20861832 -3055.20861832 9478.51227895 -4 3 1 3 3 3055.10149845 3055.57282587 -9478.69438273 -4 3 1 3 4 -72061.52799033 -72064.27025896 74111.50233838 -4 3 1 3 5 -539.02717845 -1555.40191504 -1.75676584 -4 3 1 3 6 1557.40505658 537.82743592 3.59922758 -4 3 1 3 7 -1556.30172194 -538.08452360 -3.13861215 -4 3 1 3 8 537.82743592 1557.40505658 3.58851560 -4 1 2 1 1 -0.02142397 -0.00000000 897.49310650 -4 1 2 1 2 -0.81411100 0.51417537 -5.49524926 -4 1 2 1 3 -0.02142397 -0.00000000 897.62165034 -4 1 2 1 4 0.84624696 -0.47132742 -5.44168932 -4 1 2 1 5 0.04284795 -0.04284795 -895.17931734 -4 1 2 1 6 0.01071199 -0.29993563 -1.32828637 -4 1 2 1 7 -0.04284795 -0.08569589 -886.63115183 -4 1 2 1 8 0.04284795 0.32135961 -1.24259047 -4 1 2 2 1 538.64154692 -538.57727500 -82.99647414 -4 1 2 2 2 1.47825419 -5.47382528 -2969.45916356 -4 1 2 2 3 -538.74866679 538.72724282 -83.03932209 -4 1 2 2 4 -5.47382528 1.56395008 -2969.46987555 -4 1 2 2 5 540.20549700 540.18407303 -80.89692471 -4 1 2 2 6 -0.73912709 -0.81411100 2913.96035967 -4 1 2 2 7 -535.70646252 -535.55649471 -99.87856542 -4 1 2 2 8 0.17139179 0.17139179 3371.86566168 -4 1 2 3 1 -1559.79382965 -3074.91867413 3058.48648630 -4 1 2 3 2 -5.03463382 -2969.84479509 -1.70320591 -4 1 2 3 3 -1559.77240568 -3074.89725015 -3056.17269714 -4 1 2 3 4 8.11968603 11785.02800014 -7.17703119 -4 1 2 3 5 1560.88645231 -3075.17576181 -3060.02901240 -4 1 2 3 6 -0.04284795 573.30553638 1.07119869 -4 1 2 3 7 1556.49453770 -3078.68929350 3064.50662291 -4 1 2 3 8 -0.77126305 2915.25651008 0.87838292 -4 2 2 1 1 -538.59869897 538.62012295 -83.01789811 -4 2 2 1 2 5.50596124 -1.55323809 -2969.43773959 -4 2 2 1 3 538.70581884 -538.64154692 -83.08217003 -4 2 2 1 4 -1.58537405 5.39884137 -2969.44845157 -4 2 2 1 5 -540.24834495 -540.22692098 -80.89692471 -4 2 2 1 6 -0.09640788 -0.06427192 3371.94064559 -4 2 2 1 7 535.51364676 535.59934265 -99.79286952 -4 2 2 1 8 0.74983908 0.83553497 2914.00320762 -4 2 2 2 1 -0.02142397 -0.06427192 897.40741060 -4 2 2 2 2 -0.49275140 0.79268703 -5.40955336 -4 2 2 2 3 0.06427192 0.04284795 897.57880239 -4 2 2 2 4 0.54631133 -0.83553497 -5.44168932 -4 2 2 2 5 0.04284795 0.02142397 -895.00792555 -4 2 2 2 6 -0.27851166 0.02142397 -1.17831855 -4 2 2 2 7 0.06427192 -0.04284795 -886.60972786 -4 2 2 2 8 0.27851166 -0.03213596 -1.14618259 -4 2 2 3 1 -3074.89725015 -1559.75098171 3058.22939861 -4 2 2 3 2 -2969.74838720 -5.06676978 -0.14996782 -4 2 2 3 3 -3075.02579400 -1559.75098171 -3056.17269714 -4 2 2 3 4 11784.94230425 8.09826206 5.29172151 -4 2 2 3 5 -3075.17576181 1560.86502834 3060.02901240 -4 2 2 3 6 2915.24579810 -0.68556716 -1.32828637 -4 2 2 3 7 -3078.66786953 1556.58023360 -3064.39950304 -4 2 2 3 8 573.24126446 -0.14996782 -1.51039015 -4 3 2 1 1 -1559.79382965 -3074.85440221 -3058.35794245 -4 3 2 1 2 8.76240525 11785.57431147 6.13796847 -4 3 2 1 3 -1559.77240568 -3074.85440221 3058.35794245 -4 3 2 1 4 -5.72020098 -2970.47680231 0.81411100 -4 3 2 1 5 1560.84360436 -3075.11148989 3059.85762061 -4 3 2 1 6 -0.85695895 2915.35291796 -0.98550279 -4 3 2 1 7 1556.58023360 -3078.71071747 -3064.50662291 -4 3 2 1 8 0.02142397 573.13414459 -1.26401445 -4 3 2 2 1 -3074.89725015 -1559.81525363 -3058.33651848 -4 3 2 2 2 11785.67071936 8.88023710 -6.14868045 -4 3 2 2 3 -3074.96152208 -1559.77240568 3058.35794245 -4 3 2 2 4 -2970.55178622 -5.72020098 -0.79268703 -4 3 2 2 5 -3075.17576181 1560.77933244 -3059.85762061 -4 3 2 2 6 573.15556856 -0.00000000 1.26401445 -4 3 2 2 7 -3078.62502158 1556.55880962 3064.46377496 -4 3 2 2 8 2915.31007002 -0.82482299 1.09262266 -4 3 2 3 1 0.02142397 0.04284795 9477.92311967 -4 3 2 3 2 10.06926764 -8.89094909 -7.55195073 -4 3 2 3 3 0.02142397 0.06427192 9480.19406088 -4 3 2 3 4 -10.10140360 8.80525319 -7.64835861 -4 3 2 3 5 -0.02142397 -0.00000000 -9481.99367468 -4 3 2 3 6 -1.34971034 -1.15689458 -2.89223645 -4 3 2 3 7 0.02142397 -0.02142397 -9454.99946781 -4 3 2 3 8 1.37113432 1.27472644 -2.92437241 -4 1 3 1 1 1.11404663 539.33782607 1559.91166151 -4 1 3 1 2 -0.98550279 -539.63776170 -1558.30486348 -4 1 3 1 3 -74175.68856360 -72096.66330721 -72070.11900379 -4 1 3 1 4 74178.28086442 72099.64123955 72070.54748326 -4 1 3 1 5 -9476.48771343 -3068.94138546 -3067.31316346 -4 1 3 1 6 9473.11343757 3066.24196478 3063.99244754 -4 1 3 1 7 1.11404663 1560.60794065 540.18407303 -4 1 3 1 8 -0.23566371 -1560.57580469 -539.02717845 -4 1 3 2 1 -537.97740374 0.28922365 3074.46877068 -4 1 3 2 2 -1.09262266 537.79529996 -3073.51540385 -4 1 3 2 3 -72094.52090984 -67133.64983035 -80914.36382918 -4 1 3 2 4 67120.10987897 72106.92539061 80913.67826202 -4 1 3 2 5 3068.55575394 -888.51646152 94.58684391 -4 1 3 2 6 -0.68556716 -1558.31557547 -3077.59667084 -4 1 3 2 7 1556.83732128 -0.44990345 3075.21860976 -4 1 3 2 8 888.79497318 -3064.20668728 -92.28376674 -4 1 3 3 1 1558.65835905 3074.39378677 0.33207159 -4 1 3 3 2 893.40112752 -83.06074606 -3055.92632144 -4 1 3 3 3 -72063.34902810 -80910.63605775 -67096.92913942 -4 1 3 3 4 67082.62863697 80901.68083674 72061.67795815 -4 1 3 3 5 3067.69879499 95.29383505 -887.95943820 -4 1 3 3 6 -2.87081248 -3077.38243110 -1558.18703163 -4 1 3 3 7 -534.67811179 3079.12848496 0.28922365 -4 1 3 3 8 -1.41398226 -3079.39628463 536.61698141 -4 2 3 1 1 0.44990345 -538.82365070 3074.52233062 -4 2 3 1 2 537.61319618 -0.99621478 -3073.61181173 -4 2 3 1 3 -67120.24913480 -72104.89011311 -80914.06389354 -4 2 3 1 4 72093.68537486 67135.27805235 80912.26427975 -4 2 3 1 5 2.02456552 1559.72955773 3080.16754769 -4 2 3 1 6 -3065.11720616 889.43769239 -91.65175952 -4 2 3 1 7 -889.90901981 3060.92881930 89.74502586 -4 2 3 1 8 -1558.44411931 -0.73912709 -3077.48955097 -4 2 3 2 1 538.83436268 -0.52488736 1558.35842341 -4 2 3 2 2 -539.51992984 -1.10333465 -1558.17631964 -4 2 3 2 3 -72110.97452164 -74174.93872452 -72077.06037127 -4 2 3 2 4 72107.21461426 74175.66713963 72073.84677521 -4 2 3 2 5 1560.61865264 -1.07119869 538.29876334 -4 2 3 2 6 -1559.64386184 -0.85695895 -539.69132163 -4 2 3 2 7 -3062.98552077 -9470.47828881 -3059.66480485 -4 2 3 2 8 3066.37050862 9473.19913347 3063.87461568 -4 2 3 3 1 3074.61873850 1560.09376528 0.57844729 -4 2 3 3 2 -83.10359401 893.41183951 -3055.90489746 -4 2 3 3 3 -80911.79295233 -72070.01188392 -67095.21522152 -4 2 3 3 4 80901.47730899 67093.20136800 72061.07808688 -4 2 3 3 5 3081.31373028 -535.96355021 0.29993563 -4 2 3 3 6 -3079.41770861 -1.41398226 536.58484545 -4 2 3 3 7 94.20121239 3063.58539204 -889.24487662 -4 2 3 3 8 -3077.36100713 -2.88152446 -1558.19774361 -4 3 3 1 1 -893.35827957 82.96433818 3055.88347349 -4 3 3 1 2 -1559.57958992 -3074.39378677 -0.48203941 -4 3 3 1 3 -67084.21401103 -80901.08096548 -72060.94954304 -4 3 3 1 4 72063.67038770 80909.58628304 67096.45781200 -4 3 3 1 5 2.21738128 3079.48198053 1557.20152883 -4 3 3 1 6 -3066.55261240 -94.17978841 889.22345265 -4 3 3 1 7 2.67799671 3077.90731846 -536.87406909 -4 3 3 1 8 535.10659126 -3080.32822749 -0.23566371 -4 3 3 2 1 83.51064951 -893.69035117 3055.93703342 -4 3 3 2 2 -3074.40449876 -1559.57958992 -0.48203941 -4 3 3 2 3 -80901.88436449 -67087.65255881 -72061.63511020 -4 3 3 2 4 80909.41489125 72070.16185173 67094.65819821 -4 3 3 2 5 3081.80648168 -0.59987126 -536.92762902 -4 3 3 2 6 -3080.32822749 535.17086318 -0.27851166 -4 3 3 2 7 3076.03272076 2.72084466 1559.70813376 -4 3 3 2 8 -94.15836444 -3066.55261240 889.20202868 -4 3 3 3 1 -3055.52997792 -3055.10149845 -9478.78007862 -4 3 3 3 2 3055.93703342 3055.92632144 9477.76243987 -4 3 3 3 3 -72064.25954698 -72063.75608360 -74111.05243493 -4 3 3 3 4 72065.14864189 72062.25640544 74111.86654593 -4 3 3 3 5 1555.38049107 539.07002640 -1.69249392 -4 3 3 3 6 -1556.44097777 -538.29876334 2.63514877 -4 3 3 3 7 538.12737155 1556.36599386 -3.14932413 -4 3 3 3 8 -538.29876334 -1556.44097777 2.61372479 -4 1 4 1 1 -74167.86881320 -67132.10730425 67088.54165371 -4 1 4 1 2 2.12097340 -5.62379310 7.29486305 -4 1 4 1 3 74174.06034160 67119.38146386 67080.43267967 -4 1 4 1 4 -115.00389085 213.51132196 -123.83056802 -4 1 4 1 5 74170.60036985 -67112.39724844 -67088.53094173 -4 1 4 1 6 -1.14618259 3.74919540 -8.50531756 -4 1 4 1 7 -74062.48428654 66921.46679477 -66963.46849522 -4 1 4 1 8 -0.36420755 -7.75547848 8.25894186 -4 1 4 2 1 -72109.04636401 -72098.14156139 80899.57057533 -4 1 4 2 2 -1.04977471 2.06741346 11786.03492691 -4 1 4 2 3 72098.14156139 72106.94681459 80899.83837500 -4 1 4 2 4 224.35185265 -222.12375939 -329275.61390950 -4 1 4 2 5 -72115.45213215 72109.00351606 80901.80938058 -4 1 4 2 6 1.77818982 2.80654056 -2957.25821053 -4 1 4 2 7 71902.15504993 -71902.15504993 80705.06231805 -4 1 4 2 8 -0.74983908 1.71391790 -2959.42203188 -4 1 4 3 1 72071.85434566 80911.31091292 -72063.58469181 -4 1 4 3 2 -5.01320985 -2970.33754648 -6.90923152 -4 1 4 3 3 72067.01252760 80914.34240520 72060.00688820 -4 1 4 3 4 -122.05237820 -329280.77708716 -108.19106722 -4 1 4 3 5 -72081.31303005 80900.65248600 72062.59918902 -4 1 4 3 6 6.70570377 -2956.65833927 -0.27851166 -4 1 4 3 7 -71944.31743018 80700.02768423 -71944.98157337 -4 1 4 3 8 7.02706338 11781.39663660 1.52110213 -4 2 4 1 1 -72109.41057156 -72098.72000868 80899.81695103 -4 2 4 1 2 -0.42847947 1.36042233 11785.11369604 -4 2 4 1 3 72098.07728947 72106.58260703 80899.66698321 -4 2 4 1 4 223.35563787 -219.03870717 -329277.49921918 -4 2 4 1 5 -72115.58067599 72108.76785235 80901.98077237 -4 2 4 1 6 1.69249392 2.72084466 -2957.42960232 -4 2 4 1 7 71903.05485683 -71903.27980855 80708.00811444 -4 2 4 1 8 -0.79268703 1.81032578 -2959.59342367 -4 2 4 2 1 -67118.22456928 -74175.37791599 67079.97206423 -4 2 4 2 2 5.48453727 -1.55323809 7.11275927 -4 2 4 2 3 67135.19235646 74168.57580433 67091.05897063 -4 2 4 2 4 -220.20631374 114.48971549 -124.04480776 -4 2 4 2 5 67118.71732068 -74169.04713176 -67089.64498836 -4 2 4 2 6 6.95207947 0.57844729 6.55573595 -4 2 4 2 7 -66924.08051956 74057.52463663 -66964.67894973 -4 2 4 2 8 -3.83489129 4.91680197 -6.14868045 -4 2 4 3 1 80912.67133525 72070.05473187 -72065.10579394 -4 2 4 3 2 -2970.15544271 -4.95964991 10.48703513 -4 2 4 3 3 80912.01790406 72068.21227013 72057.73594698 -4 2 4 3 4 -329277.20999554 -122.99503305 112.11165440 -4 2 4 3 5 80896.86044266 -72079.95260772 -72061.65653417 -4 2 4 3 6 11782.30715548 7.66978259 1.11404663 -4 2 4 3 7 80700.12409211 -71944.87445350 71945.33506893 -4 2 4 3 8 -2956.48694748 6.60929589 -0.02142397 -4 3 4 1 1 72071.68295387 80911.37518484 -72063.56326783 -4 3 4 1 2 -4.97036190 -2970.33754648 -6.88780755 -4 3 4 1 3 72066.86255978 80914.12816547 72059.62125667 -4 3 4 1 4 -122.02024224 -329280.15579192 -108.46957887 -4 3 4 1 5 -72081.28089409 80900.58821408 72062.81342875 -4 3 4 1 6 6.69499178 -2956.65833927 -0.21423974 -4 3 4 1 7 -71943.97464660 80699.85629244 -71944.61736582 -4 3 4 1 8 7.09133530 11781.30022872 1.48896617 -4 3 4 2 1 80912.49994346 72069.87262809 -72065.06294599 -4 3 4 2 2 -2970.11259476 -4.95964991 10.51917109 -4 3 4 2 3 80912.02861604 72068.21227013 72057.77879493 -4 3 4 2 4 -329277.27426746 -122.84506523 111.29754340 -4 3 4 2 5 80896.81759471 -72079.84548785 -72061.42087046 -4 3 4 2 6 11782.24288356 7.77690246 0.96407882 -4 3 4 2 7 80700.35975583 -71944.96014939 71945.57073265 -4 3 4 2 8 -2956.50837145 6.59858390 -0.09640788 -4 3 4 3 1 -67096.30784418 -67097.92535420 74105.35365793 -4 3 4 3 2 4.34906666 -1.46754220 -7.12347126 -4 3 4 3 3 67094.73318212 67093.13709607 74109.12427730 -4 3 4 3 4 -107.88041960 110.91191188 4.58473037 -4 3 4 3 5 67086.95627966 -67087.33119920 -74078.23090722 -4 3 4 3 6 -0.88909491 -1.11404663 -5.99871264 -4 3 4 3 7 -66981.47534512 66981.07900160 -74121.55018205 -4 3 4 3 8 0.64271921 2.61372479 -5.98800065 -4 1 5 1 1 1.30686240 -1559.55816594 -536.92762902 -4 1 5 1 2 -0.21423974 540.80536827 1560.30800502 -4 1 5 1 3 -9477.32324841 3068.19154638 3067.05607578 -4 1 5 1 4 74173.47118233 -72113.84533412 -72079.65267209 -4 1 5 1 5 -74162.65207560 72101.22661361 72062.02074173 -4 1 5 1 6 9463.84756895 -3060.07186035 -3055.14434640 -4 1 5 1 7 0.55702332 -537.76316400 -1559.04399057 -4 1 5 1 8 1.04977471 1561.01499615 541.65161523 -4 1 5 2 1 -1560.00806939 0.37491954 3080.60673915 -4 1 5 2 2 0.23566371 539.92698534 -3074.61873850 -4 1 5 2 3 -3068.90924950 -888.08798204 94.95105147 -4 1 5 2 4 -67118.25670525 72109.47484348 80903.18051490 -4 1 5 2 5 72102.62988389 -67157.19477746 -80923.70468171 -4 1 5 2 6 0.73912709 -1552.98100601 -3070.56960747 -4 1 5 2 7 533.88542476 3.67421149 3077.27531124 -4 1 5 2 8 -890.38034723 -3055.08007448 -86.33861404 -4 1 5 3 1 537.95597976 3080.69243504 0.36420755 -4 1 5 3 2 -890.89452260 -81.12187644 -3057.53311947 -4 1 5 3 3 -3066.99180386 94.69396378 -888.06655807 -4 1 5 3 4 -67091.70168984 80902.47352377 72061.63511020 -4 1 5 3 5 72057.84306685 -80921.94791587 -67086.28142449 -4 1 5 3 6 7.01635139 -3071.96216576 -1561.50774755 -4 1 5 3 7 -1556.53738565 3074.92938612 -3.53495566 -4 1 5 3 8 3.23502003 -3077.67165475 534.88163954 -4 2 5 1 1 888.06655807 3068.93067348 94.88677954 -4 2 5 1 2 -540.16264905 -0.47132742 -3074.66158644 -4 2 5 1 3 -0.39634351 1559.98664542 3080.46748332 -4 2 5 1 4 -72109.92474693 67118.39596107 80902.75203543 -4 2 5 1 5 67159.65853443 -72100.92667798 -80924.24028106 -4 2 5 1 6 3054.27667546 889.54481225 -86.89563735 -4 2 5 1 7 -3.66349950 -533.89613675 3077.30744720 -4 2 5 1 8 1552.14547104 -1.60679803 -3069.96973620 -4 2 5 2 1 -3069.32701699 9475.36295481 3068.47005804 -4 2 5 2 2 -540.71967237 0.14996782 1560.14732522 -4 2 5 2 3 1560.64007661 -1.00692676 -536.15636597 -4 2 5 2 4 72113.71679028 -74171.01813734 -72081.98788522 -4 2 5 2 5 -72101.65509308 74162.74848349 72060.64960741 -4 2 5 2 6 -1560.04020535 -0.57844729 542.36931835 -4 2 5 2 7 537.74174003 -0.78197504 -1559.24751832 -4 2 5 2 8 3059.64338088 -9464.82235975 -3054.46949123 -4 2 5 3 1 94.67253981 -3066.99180386 888.12011800 -4 2 5 3 2 -81.13258843 -891.18374624 3057.27603178 -4 2 5 3 3 3080.62816312 537.97740374 -0.47132742 -4 2 5 3 4 80904.42310538 -67093.73696734 -72063.28475617 -4 2 5 3 5 -80923.98319337 72062.10643762 67085.91721694 -4 2 5 3 6 -3076.60045606 3.51353169 -534.09966450 -4 2 5 3 7 3074.96152208 -1556.52667366 3.55637964 -4 2 5 3 8 -3072.99051650 5.07748177 1562.87888187 -4 3 5 1 1 -1.58537405 3078.94638119 -537.81672393 -4 3 5 1 2 1560.58651668 -3074.75799433 -0.68556716 -4 3 5 1 3 -0.21423974 3080.31751550 1555.20909928 -4 3 5 1 4 -72075.29289344 80900.22400653 67090.52337128 -4 3 5 1 5 67095.81509279 -80906.99398222 -72056.42908459 -4 3 5 1 6 3062.98552077 -92.48729449 891.40869797 -4 3 5 1 7 889.60908418 93.36567741 3056.70829648 -4 3 5 1 8 -531.95726712 -3078.65715754 0.74983908 -4 3 5 2 1 3080.63887511 -0.43919146 -1554.99485954 -4 3 5 2 2 -3074.68301042 1560.53295675 0.50346338 -4 3 5 2 3 3080.78884292 -0.27851166 539.11287434 -4 3 5 2 4 80897.57814578 -72076.97467537 -67092.08732136 -4 3 5 2 5 -80907.37961375 67096.80059558 72055.31503796 -4 3 5 2 6 -3077.67165475 -531.48593970 -0.04284795 -4 3 5 2 7 93.68703702 889.83403590 -3056.89040025 -4 3 5 2 8 -92.91577396 3062.02144196 -890.78740273 -4 3 5 3 1 536.94905300 -1557.46932851 -2.79582857 -4 3 5 3 2 3057.07250403 -3056.72972045 -9482.87205760 -4 3 5 3 3 1557.45861652 -536.92762902 -2.78511658 -4 3 5 3 4 72065.11650593 -72064.76301036 -74082.62282182 -4 3 5 3 5 -72059.20348918 72057.02895585 74119.92196005 -4 3 5 3 6 -1553.81654099 540.29119290 -7.06991132 -4 3 5 3 7 -3064.09956741 3064.05671946 9465.71145466 -4 3 5 3 8 -539.43423395 1554.64136398 -7.60551067 -4 1 6 1 1 -9471.68874332 0.42847947 -1.88530969 -4 1 6 1 2 0.53559934 -0.61058325 -0.10711987 -4 1 6 1 3 9471.73159127 -0.44990345 -2.05670148 -4 1 6 1 4 -1.21045451 -1.39255829 6.94136748 -4 1 6 1 5 9461.21242018 1.22116650 5.87016880 -4 1 6 1 6 4.89537799 1.32828637 -6.87709556 -4 1 6 1 7 -9465.60433479 0.40705550 -1.94958161 -4 1 6 1 8 0.19281576 -0.89980690 0.14996782 -4 1 6 2 1 -3065.44927775 1558.55123918 -3077.98230237 -4 1 6 2 2 -0.66414318 -0.73912709 573.18770452 -4 1 6 2 3 3067.67737102 -1558.48696726 -3078.06799826 -4 1 6 2 4 1.92815763 2.44233300 -2958.47937704 -4 1 6 2 5 -3060.86454738 -1552.70249436 -3072.54061305 -4 1 6 2 6 -1.88530969 -6.91994351 11774.93730853 -4 1 6 2 7 3059.62195690 1557.82282407 -3075.45427347 -4 1 6 2 8 -0.44990345 0.17139179 2914.44239908 -4 1 6 3 1 3061.65723440 -3078.00372634 1559.04399057 -4 1 6 3 2 -1.11404663 2913.81039186 0.54631133 -4 1 6 3 3 3065.94202915 -3078.08942224 -1558.97971865 -4 1 6 3 4 -6.56644794 -2960.02190314 -1.64964598 -4 1 6 3 5 -3056.66544853 -3070.33394376 -1562.62179418 -4 1 6 3 6 -6.72712774 11773.54475024 4.77754614 -4 1 6 3 7 -3056.96538416 -3075.53996937 1557.26580076 -4 1 6 3 8 0.51417537 574.76236659 1.45683021 -4 2 6 1 1 3065.89918120 1561.14354000 -3079.48198053 -4 2 6 1 2 -0.02142397 -0.17139179 2915.20295015 -4 2 6 1 3 -3065.87775722 -1561.07926808 -3079.48198053 -4 2 6 1 4 -0.07498391 7.00563940 11783.82825762 -4 2 6 1 5 3053.62324426 -1560.28658105 -3077.03964753 -4 2 6 1 6 3.81346732 -2.39948506 -2963.36404304 -4 2 6 1 7 -3057.15819993 1555.16625133 -3074.08313915 -4 2 6 1 8 -0.23566371 0.70699113 574.67667069 -4 2 6 2 1 -890.70170683 -0.17139179 -1.15689458 -4 2 6 2 2 0.57844729 0.02142397 -0.55702332 -4 2 6 2 3 886.26694428 0.08569589 -1.15689458 -4 2 6 2 4 5.06676978 0.83553497 6.96279145 -4 2 6 2 5 889.07348483 -0.40705550 3.29929195 -4 2 6 2 6 0.43919146 -0.44990345 -6.87709556 -4 2 6 2 7 -891.34442605 -0.17139179 -1.07119869 -4 2 6 2 8 0.59987126 0.20352775 0.62129524 -4 2 6 3 1 -90.70910467 -539.02717845 -536.64911737 -4 2 6 3 2 3371.64070996 -0.82482299 -0.77126305 -4 2 6 3 3 -90.77337659 -539.15572229 536.62769339 -4 2 6 3 4 -2961.93934879 6.98421543 -0.96407882 -4 2 6 3 5 -87.04560517 542.28362245 -534.31390423 -4 2 6 3 6 -2965.24935273 -5.74162495 -0.53559934 -4 2 6 3 7 -89.98068957 535.36367894 537.80601195 -4 2 6 3 8 2914.02463160 0.11783186 -1.01763875 -4 3 6 1 1 -3065.06364622 -3080.70314703 1556.38741783 -4 3 6 1 2 -0.72841511 573.31624836 -0.78197504 -4 3 6 1 3 -3067.16319565 -3080.68172306 -1556.40884181 -4 3 6 1 4 5.81660886 11784.47097683 -0.34278358 -4 3 6 1 5 3064.78513457 -3078.00372634 -1554.78061981 -4 3 6 1 6 5.73091297 -2961.15737375 -2.91366042 -4 3 6 1 7 3055.67994574 -3072.94766855 1559.92237350 -4 3 6 1 8 0.81411100 2915.69570154 -1.17831855 -4 3 6 2 1 -96.57927347 535.49222279 538.19164347 -4 3 6 2 2 2915.50288578 -0.24637570 -1.30686240 -4 3 6 2 3 -94.41545212 535.55649471 -538.21306745 -4 3 6 2 4 -2955.74782039 6.42719211 -2.48518095 -4 3 6 2 5 -95.87228234 -531.74302739 539.49850587 -4 3 6 2 6 -2958.95070446 -7.62693464 0.89980690 -4 3 6 2 7 -88.56670730 -538.77009076 -536.00639816 -4 3 6 2 8 3374.57579436 0.98550279 -0.43919146 -4 3 6 3 1 -885.38856136 -0.10711987 2.42090903 -4 3 6 3 2 -0.89980690 0.91051888 -1.99242955 -4 3 6 3 3 887.57380667 0.19281576 2.61372479 -4 3 6 3 4 -0.18210378 -1.24259047 -3.96343514 -4 3 6 3 5 892.20138499 -0.59987126 -7.41269490 -4 3 6 3 6 -1.61751001 0.10711987 3.87773924 -4 3 6 3 7 -892.13711307 -0.08569589 2.44233300 -4 3 6 3 8 0.55702332 0.74983908 1.96029359 -4 1 7 1 1 9469.50349801 -3060.32894803 3063.82105575 -4 1 7 1 2 0.64271921 -536.16707796 1555.77683458 -4 1 7 1 3 0.87838292 1556.77304936 -534.87092755 -4 1 7 1 4 -74060.30975321 71902.24074582 -71939.98978750 -4 1 7 1 5 1.09262266 534.61383986 -1556.60165757 -4 1 7 1 6 -9463.10844185 3057.22247185 -3060.00758843 -4 1 7 1 7 74050.93676471 -71899.38064533 71936.81903939 -4 1 7 1 8 0.34278358 -1555.12340339 535.12801523 -4 1 7 2 1 3064.20668728 890.15539551 93.68703702 -4 1 7 2 2 -0.38563153 -535.46008683 -3078.36793390 -4 1 7 2 3 1561.08998006 -0.51417537 3079.05350105 -4 1 7 2 4 66920.29918820 -71901.25524303 80698.90292561 -4 1 7 2 5 -537.74174003 2.07812545 3074.42592273 -4 1 7 2 6 -0.11783186 1557.43719255 -3075.00437002 -4 1 7 2 7 -71897.54889558 66928.76165781 -80701.76302610 -4 1 7 2 8 890.23037941 3058.80784590 -90.81622454 -4 1 7 3 1 -3059.57910895 90.83764851 889.48054033 -4 1 7 3 2 -884.51017843 -101.45322749 3065.36358186 -4 1 7 3 3 540.19478501 3075.30430566 0.47132742 -4 1 7 3 4 -66970.30274283 80708.32947404 -71949.58772772 -4 1 7 3 5 -1559.75098171 3079.71764424 -1.64964598 -4 1 7 3 6 -2.21738128 -3075.60424129 1556.98728910 -4 1 7 3 7 71936.66907157 -80703.77687963 66976.95488667 -4 1 7 3 8 -0.47132742 -3073.19404425 -537.62390817 -4 2 7 1 1 -0.44990345 -1561.74341126 3079.73906821 -4 2 7 1 2 535.81358239 0.53559934 -3078.19654211 -4 2 7 1 3 -890.35892326 -3064.14241535 93.70846099 -4 2 7 1 4 71905.44362989 -66921.68103450 80700.27405993 -4 2 7 1 5 -2.24951724 537.65604413 3074.40449876 -4 2 7 1 6 -3056.98680814 -889.00921291 -92.10166296 -4 2 7 1 7 -66934.21405912 71898.48083844 -80702.48072922 -4 2 7 1 8 -1557.05156102 -0.05355993 -3075.19718579 -4 2 7 2 1 -1555.93751439 -0.06427192 -535.36367894 -4 2 7 2 2 536.02782213 -0.58915928 1555.58401882 -4 2 7 2 3 3061.16448301 -9468.73223495 3064.35665509 -4 2 7 2 4 -71906.13990904 74059.80628983 -71941.46804168 -4 2 7 2 5 -534.33532821 -0.81411100 -1556.58023360 -4 2 7 2 6 1554.09505265 -0.74983908 535.89927829 -4 2 7 2 7 71901.76941840 -74052.84349837 71936.95829522 -4 2 7 2 8 -3056.81541635 9464.09394464 -3059.30059730 -4 2 7 3 1 3076.31123242 540.66611244 -1.14618259 -4 2 7 3 2 -101.95669087 -884.86367400 -3065.44927775 -4 2 7 3 3 90.40916904 -3060.60745969 -890.20895544 -4 2 7 3 4 80704.86950229 -66967.82827387 71949.52345579 -4 2 7 3 5 3079.81405212 -1559.81525363 1.90673366 -4 2 7 3 6 -3074.95081009 -1.90673366 538.83436268 -4 2 7 3 7 -80698.02454269 71937.30107879 -66975.86226401 -4 2 7 3 8 -3076.54689613 -2.86010049 -1557.45861652 -4 3 7 1 1 5.48453727 3079.31058874 -1557.96207990 -4 3 7 1 2 1556.96586512 -3078.74285344 -0.55702332 -4 3 7 1 3 2.77440459 3075.30430566 537.95597976 -4 3 7 1 4 -71947.45604233 80700.16694006 -66984.34615759 -4 3 7 1 5 891.07662637 93.36567741 -3062.70700912 -4 3 7 1 6 3057.27603178 -88.43816346 -890.61601094 -4 3 7 1 7 66971.77028503 -80709.42209670 71957.31107024 -4 3 7 1 8 -537.80601195 -3071.57653423 0.99621478 -4 3 7 2 1 3075.56139334 2.24951724 -538.30947533 -4 3 7 2 2 -3078.64644555 1557.10512095 0.46061543 -4 3 7 2 3 3077.35029514 2.72084466 1556.10890618 -4 3 7 2 4 80699.50279688 -71939.83981968 66983.63916646 -4 3 7 2 5 93.09787774 890.53031505 3062.98552077 -4 3 7 2 6 -3071.65151814 -537.67746810 -0.87838292 -4 3 7 2 7 -80707.36539523 66966.68209127 -71955.26508075 -4 3 7 2 8 -87.73117233 3058.17583868 891.34442605 -4 3 7 3 1 -1559.30107826 537.32397254 -2.94579638 -4 3 7 3 2 -3067.63452307 3067.61309909 -9457.99882413 -4 3 7 3 3 -534.90306351 1561.78625921 -1.28543842 -4 3 7 3 4 -71944.41383807 71937.89023807 -74124.67808221 -4 3 7 3 5 3058.44363835 -3057.56525543 9466.09708619 -4 3 7 3 6 1560.44726085 -535.77073444 2.18524532 -4 3 7 3 7 71951.70870111 -71950.78747024 74116.21561260 -4 3 7 3 8 535.79215842 -1560.43654886 2.24951724 -4 1 8 1 1 -0.19281576 -886.43833607 -1.15689458 -4 1 8 1 2 -0.00000000 0.23566371 -0.35349557 -4 1 8 1 3 0.10711987 886.37406415 -1.37113432 -4 1 8 1 4 -0.81411100 -1.41398226 8.20538193 -4 1 8 1 5 0.42847947 -891.19445823 3.34213990 -4 1 8 1 6 -0.20352775 0.19281576 0.34278358 -4 1 8 1 7 0.23566371 888.98778894 -1.09262266 -4 1 8 1 8 0.38563153 3.27786798 -8.23751789 -4 1 8 2 1 1561.14354000 3065.96345312 -3079.41770861 -4 1 8 2 2 0.06427192 -0.09640788 2915.23508611 -4 1 8 2 3 -1561.14354000 -3065.96345312 -3079.39628463 -4 1 8 2 4 -6.39505615 -0.72841511 11784.34243299 -4 1 8 2 5 1560.30800502 -3053.68751619 -3076.99679958 -4 1 8 2 6 -0.68556716 0.06427192 574.69809467 -4 1 8 2 7 -1555.14482736 3059.10778153 -3074.08313915 -4 1 8 2 8 1.84246174 -4.65971428 -2964.22100199 -4 1 8 3 1 -538.98433050 -90.73052865 -536.60626942 -4 1 8 3 2 -0.81411100 3371.73711784 0.61058325 -4 1 8 3 3 -539.09145037 -90.75195262 536.62769339 -4 1 8 3 4 6.39505615 -2961.07167785 0.34278358 -4 1 8 3 5 542.24077450 -87.06702914 534.14251244 -4 1 8 3 6 0.10711987 2914.21744736 1.17831855 -4 1 8 3 7 535.29940702 -92.12308694 -537.76316400 -4 1 8 3 8 -5.14175369 -2964.29598590 1.31757438 -4 2 8 1 1 1558.50839123 -3065.49212570 -3078.08942224 -4 2 8 1 2 1.00692676 0.31064762 573.34838433 -4 2 8 1 3 -1558.55123918 3067.63452307 -3077.93945442 -4 2 8 1 4 -3.79204335 -3.79204335 -2957.10824272 -4 2 8 1 5 1552.70249436 3058.59360616 -3072.54061305 -4 2 8 1 6 -0.40705550 -0.02142397 2914.30314325 -4 2 8 1 7 -1557.73712818 -3057.43671158 -3075.58281731 -4 2 8 1 8 8.29107782 0.14996782 11773.71614203 -4 2 8 2 1 0.42847947 -9471.62447140 -1.92815763 -4 2 8 2 2 0.89980690 -0.31064762 -0.23566371 -4 2 8 2 3 -0.42847947 9473.93826056 -1.97100558 -4 2 8 2 4 -0.57844729 2.14239737 6.25580032 -4 2 8 2 5 -1.17831855 -9463.44051345 5.65592906 -4 2 8 2 6 0.69627915 -0.14996782 0.36420755 -4 2 8 2 7 -0.32135961 9463.56905729 -1.97100558 -4 2 8 2 8 0.72841511 -4.01699507 -6.23437635 -4 2 8 3 1 -3078.11084621 3061.63581043 1558.97971865 -4 2 8 3 2 2913.91751173 -0.94265484 -1.18903054 -4 2 8 3 3 -3078.02515032 3065.98487709 -1558.80832686 -4 2 8 3 4 -2960.77174222 -5.76304893 -2.87081248 -4 2 8 3 5 -3070.37679170 -3054.45877924 1562.49325034 -4 2 8 3 6 574.69809467 0.70699113 -0.79268703 -4 2 8 3 7 -3075.45427347 -3061.29302685 -1557.33007268 -4 2 8 3 8 11774.25174137 -5.83803283 -0.42847947 -4 3 8 1 1 535.47079881 -96.60069744 538.38445924 -4 3 8 1 2 -0.44990345 2915.17081419 0.94265484 -4 3 8 1 3 535.53507073 -94.47972404 -538.25591539 -4 3 8 1 4 7.70191855 -2957.60099411 -0.02142397 -4 3 8 1 5 -531.87157123 -91.58748759 -539.45565792 -4 3 8 1 6 1.18903054 3374.34013065 0.92123087 -4 3 8 1 7 -538.70581884 -88.48101141 536.02782213 -4 3 8 1 8 -8.86952511 -2960.78245421 1.60679803 -4 3 8 2 1 -3080.68172306 -3064.99937430 1556.28029797 -4 3 8 2 2 573.32696035 -0.81411100 1.18903054 -4 3 8 2 3 -3080.63887511 -3067.18461962 -1556.40884181 -4 3 8 2 4 11784.55667272 5.76304893 2.93508440 -4 3 8 2 5 -3078.04657429 3062.59988925 1554.60922802 -4 3 8 2 6 2915.72783750 0.92123087 0.79268703 -4 3 8 2 7 -3072.92624457 3057.97231093 -1559.92237350 -4 3 8 2 8 -2961.24306964 5.69877701 0.25708768 -4 3 8 3 1 -0.10711987 -885.36713738 2.48518095 -4 3 8 3 2 -0.85695895 0.19281576 -2.08883744 -4 3 8 3 3 0.12854384 887.61665462 2.52802890 -4 3 8 3 4 0.54631133 -2.54945287 -4.62757832 -4 3 8 3 5 0.38563153 -890.08041160 -7.36984695 -4 3 8 3 6 -0.84624696 -1.09262266 2.01385353 -4 3 8 3 7 0.23566371 892.22280897 2.52802890 -4 3 8 3 8 0.57844729 -1.04977471 4.59544236 -5 1 1 1 1 -0.02142397 -0.03213596 -9.10518883 -5 1 1 1 2 -0.83553497 -890.29465133 -0.14996782 -5 1 1 1 3 0.03213596 -0.04284795 0.87838292 -5 1 1 1 4 0.88909491 890.14468352 -0.29993563 -5 1 1 1 5 -0.11783186 -0.06427192 13.28286370 -5 1 1 1 6 -0.62129524 -889.56623623 -2.35663711 -5 1 1 1 7 0.06427192 0.04284795 0.43919146 -5 1 1 1 8 0.53559934 889.50196431 -2.49589294 -5 1 1 2 1 1.24259047 -1.84246174 2959.80766341 -5 1 1 2 2 1560.54366873 -3071.70507807 3080.36036345 -5 1 1 2 3 -0.16067980 -0.34278358 -573.00560075 -5 1 1 2 4 -1560.55438072 3071.70507807 3080.42463537 -5 1 1 2 5 -1.24259047 -1.82103777 -11776.28701887 -5 1 1 2 6 1553.15239780 3059.42914114 3071.76934999 -5 1 1 2 7 0.14996782 -0.32135961 -2914.66735081 -5 1 1 2 8 -1553.10954986 -3055.03722653 3071.87646986 -5 1 1 3 1 -13.11147191 2961.20022170 0.61058325 -5 1 1 3 2 -536.04924610 94.73681173 538.23449142 -5 1 1 3 3 -0.22495172 -2914.47453504 0.17139179 -5 1 1 3 4 -536.15636597 94.75823570 -538.17021950 -5 1 1 3 5 17.32128274 2964.45666570 -0.68556716 -5 1 1 3 6 534.67811179 87.36696477 -537.69889208 -5 1 1 3 7 -1.24259047 -3373.61171554 -0.07498391 -5 1 1 3 8 534.72095973 85.31026330 537.84885989 -5 2 1 1 1 -1.30686240 1.78890180 -11786.34557453 -5 2 1 1 2 1560.86502834 3071.46941436 3081.45298611 -5 2 1 1 3 0.17139179 0.34278358 -2915.31007002 -5 2 1 1 4 -1560.79004443 -3071.38371847 3081.45298611 -5 2 1 1 5 1.31757438 1.73534187 2966.06346373 -5 2 1 1 6 1558.07991176 -3056.30124098 3073.65465968 -5 2 1 1 7 -0.19281576 0.36420755 -574.32317513 -5 2 1 1 8 -1558.05848778 3051.86647842 3073.59038776 -5 2 1 2 1 -0.00000000 -0.04284795 -8.81596518 -5 2 1 2 2 0.79268703 -9474.68809964 0.85695895 -5 2 1 2 3 -0.04284795 -0.04284795 -0.17139179 -5 2 1 2 4 -0.80339901 9474.62382772 1.11404663 -5 2 1 2 5 -0.00000000 -0.00000000 13.36855959 -5 2 1 2 6 -0.12854384 -9456.11351444 -2.91366042 -5 2 1 2 7 -0.06427192 0.02142397 -0.20352775 -5 2 1 2 8 0.06427192 9456.19921033 -2.96722036 -5 2 1 3 1 -11784.51382478 -4.48832249 -0.02142397 -5 2 1 3 2 3081.75292174 3064.99937430 1556.30172194 -5 2 1 3 3 -573.29482439 1.69249392 0.02142397 -5 2 1 3 4 3081.80648168 3065.04222225 -1556.32314591 -5 2 1 3 5 2961.16808574 -4.32764269 -0.04284795 -5 2 1 3 6 3074.46877068 -3061.35729877 1557.35149665 -5 2 1 3 7 -2915.73854949 -0.08569589 0.01071199 -5 2 1 3 8 3074.53304260 -3061.34658679 -1557.33007268 -5 3 1 1 1 -12.21166501 2959.22921612 -0.58915928 -5 3 1 1 2 538.27733937 94.05124457 -536.52057352 -5 3 1 1 3 1.39255829 -3372.17630930 -0.10711987 -5 3 1 1 4 538.19164347 94.00839662 536.45630160 -5 3 1 1 5 13.76490311 2962.50708409 0.64271921 -5 3 1 1 6 -539.45565792 87.28126888 536.07067008 -5 3 1 1 7 -0.29993563 -2914.66735081 0.07498391 -5 3 1 1 8 -539.54135382 89.50936214 -536.02782213 -5 3 1 2 1 2958.07232153 10.61557897 -0.03213596 -5 3 1 2 2 3081.15305048 -3064.33523112 1558.27272752 -5 3 1 2 3 -2913.56401616 1.26401445 0.02142397 -5 3 1 2 4 3081.17447445 -3064.24953522 -1558.29415149 -5 3 1 2 5 -11771.71300049 13.11147191 0.02142397 -5 3 1 2 6 3069.81976839 3052.95910108 1560.60794065 -5 3 1 2 7 -574.99803030 -2.23880525 0.03213596 -5 3 1 2 8 3069.84119236 3052.93767711 -1560.51153277 -5 3 1 3 1 0.04284795 0.02142397 8.22680590 -5 3 1 3 2 -0.10711987 -886.33121620 -1.94958161 -5 3 1 3 3 0.02142397 0.06427192 2.63514877 -5 3 1 3 4 0.12854384 886.43833607 -2.05670148 -5 3 1 3 5 0.04284795 0.04284795 -10.32635533 -5 3 1 3 6 0.14996782 -891.30157810 2.91366042 -5 3 1 3 7 0.02142397 -0.03213596 -2.23880525 -5 3 1 3 8 -0.21423974 891.24801816 2.94579638 -5 1 2 1 1 -1.30686240 1559.55816594 -536.94905300 -5 1 2 1 2 -74173.54616623 72114.10242181 -72080.03830361 -5 1 2 1 3 9477.33396039 -3068.19154638 3067.09892373 -5 1 2 1 4 0.21423974 -540.82679224 1560.32942900 -5 1 2 1 5 74162.80204342 -72101.41942937 72062.32067736 -5 1 2 1 6 -1.03906272 -1561.01499615 541.68375119 -5 1 2 1 7 -0.49275140 537.69889208 -1559.06541455 -5 1 2 1 8 -9463.82614497 3060.06114836 -3055.20861832 -5 1 2 2 1 -888.13082999 -3068.93067348 94.91891551 -5 1 2 2 2 72109.71050720 -67118.04246551 80902.60206761 -5 1 2 2 3 0.37491954 -1560.07234131 3080.55317921 -5 1 2 2 4 540.15193707 0.51417537 -3074.64016247 -5 1 2 2 5 -67159.40144675 72100.60531837 -80923.96176940 -5 1 2 2 6 -1552.13475905 1.52110213 -3069.96973620 -5 1 2 2 7 3.68492348 533.86400078 3077.29673521 -5 1 2 2 8 -3054.28738745 -889.59837219 -86.90634934 -5 1 2 3 1 -0.96407882 3079.87832404 538.44873116 -5 1 2 3 2 -72076.78185961 80900.02047878 -67092.25871315 -5 1 2 3 3 -0.25708768 3080.53175524 -1555.10197941 -5 1 2 3 4 1560.81146840 -3074.42592273 0.47132742 -5 1 2 3 5 67095.39732530 -80910.50751391 72055.91490922 -5 1 2 3 6 -530.69325268 -3076.84683176 0.42847947 -5 1 2 3 7 889.67335610 93.55849317 -3056.79399237 -5 1 2 3 8 3062.79270501 -92.16593488 -891.29086611 -5 2 2 1 1 1560.02949336 -0.34278358 3080.55317921 -5 2 2 1 2 67116.25356370 -72107.95374135 80901.40232508 -5 2 2 1 3 3068.87711354 888.06655807 94.95105147 -5 2 2 1 4 -0.61058325 -540.11980111 -3074.89725015 -5 2 2 1 5 -72098.23796928 67157.04480964 -80923.70468171 -5 2 2 1 6 889.99471570 3055.25146627 -86.12437430 -5 2 2 1 7 -533.88542476 -3.66349950 3077.27531124 -5 2 2 1 8 -2.57087684 1551.70627958 -3069.28416904 -5 2 2 2 1 3068.21297036 -9477.30182443 3067.09892373 -5 2 2 2 2 -72113.95245399 74173.65328610 -72080.02759163 -5 2 2 2 3 -1559.56887793 1.30686240 -536.92762902 -5 2 2 2 4 540.81608025 -0.23566371 1560.30800502 -5 2 2 2 5 72101.40871738 -74162.81275541 72062.36352530 -5 2 2 2 6 -3060.07186035 9463.84756895 -3055.18719435 -5 2 2 2 7 -537.67746810 0.50346338 -1559.04399057 -5 2 2 2 8 1560.97214821 1.01763875 541.68375119 -5 2 2 3 1 3080.48890729 -0.29993563 1555.09126742 -5 2 2 3 2 80900.03119077 -72076.84613153 67092.29084911 -5 2 2 3 3 3079.86761205 -0.96407882 -538.42730718 -5 2 2 3 4 -3074.40449876 1560.80075642 -0.40705550 -5 2 2 3 5 -80910.51822590 67095.42946126 -72055.91490922 -5 2 2 3 6 -92.09095098 3062.81412898 891.23730618 -5 2 2 3 7 93.55849317 889.69478007 3056.82612833 -5 2 2 3 8 -3076.91110368 -530.67182870 -0.46061543 -5 3 2 1 1 537.91313182 3080.69243504 -0.37491954 -5 3 2 1 2 -67092.62292071 80902.98769914 -72062.15999755 -5 3 2 1 3 -3066.97037988 94.71538776 888.08798204 -5 3 2 1 4 -891.09805035 -81.21828432 3057.39386364 -5 3 2 1 5 72060.04973614 -80922.01218779 67086.06718475 -5 3 2 1 6 3.08505221 -3077.55382289 -534.82807960 -5 3 2 1 7 -1556.55880962 3074.97223406 3.57780361 -5 3 2 1 8 6.06298456 -3072.57274901 1562.17189073 -5 3 2 2 1 94.73681173 -3066.95966790 -888.13082999 -5 3 2 2 2 80903.00912311 -67092.44081693 72062.20284550 -5 3 2 2 3 3080.67101107 537.89170784 0.40705550 -5 3 2 2 4 -81.22899631 -891.04449041 -3057.41528761 -5 3 2 2 5 -80922.00147580 72060.00688820 -67086.04576078 -5 3 2 2 6 -3072.59417298 6.06298456 -1562.15046676 -5 3 2 2 7 3075.00437002 -1556.56952161 -3.54566765 -5 3 2 2 8 -3077.53239892 3.07434023 534.81736761 -5 3 2 3 1 -536.86335710 1557.44790453 -2.81725254 -5 3 2 3 2 -72066.28411249 72066.61618409 -74083.90826025 -5 3 2 3 3 -1557.44790453 536.94905300 -2.82796453 -5 3 2 3 4 -3056.81541635 3057.09392801 -9483.02202541 -5 3 2 3 5 72059.08565733 -72061.33517457 74120.22189568 -5 3 2 3 6 540.68753641 -1552.85246217 -6.34149622 -5 3 2 3 7 3064.03529549 -3064.05671946 9465.72216665 -5 3 2 3 8 1553.68799715 -539.86271342 -6.89851953 -5 1 3 1 1 -0.06427192 0.02142397 -0.26779967 -5 1 3 1 2 9474.66667567 -0.81411100 0.81411100 -5 1 3 1 3 -0.04284795 -0.02142397 -8.76240525 -5 1 3 1 4 -9474.62382772 0.70699113 0.47132742 -5 1 3 1 5 0.05355993 -0.02142397 13.47567946 -5 1 3 1 6 -9456.19921033 -0.02142397 -2.82796453 -5 1 3 1 7 0.04284795 0.05355993 -0.14996782 -5 1 3 1 8 9456.13493841 -0.00000000 -3.07434023 -5 1 3 2 1 -0.00000000 -0.01071199 -2915.58858168 -5 1 3 2 2 -3069.28416904 -1560.73648450 3081.34586624 -5 1 3 2 3 -0.02142397 -0.00000000 -11786.27059062 -5 1 3 2 4 3069.24132110 1560.77933244 3081.23874637 -5 1 3 2 5 -0.04284795 -0.00000000 2965.97776783 -5 1 3 2 6 -3056.27981700 1558.10133573 3073.61181173 -5 1 3 2 7 0.02142397 0.06427192 -574.32317513 -5 1 3 2 8 3056.32266495 -1558.04777580 3073.62252372 -5 1 3 3 1 0.77126305 -573.03773671 0.02142397 -5 1 3 3 2 3069.30559302 3081.73149777 -1556.32314591 -5 1 3 3 3 -9.03020492 -11786.35628651 0.55702332 -5 1 3 3 4 3069.30559302 3081.79576969 1556.28029797 -5 1 3 3 5 -8.85881313 2963.14980330 -0.62129524 -5 1 3 3 6 -3059.15062948 3074.46877068 1557.26580076 -5 1 3 3 7 -0.85695895 -2916.01706115 -0.02142397 -5 1 3 3 8 -3061.44299467 3074.31880286 -1557.37292062 -5 2 3 1 1 -0.00000000 -0.01071199 -573.01631273 -5 2 3 1 2 3069.39128891 -1560.56509271 3080.57460319 -5 2 3 1 3 0.05355993 -0.06427192 2959.63627162 -5 2 3 1 4 -3069.53054474 1560.45797284 3080.51033127 -5 2 3 1 5 0.04284795 -0.04284795 -11776.37271477 -5 2 3 1 6 3059.40771717 1553.10954986 3071.94074178 -5 2 3 1 7 0.04284795 -0.00000000 -2914.74233471 -5 2 3 1 8 -3059.38629319 -1553.09883787 3071.76934999 -5 2 3 2 1 0.08569589 -0.05355993 1.00692676 -5 2 3 2 2 890.20895544 0.85695895 -0.19281576 -5 2 3 2 3 -0.00000000 -0.14996782 -7.88402232 -5 2 3 2 4 -890.19824345 -0.92123087 0.17139179 -5 2 3 2 5 -0.06427192 -0.04284795 12.08312117 -5 2 3 2 6 -887.48811078 -0.40705550 -2.52802890 -5 2 3 2 7 0.08569589 0.02142397 0.21423974 -5 2 3 2 8 887.38099091 0.57844729 -2.46375698 -5 2 3 3 1 -2915.01013439 -0.34278358 -0.03213596 -5 2 3 3 2 94.77965968 -536.09209405 -538.29876334 -5 2 3 3 3 2958.49008902 -11.20473825 0.12854384 -5 2 3 3 4 94.80108365 -536.11351802 538.29876334 -5 2 3 3 5 2961.76795700 15.44668504 -0.04284795 -5 2 3 3 6 89.61648201 534.74238371 -537.78458797 -5 2 3 3 7 -3374.10446694 -0.95336683 -0.00000000 -5 2 3 3 8 89.70217791 534.71024775 537.74174003 -5 3 3 1 1 1.92815763 -2913.87466378 0.02142397 -5 3 3 1 2 -3068.74856970 3081.11020253 -1558.22987957 -5 3 3 1 3 14.19338258 2960.87886209 -0.06427192 -5 3 3 1 4 -3068.67358579 3081.21732240 1558.16560765 -5 3 3 1 5 16.67856353 -11774.20889342 -0.00000000 -5 3 3 1 6 3053.08764492 3069.84119236 1560.65078860 -5 3 3 1 7 -1.47825419 -574.68738268 -0.05355993 -5 3 3 1 8 3052.98052505 3069.83048037 -1560.55438072 -5 3 3 2 1 -3372.13346135 1.29615041 -0.00000000 -5 3 3 2 2 94.05124457 538.27733937 536.60626942 -5 3 3 2 3 2959.32562400 -12.16881707 0.72841511 -5 3 3 2 4 94.01910861 538.25591539 -536.54199750 -5 3 3 2 5 2962.52850807 13.71134317 -0.57844729 -5 3 3 2 6 89.53078612 -539.47708190 536.02782213 -5 3 3 2 7 -2914.64592683 -0.31064762 -0.10711987 -5 3 3 2 8 87.38838875 -539.54135382 -536.04924610 -5 3 3 3 1 0.14996782 -0.11783186 2.69942069 -5 3 3 3 2 886.39548812 0.10711987 -2.03527750 -5 3 3 3 3 0.97479080 0.66414318 8.84810114 -5 3 3 3 4 -888.46290158 -0.02142397 -1.84246174 -5 3 3 3 5 0.92123087 -0.59987126 -10.92622659 -5 3 3 3 6 -891.32300207 0.08569589 2.95650837 -5 3 3 3 7 0.14996782 0.07498391 -2.28165320 -5 3 3 3 8 891.28015412 -0.08569589 2.81725254 -5 1 4 1 1 1.28543842 -1559.56887793 -536.91691704 -5 1 4 1 2 -0.34278358 540.64468846 1560.22230913 -5 1 4 1 3 -9477.33396039 3068.19154638 3067.09892373 -5 1 4 1 4 74173.97464571 -72114.61659717 -72080.20969540 -5 1 4 1 5 -74162.52353176 72103.32616303 72061.87077391 -5 1 4 1 6 9463.94397683 -3060.22182817 -3055.10149845 -5 1 4 1 7 0.53559934 -537.76316400 -1559.02256660 -5 1 4 1 8 0.36420755 1560.10447727 542.32647040 -5 1 4 2 1 888.04513410 3068.93067348 94.89749153 -5 1 4 2 2 -540.16264905 -0.53559934 -3074.64016247 -5 1 4 2 3 -0.35349557 1560.05091734 3080.46748332 -5 1 4 2 4 -72109.66765925 67117.96748160 80902.68776351 -5 1 4 2 5 67159.33717483 -72100.41250261 -80923.76895363 -5 1 4 2 6 3054.26596348 889.56623623 -86.89563735 -5 1 4 2 7 -3.64207553 -533.89613675 3077.28602322 -5 1 4 2 8 1552.14547104 -1.56395008 -3070.03400812 -5 1 4 3 1 -0.89980690 3079.84618808 -538.47015513 -5 1 4 3 2 1560.86502834 -3074.46877068 -0.46061543 -5 1 4 3 3 -0.28922365 3080.53175524 1555.08055544 -5 1 4 3 4 -72076.52477192 80899.60271129 67091.98020149 -5 1 4 3 5 67095.01169377 -80910.10045841 -72055.57212564 -5 1 4 3 6 3062.79270501 -92.12308694 891.23730618 -5 1 4 3 7 889.73762802 93.55849317 3056.79399237 -5 1 4 3 8 -530.71467665 -3076.86825574 -0.49275140 -5 2 4 1 1 -1560.00806939 0.36420755 3080.55317921 -5 2 4 1 2 0.64271921 540.07695316 -3074.81155426 -5 2 4 1 3 -3068.90924950 -888.04513410 94.86535557 -5 2 4 1 4 -67116.39281953 72107.97516533 80901.33805316 -5 2 4 1 5 72098.30224120 -67157.10908156 -80923.87607350 -5 2 4 1 6 2.58158883 -1551.67414362 -3069.24132110 -5 2 4 1 7 533.94969668 3.65278752 3077.29673521 -5 2 4 1 8 -890.01613968 -3055.26217825 -86.18864622 -5 2 4 2 1 -3068.25581831 9477.33396039 3067.09892373 -5 2 4 2 2 -540.65540045 0.28922365 1560.21159714 -5 2 4 2 3 1559.59030190 -1.30686240 -536.97047697 -5 2 4 2 4 72115.03436466 -74174.42454916 -72080.83099064 -5 2 4 2 5 -72103.56182674 74162.87702733 72062.02074173 -5 2 4 2 6 -1560.14732522 -0.40705550 542.28362245 -5 2 4 2 7 537.76316400 -0.54631133 -1559.03327859 -5 2 4 2 8 3060.22182817 -9463.93326484 -3055.06936249 -5 2 4 3 1 3080.48890729 -0.29993563 -1555.11269140 -5 2 4 3 2 -3074.68301042 1560.55438072 0.46061543 -5 2 4 3 3 3079.88903603 -0.92123087 538.47015513 -5 2 4 3 4 80899.31348765 -72076.63189179 -67091.89450560 -5 2 4 3 5 -80907.86165316 67097.03625929 72055.50785372 -5 2 4 3 6 -3077.70379071 -531.46451573 -0.00000000 -5 2 4 3 7 93.62276510 889.69478007 -3056.79399237 -5 2 4 3 8 -92.91577396 3062.00001798 -890.76597876 -5 3 4 1 1 537.91313182 3080.66029908 0.43919146 -5 3 4 1 2 -891.15161028 -81.20757233 -3057.43671158 -5 3 4 1 3 -3066.95966790 94.71538776 -888.10940602 -5 3 4 1 4 -67092.34440905 80902.83773132 72062.17070954 -5 3 4 1 5 72059.95332826 -80921.90506792 -67086.06718475 -5 3 4 1 6 6.06298456 -3072.60488497 -1562.19331471 -5 3 4 1 7 -1556.51596168 3074.95081009 -3.55637964 -5 3 4 1 8 3.10647619 -3077.56453488 534.79594364 -5 3 4 2 1 94.73681173 -3066.94895591 888.10940602 -5 3 4 2 2 -81.19686035 -891.10876234 3057.44742357 -5 3 4 2 3 3080.68172306 537.95597976 -0.38563153 -5 3 4 2 4 80902.84844331 -67092.36583302 -72062.02074173 -5 3 4 2 5 -80921.91577991 72059.92119230 67085.89579296 -5 3 4 2 6 -3077.54311091 3.10647619 -534.74238371 -5 3 4 2 7 3074.96152208 -1556.56952161 3.53495566 -5 3 4 2 8 -3072.60488497 6.08440853 1562.17189073 -5 3 4 3 1 536.88478108 -1557.44790453 -2.76369261 -5 3 4 3 2 3057.02965608 -3056.72972045 -9482.85063362 -5 3 4 3 3 1557.44790453 -536.88478108 -2.82796453 -5 3 4 3 4 72064.98796208 -72064.74158639 -74082.62282182 -5 3 4 3 5 -72059.06423335 72056.85756406 74120.05050389 -5 3 4 3 6 -1553.84867695 540.24834495 -7.11275927 -5 3 4 3 7 -3064.05671946 3064.03529549 9465.70074267 -5 3 4 3 8 -539.39138600 1554.68421192 -7.66978259 -5 1 5 1 1 0.77126305 -1.06048670 16.05726829 -5 1 5 1 2 74158.14232914 -67155.81293115 67095.98648458 -5 1 5 1 3 -0.26779967 0.04284795 -8.09826206 -5 1 5 1 4 -74157.97093735 67155.84506711 67095.77224484 -5 1 5 1 5 -2.11026141 -1.92815763 -387.68822819 -5 1 5 1 6 -73990.13552734 -66819.74576761 -66907.41266802 -5 1 5 1 7 1.37113432 1.03906272 8.13039802 -5 1 5 1 8 73990.15695131 66821.92030094 -66912.20092614 -5 1 5 2 1 -0.00000000 0.08569589 2959.14352022 -5 1 5 2 2 -72101.71936500 72101.71936500 -80905.50501605 -5 1 5 2 3 0.01071199 -0.06427192 2959.10067227 -5 1 5 2 4 72101.88004481 -72101.89075679 -80905.79423969 -5 1 5 2 5 -0.06427192 0.29993563 328882.97674338 -5 1 5 2 6 -71808.43587695 -71808.42516497 -80608.60087644 -5 1 5 2 7 0.06427192 -0.08569589 -11773.06271083 -5 1 5 2 8 71808.40374099 71808.26448516 -80608.27951684 -5 1 5 3 1 14.41833430 -11771.85225631 -1.25330246 -5 1 5 3 2 72062.59918902 -80922.22642753 72055.34717392 -5 1 5 3 3 12.57587257 2960.87886209 -0.19281576 -5 1 5 3 4 72062.17070954 -80921.94791587 -72054.97225438 -5 1 5 3 5 -387.76321210 328883.51234273 1.00692676 -5 1 5 3 6 -71879.94910118 -80593.49697498 -71890.75749592 -5 1 5 3 7 -4.11340295 2953.94820660 0.07498391 -5 1 5 3 8 -71879.85269330 -80588.96580454 71890.48969625 -5 2 5 1 1 -0.00000000 0.02142397 2959.18636817 -5 2 5 1 2 -72101.74078898 72101.63366911 -80905.55857598 -5 2 5 1 3 -0.01071199 -0.04284795 2959.16494419 -5 2 5 1 4 72101.86933282 -72101.91218077 -80905.62284790 -5 2 5 1 5 -0.09640788 0.25708768 328883.16955915 -5 2 5 1 6 -71808.35018106 -71808.53228483 -80608.51518055 -5 2 5 1 7 0.02142397 -0.08569589 -11773.00915089 -5 2 5 1 8 71808.42516497 71808.39302900 -80608.39734869 -5 2 5 2 1 0.12854384 -0.09640788 -7.85188636 -5 2 5 2 2 67156.12357877 -74158.05663324 67095.99719656 -5 2 5 2 3 -0.22495172 0.10711987 18.08183381 -5 2 5 2 4 -67155.74865923 74157.99236132 67095.85794074 -5 2 5 2 5 -1.47825419 -1.02835074 -389.61638582 -5 2 5 2 6 -66817.62479421 -73990.13552734 -66907.71260365 -5 2 5 2 7 1.37113432 1.30686240 7.93758226 -5 2 5 2 8 66817.64621819 73990.07125541 -66912.26519806 -5 2 5 3 1 2965.52786438 18.09254579 0.05355993 -5 2 5 3 2 -80923.68325774 72056.15057293 -72055.21863007 -5 2 5 3 3 -11768.79934006 15.44668504 -0.00000000 -5 2 5 3 4 -80923.01911455 72055.52927769 72054.52235093 -5 2 5 3 5 328878.97046030 -384.32466432 0.29993563 -5 2 5 3 6 -80591.86875298 -71878.63152680 -71889.60060134 -5 2 5 3 7 2955.18008508 -3.02078029 -0.01071199 -5 2 5 3 8 -80592.25438450 -71879.03858230 71889.96480889 -5 3 5 1 1 14.50403020 -11771.85225631 -1.28543842 -5 3 5 1 2 72062.38494928 -80922.01218779 72055.16507014 -5 3 5 1 3 12.51160064 2960.90028606 -0.19281576 -5 3 5 1 4 72062.24569345 -80921.92649189 -72055.10079822 -5 3 5 1 5 -387.61324428 328883.38379888 1.52110213 -5 3 5 1 6 -71880.03479708 -80593.66836677 -71890.67180002 -5 3 5 1 7 -4.09197898 2954.00176653 0.22495172 -5 3 5 1 8 -71879.80984535 -80588.98722851 71890.51112022 -5 3 5 2 1 2965.48501644 18.11396977 0.02142397 -5 3 5 2 2 -80923.81180158 72056.08630101 -72055.24005405 -5 3 5 2 3 -11768.74578013 15.55380491 0.06427192 -5 3 5 2 4 -80922.76202687 72055.05795027 72054.09387145 -5 3 5 2 5 328878.61696473 -384.17469650 0.59987126 -5 3 5 2 6 -80591.80448106 -71878.58867885 -71889.34351365 -5 3 5 2 7 2955.26578098 -3.03149228 -0.00000000 -5 3 5 2 8 -80592.34008040 -71879.08143025 71889.85768902 -5 3 5 3 1 0.85695895 -1.04977471 -9.97285976 -5 3 5 3 2 67081.95378180 -67081.96449379 74113.44120800 -5 3 5 3 3 -0.27851166 -0.04284795 -9.23373267 -5 3 5 3 4 -67081.82523796 67081.99662975 74113.32337615 -5 3 5 3 5 -2.04598949 -1.90673366 28.47246106 -5 3 5 3 6 -66906.80208477 -66906.72710086 -74110.49541162 -5 3 5 3 7 1.39255829 1.07119869 -10.62629096 -5 3 5 3 8 66906.83422073 66909.01946604 -74114.80163033 -5 1 6 1 1 -0.96407882 1553.77369304 534.26034430 -5 1 6 1 2 -0.62129524 -1552.55252654 -531.60377156 -5 1 6 1 3 -9459.56277421 -3053.08764492 -3057.90803901 -5 1 6 1 4 9463.10844185 3055.52997792 3062.21425772 -5 1 6 1 5 -73991.82802126 -71805.44723262 -71878.37443912 -5 1 6 1 6 73991.34598185 71801.89085298 71869.24782632 -5 1 6 1 7 -0.92123087 533.96040867 1555.38049107 -5 1 6 1 8 -0.70699113 -533.93898469 -1553.50589337 -5 1 6 2 1 -890.89452260 3056.08700124 90.58056083 -5 1 6 2 2 -1559.83667760 0.82482299 -3077.51097495 -5 1 6 2 3 0.64271921 1557.43719255 3074.04029121 -5 1 6 2 4 -3059.60053293 889.52338828 -93.55849317 -5 1 6 2 5 -66822.94865168 -71804.35460996 -80591.07606595 -5 1 6 2 6 71802.79065988 66839.32727958 80599.21717596 -5 1 6 2 7 -2.67799671 -537.82743592 3077.45741501 -5 1 6 2 8 532.68568223 -1.10333465 -3079.13919695 -5 1 6 3 1 -3.89916321 3073.27974014 -538.95219454 -5 1 6 3 2 542.86206974 -3070.77313522 -0.07498391 -5 1 6 3 3 -4.30621871 3075.06864194 1558.01563984 -5 1 6 3 4 -3054.25525149 -87.21699696 890.10183557 -5 1 6 3 5 -66913.49707655 -80606.32993523 -71895.12798655 -5 1 6 3 6 71873.00773370 80595.38228466 66916.28219313 -5 1 6 3 7 -885.60280109 101.50678742 3068.98423341 -5 1 6 3 8 -1554.43783623 -3080.94952273 0.49275140 -5 2 6 1 1 1558.31557547 -0.20352775 3074.65087446 -5 2 6 1 2 889.73762802 -3059.54697299 -93.65490106 -5 2 6 1 3 3057.00823211 -891.79432949 90.02353751 -5 2 6 1 4 1.69249392 -1560.52224476 -3078.06799826 -5 2 6 1 5 -71806.19707170 -66823.21645135 -80591.16176184 -5 2 6 1 6 66838.00970519 71805.74716825 80599.73135133 -5 2 6 1 7 -537.52750029 -2.93508440 3077.40385508 -5 2 6 1 8 -0.85695895 532.57856236 -3079.06421304 -5 2 6 2 1 -3053.13049287 -9459.53063825 -3057.89732702 -5 2 6 2 2 3055.44428203 9463.12986583 3062.19283375 -5 2 6 2 3 1553.78440503 -0.87838292 534.27105629 -5 2 6 2 4 -1552.57395051 -0.66414318 -531.59305957 -5 2 6 2 5 -71806.10066382 -73992.47074047 -71878.76007064 -5 2 6 2 6 71802.52286021 73992.02083702 71869.80484963 -5 2 6 2 7 534.01396860 -0.86767094 1555.41262703 -5 2 6 2 8 -533.92827271 -0.72841511 -1553.47375741 -5 2 6 3 1 3074.68301042 -4.55259441 1558.21916759 -5 2 6 3 2 -87.23842093 -3054.21240354 890.11254756 -5 2 6 3 3 3071.41585443 -2.61372479 -537.65604413 -5 2 6 3 4 -3070.77313522 542.81922179 -0.06427192 -5 2 6 3 5 -80608.76155624 -66915.48950610 -71896.92760035 -5 2 6 3 6 80600.23481471 71873.74686080 66916.92491234 -5 2 6 3 7 101.05688397 -885.42069732 3068.80212964 -5 2 6 3 8 -3080.91738677 -1554.39498828 0.50346338 -5 3 6 1 1 -539.32711408 3069.44484885 0.35349557 -5 3 6 1 2 3.77061937 -3073.14048431 539.64847369 -5 3 6 1 3 3053.62324426 86.55285377 -891.32300207 -5 3 6 1 4 5.84874482 -3077.12534342 -1554.86631570 -5 3 6 1 5 -71877.87097573 -80588.71942884 -66910.19778460 -5 3 6 1 6 66912.12594223 80611.81447250 71886.60124502 -5 3 6 1 7 1558.22987957 3080.91738677 2.52802890 -5 3 6 1 8 883.63179551 -109.74430531 -3072.56203702 -5 3 6 2 1 86.55285377 3053.75178811 -891.32300207 -5 3 6 2 2 -3076.48262421 4.88466601 -1554.29858040 -5 3 6 2 3 3069.41271289 -539.32711408 0.34278358 -5 3 6 2 4 -3073.23689219 3.59922758 539.73416958 -5 3 6 2 5 -80588.69800487 -71875.71786638 -66910.32632844 -5 3 6 2 6 80611.33243309 66911.16186341 71885.95852581 -5 3 6 2 7 3080.85311485 1558.15489566 2.54945287 -5 3 6 2 8 -109.64789743 883.39613180 -3072.64773292 -5 3 6 3 1 536.17778994 1560.17946118 3.10647619 -5 3 6 3 2 -533.47836926 -1563.91794459 -6.05227257 -5 3 6 3 3 1560.20088515 536.24206187 3.04220427 -5 3 6 3 4 -1563.11454558 -534.27105629 -6.64143185 -5 3 6 3 5 -71893.03914912 -71890.90746373 -74117.05114757 -5 3 6 3 6 71886.49412515 71886.21561349 74133.84754296 -5 3 6 3 7 -3064.48519893 -3064.43163900 -9458.98432692 -5 3 6 3 8 3071.12663078 3070.84811912 9448.22949211 -5 1 7 1 1 -0.12854384 0.06427192 -0.77126305 -5 1 7 1 2 -0.77126305 2.42090903 890.08041160 -5 1 7 1 3 0.10711987 -0.12854384 -0.98550279 -5 1 7 1 4 0.76055107 -2.37806108 889.82332391 -5 1 7 1 5 0.62129524 0.59987126 -4.90608998 -5 1 7 1 6 -0.83553497 -2.22809327 -886.52403196 -5 1 7 1 7 -0.64271921 -0.68556716 -2.32450115 -5 1 7 1 8 0.81411100 2.39948506 -884.39234658 -5 1 7 2 1 -0.08569589 -0.05355993 -3374.52223442 -5 1 7 2 2 537.95597976 534.74238371 91.58748759 -5 1 7 2 3 0.07498391 0.06427192 -2915.86709333 -5 1 7 2 4 -537.92384380 -534.74238371 93.70846099 -5 1 7 2 5 0.65343120 -0.55702332 2950.74532253 -5 1 7 2 6 533.99254463 -537.27041260 101.93526689 -5 1 7 2 7 -0.59987126 0.64271921 2950.69176259 -5 1 7 2 8 -534.05681655 537.23827664 102.05309875 -5 1 7 3 1 0.38563153 -2914.59236690 0.18210378 -5 1 7 3 2 -1558.95829468 3078.60359761 -3060.97166725 -5 1 7 3 3 0.32135961 -574.37673506 0.17139179 -5 1 7 3 4 -1558.94758269 3078.60359761 3060.92881930 -5 1 7 3 5 11.74033759 -11775.06585237 0.77126305 -5 1 7 3 6 1555.18767531 3076.61116805 3068.55575394 -5 1 7 3 7 -4.79897011 2953.48759116 0.85695895 -5 1 7 3 8 1555.12340339 3076.76113587 -3070.80527118 -5 2 7 1 1 -0.06427192 -0.09640788 -2915.96350122 -5 2 7 1 2 -534.69953576 -537.97740374 91.35182388 -5 2 7 1 3 0.05355993 0.08569589 -3374.53294641 -5 2 7 1 4 534.78523165 537.99882771 93.40852536 -5 2 7 1 5 0.56773530 -0.62129524 2950.78817047 -5 2 7 1 6 -537.29183658 534.03539257 101.89241895 -5 2 7 1 7 -0.62129524 0.67485517 2950.67033862 -5 2 7 1 8 537.33468452 -533.96040867 102.01025080 -5 2 7 2 1 -0.08569589 0.16067980 -0.97479080 -5 2 7 2 2 -2.39948506 0.77126305 890.27322736 -5 2 7 2 3 0.11783186 -0.04284795 -0.77126305 -5 2 7 2 4 2.37806108 -0.66414318 890.16610749 -5 2 7 2 5 0.66414318 0.64271921 -4.92751395 -5 2 7 2 6 -2.39948506 -0.77126305 -886.43833607 -5 2 7 2 7 -0.53559934 -0.68556716 -2.41019704 -5 2 7 2 8 2.39948506 0.74983908 -884.39234658 -5 2 7 3 1 -574.50527891 0.34278358 0.17139179 -5 2 7 3 2 3078.51790171 -1558.95829468 3060.99309122 -5 2 7 3 3 -2914.61379087 0.42847947 0.08569589 -5 2 7 3 4 3078.57146165 -1558.87259878 -3060.97166725 -5 2 7 3 5 -11775.08727634 11.74033759 0.85695895 -5 2 7 3 6 3076.71828792 1555.14482736 3068.59860189 -5 2 7 3 7 2953.40189527 -4.77754614 0.87838292 -5 2 7 3 8 3076.80398381 1555.13411537 -3070.77313522 -5 3 7 1 1 -0.66414318 -574.54812685 0.23566371 -5 3 7 1 2 -1556.28029797 3074.74728234 3062.49276938 -5 3 7 1 3 -1.67106995 -2914.36741517 0.21423974 -5 3 7 1 4 -1556.21602604 3074.83297823 -3062.68558514 -5 3 7 1 5 -4.23123481 2952.11645684 0.83553497 -5 3 7 1 6 1557.90851997 3080.51033127 -3066.84183604 -5 3 7 1 7 3.27786798 -11773.74827799 0.84624696 -5 3 7 1 8 1557.88709599 3080.63887511 3064.72086264 -5 3 7 2 1 -2914.41026312 -1.83174975 0.23566371 -5 3 7 2 2 3074.68301042 -1556.25887399 -3062.62131322 -5 3 7 2 3 -574.67667069 -0.70699113 0.12854384 -5 3 7 2 4 3074.69372240 -1556.21602604 3062.34280156 -5 3 7 2 5 2952.10574486 -4.13482693 0.89980690 -5 3 7 2 6 3080.57460319 1557.92994394 -3066.92753194 -5 3 7 2 7 -11773.71614203 3.32071592 0.94265484 -5 3 7 2 8 3080.55317921 1557.96207990 3064.77442258 -5 3 7 3 1 -0.21423974 0.16067980 -3.01006831 -5 3 7 3 2 3.10647619 -3.14932413 9467.72530819 -5 3 7 3 3 0.16067980 -0.23566371 -2.84938850 -5 3 7 3 4 -3.13861215 3.12790016 9467.55391640 -5 3 7 3 5 1.24259047 1.28543842 -13.28286370 -5 3 7 3 6 3.08505221 3.08505221 -9459.36995844 -5 3 7 3 7 -1.19974253 -1.19974253 -1.88530969 -5 3 7 3 8 -3.10647619 -3.01006831 -9455.16014761 -5 1 8 1 1 0.29993563 -1552.85246217 534.90306351 -5 1 8 1 2 -9463.14057781 -3055.46570600 3062.19283375 -5 1 8 1 3 9459.61633414 3053.30188466 -3057.77949516 -5 1 8 1 4 0.66414318 1552.59537449 -531.55021162 -5 1 8 1 5 73992.54572438 71806.34703952 -71878.82434256 -5 1 8 1 6 0.74983908 533.94969668 -1553.49518138 -5 1 8 1 7 0.77126305 -533.75688092 1555.30550716 -5 1 8 1 8 -73991.44238973 -71804.18321817 71869.36565817 -5 1 8 2 1 891.73005757 -3056.94396019 90.00211354 -5 1 8 2 2 3059.64338088 -889.53410027 -93.55849317 -5 1 8 2 3 0.16067980 -1558.27272752 3074.66158644 -5 1 8 2 4 1559.89023753 -0.83553497 -3077.46812700 -5 1 8 2 5 66823.24858731 71804.11894625 -80591.20460979 -5 1 8 2 6 -532.71781819 1.04977471 -3079.09634900 -5 1 8 2 7 2.97793235 537.58106022 3077.42527905 -5 1 8 2 8 -71804.91163328 -66837.13132227 80599.13148006 -5 1 8 3 1 -2.54945287 3071.42656641 537.67746810 -5 1 8 3 2 -3054.22311553 -87.21699696 -890.12325954 -5 1 8 3 3 -4.50974647 3074.70443439 -1558.20845560 -5 1 8 3 4 542.84064577 -3070.80527118 0.08569589 -5 1 8 3 5 -66915.05031464 -80608.23666889 71896.43484895 -5 1 8 3 6 -1554.41641225 -3080.96023471 -0.47132742 -5 1 8 3 7 -885.38856136 101.15329185 -3068.78070566 -5 1 8 3 8 71873.33980530 80600.00986299 -66916.57141678 -5 2 8 1 1 -1557.48004049 -0.55702332 3074.13669909 -5 2 8 1 2 -1.60679803 1560.71506052 -3078.04657429 -5 2 8 1 3 -3056.10842521 890.85167465 90.53771288 -5 2 8 1 4 -890.38034723 3060.41464393 -93.06574178 -5 2 8 1 5 71806.51843131 66820.70984643 -80591.14033787 -5 2 8 1 6 0.78197504 -532.42859455 -3079.13919695 -5 2 8 1 7 537.78458797 2.71013267 3077.41456707 -5 2 8 1 8 -66839.56294329 -71802.41574034 80599.13148006 -5 2 8 2 1 3052.48777366 9460.41973315 -3057.34030370 -5 2 8 2 2 1552.57395051 0.66414318 -531.61448355 -5 2 8 2 3 -1553.69870913 1.13547061 534.35675218 -5 2 8 2 4 -3055.44428203 -9463.16200179 3062.19283375 -5 2 8 2 5 71806.12208779 73992.68498021 -71878.86719051 -5 2 8 2 6 533.92827271 0.72841511 -1553.49518138 -5 2 8 2 7 -534.01396860 1.06048670 1555.32693114 -5 2 8 2 8 -71801.91227696 -73993.55265114 71869.18355440 -5 2 8 3 1 3073.37614802 -2.74226863 -1556.89088122 -5 2 8 3 2 -3070.76242323 542.81922179 0.07498391 -5 2 8 3 3 3071.64080615 -2.22809327 537.84885989 -5 2 8 3 4 -87.23842093 -3054.24453950 -890.08041160 -5 2 8 3 5 -80607.18689418 -66913.32568476 71895.51361808 -5 2 8 3 6 -3080.93881074 -1554.39498828 -0.47132742 -5 2 8 3 7 100.94976410 -885.04577778 -3068.96280944 -5 2 8 3 8 80600.09555888 71869.11928247 -66916.71067260 -5 3 8 1 1 -539.28426613 3069.38057693 -0.37491954 -5 3 8 1 2 5.84874482 -3077.11463143 1554.90916365 -5 3 8 1 3 3053.63395625 86.57427775 891.30157810 -5 3 8 1 4 3.77061937 -3073.14048431 -539.66989766 -5 3 8 1 5 -71877.63531202 -80588.44091718 66910.15493665 -5 3 8 1 6 883.57823558 -109.71216935 3072.58346099 -5 3 8 1 7 1558.20845560 3080.87453882 -2.54945287 -5 3 8 1 8 66911.91170249 80611.54667283 -71886.24774945 -5 3 8 2 1 86.57427775 3053.65538023 891.34442605 -5 3 8 2 2 -3073.16190828 3.58851560 -539.77701753 -5 3 8 2 3 3069.42342487 -539.28426613 -0.29993563 -5 3 8 2 4 -3076.52547216 4.92751395 1554.28786841 -5 3 8 2 5 -80588.40878122 -71875.54647459 66910.24063255 -5 3 8 2 6 -109.64789743 883.37470783 3072.66915689 -5 3 8 2 7 3080.89596279 1558.16560765 -2.57087684 -5 3 8 2 8 80610.91466560 66911.06545553 -71885.70143812 -5 3 8 3 1 -536.75623723 -1559.35463819 3.94201116 -5 3 8 3 2 1563.15739352 534.28176827 -6.59858390 -5 3 8 3 3 -1560.15803721 -535.98497418 3.40641182 -5 3 8 3 4 533.47836926 1563.90723260 -6.17010443 -5 3 8 3 5 71893.06057309 71891.14312744 -74116.75121194 -5 3 8 3 6 -3071.10520681 -3070.80527118 9448.22949211 -5 3 8 3 7 3064.97795033 3065.21361404 -9458.15950393 -5 3 8 3 8 -71886.55839707 -71888.36872285 74131.80155347 -6 1 1 1 1 74113.83755151 -72001.92649548 72006.23271419 -6 1 1 1 2 0.49275140 -1558.28343951 535.74931047 -6 1 1 1 3 -0.62129524 537.95597976 -1559.68670978 -6 1 1 1 4 -9472.03152690 3065.23503801 -3066.41335657 -6 1 1 1 5 -0.95336683 1557.77997612 -539.79844150 -6 1 1 1 6 -74107.15327172 71997.17037332 -71995.04939992 -6 1 1 1 7 9466.41844579 -3061.80720222 3061.16448301 -6 1 1 1 8 -0.02142397 -536.08138206 1557.85496003 -6 1 1 2 1 -72004.34740451 67024.50539631 -80796.18919021 -6 1 1 2 2 889.35199649 3066.01701305 -95.09030729 -6 1 1 2 3 -537.75245201 0.34278358 3077.44670303 -6 1 1 2 4 1.77818982 1561.95765100 -3081.64580187 -6 1 1 2 5 1553.42019748 0.21423974 3070.14112799 -6 1 1 2 6 67035.67799859 -72006.46837791 80811.55017936 -6 1 1 2 7 3061.33587480 889.93044378 90.86978447 -6 1 1 2 8 0.57844729 -536.67054134 -3076.99679958 -6 1 1 3 1 72007.83951222 -80795.30009530 67033.78197692 -6 1 1 3 2 -1.39255829 -3078.06799826 -538.18093149 -6 1 1 3 3 -1558.04777580 3077.53239892 0.27851166 -6 1 1 3 4 -2.86010049 -3080.14612371 1557.13725691 -6 1 1 3 5 536.22063789 3076.67543997 1.88530969 -6 1 1 3 6 -67028.31886363 80799.95980959 -72006.42552996 -6 1 1 3 7 -3061.97859401 91.88742323 890.48746710 -6 1 1 3 8 -891.51581784 -92.55156641 3061.18590698 -6 2 1 1 1 -67017.46762094 72015.89492634 -80796.97116525 -6 2 1 1 2 -1561.78625921 -1.85317373 -3081.82790565 -6 2 1 1 3 -0.57844729 538.57727500 3077.33958316 -6 2 1 1 4 -3065.10649417 -888.70927728 -95.70089055 -6 2 1 1 5 -891.71934559 -3053.55897234 86.16722225 -6 2 1 1 6 71999.35561863 -67052.19588232 80811.67872320 -6 2 1 1 7 0.44990345 -1557.58716036 3076.32194441 -6 2 1 1 8 536.88478108 -0.51417537 -3076.93252766 -6 2 1 2 1 72011.80294736 -74112.61638501 72011.03168430 -6 2 1 2 2 -3064.61374278 9472.93133380 -3065.78134934 -6 2 1 2 3 -537.46322837 -0.70699113 -1558.44411931 -6 2 1 2 4 1558.21916759 -0.34278358 535.87785431 -6 2 1 2 5 3056.94396019 -9458.51299949 3054.97295461 -6 2 1 2 6 -72002.16215919 74100.51183987 -71998.43438777 -6 2 1 2 7 -1558.82975084 -1.47825419 -537.10973280 -6 2 1 2 8 536.13494200 0.16067980 1557.81211209 -6 2 1 3 1 -80798.84576295 72015.87350236 -67033.67485705 -6 2 1 3 2 -3080.18897166 -2.88152446 -1557.11583294 -6 2 1 3 3 3077.13605541 -1559.92237350 -0.25708768 -6 2 1 3 4 -3078.10013422 -1.41398226 538.17021950 -6 2 1 3 5 89.61648201 -3058.44363835 -892.09426513 -6 2 1 3 6 80806.74049726 -67036.98486099 72006.25413817 -6 2 1 3 7 3076.16126460 535.37439093 -0.02142397 -6 2 1 3 8 -92.57299038 -891.53724181 -3061.19661897 -6 3 1 1 1 67029.91494967 -80801.69515146 72004.17601272 -6 3 1 1 2 -540.07695316 -3079.37486066 -0.85695895 -6 3 1 1 3 888.90209304 90.36632109 -3062.66416117 -6 3 1 1 4 3063.45684820 -93.02289383 -888.81639715 -6 3 1 1 5 -2.19595730 3073.89032339 536.15636597 -6 3 1 1 6 -71997.19179729 80810.32901286 -67028.00821601 -6 3 1 1 7 -0.51417537 3076.69686395 -1559.55816594 -6 3 1 1 8 1557.71570420 -3077.29673521 -0.34278358 -6 3 1 2 1 -80804.71593175 67032.88217003 -72004.62591617 -6 3 1 2 2 -92.80865410 3063.38186429 888.76283721 -6 3 1 2 3 90.61269679 889.00921291 3062.72843309 -6 3 1 2 4 -3078.46434178 -539.45565792 0.19281576 -6 3 1 2 5 3072.49776510 -1.86388571 1561.55059550 -6 3 1 2 6 80813.09270547 -72002.07646330 67026.70135361 -6 3 1 2 7 3076.97537560 0.19281576 -535.59934265 -6 3 1 2 8 -3077.12534342 1557.80140010 0.42847947 -6 3 1 3 1 71999.93406592 -71999.81623407 74099.97624053 -6 3 1 3 2 536.34918173 -1559.29036627 2.34592512 -6 3 1 3 3 3062.88911289 -3062.70700912 9469.33210622 -6 3 1 3 4 1559.34392621 -536.30633379 2.33521313 -6 3 1 3 5 -537.06688485 1558.74405494 3.72777142 -6 3 1 3 6 -72001.54086395 72000.79102487 -74115.23010981 -6 3 1 3 7 -1558.61551110 537.17400472 2.88152446 -6 3 1 3 8 -3061.33587480 3061.33587480 -9465.43294300 -6 1 2 1 1 0.14996782 886.35264017 -1.09262266 -6 1 2 1 2 0.17139179 2.39948506 8.77311723 -6 1 2 1 3 -0.25708768 -886.41691209 -1.02835074 -6 1 2 1 4 0.13925583 -0.00000000 -0.36420755 -6 1 2 1 5 -0.40705550 891.28015412 3.25644400 -6 1 2 1 6 0.13925583 -2.29236519 -8.82667717 -6 1 2 1 7 -0.12854384 -891.36585002 -1.09262266 -6 1 2 1 8 0.12854384 0.08569589 0.29993563 -6 1 2 2 1 -1558.50839123 3063.32830435 -3078.06799826 -6 1 2 2 2 1.82103777 4.73469819 -2955.21222105 -6 1 2 2 3 1558.67978302 -3063.28545641 -3078.11084621 -6 1 2 2 4 -0.66414318 -0.06427192 573.69116790 -6 1 2 2 5 -1552.65964641 -3060.80027546 -3072.41206920 -6 1 2 2 6 -6.35220820 0.70699113 11771.70228850 -6 1 2 2 7 1557.65143228 3055.29431421 -3075.62566526 -6 1 2 2 8 0.06427192 0.11783186 2914.09961550 -6 1 2 3 1 535.49222279 -92.25163078 -538.25591539 -6 1 2 3 2 6.34149622 -2959.42203188 -1.27472644 -6 1 2 3 3 535.57791868 -94.50114802 538.08452360 -6 1 2 3 4 -0.18210378 2914.83874260 -1.07119869 -6 1 2 3 5 -531.85014726 -91.52321567 539.58420176 -6 1 2 3 6 -7.61622265 -2962.63562793 -0.38563153 -6 1 2 3 7 -538.77009076 -88.52385935 -536.00639816 -6 1 2 3 8 0.92123087 3373.89022720 -0.63200722 -6 2 2 1 1 -1561.14354000 -3065.92060517 -3079.61052437 -6 2 2 1 2 6.34149622 0.83553497 11784.49240080 -6 2 2 1 3 1561.16496397 3065.96345312 -3079.56767642 -6 2 2 1 4 -0.13925583 0.08569589 2915.24579810 -6 2 2 1 5 -1560.30800502 3053.53754837 -3077.08249547 -6 2 2 1 6 -1.69249392 4.64900229 -2964.13530609 -6 2 2 1 7 1555.20909928 -3059.30059730 -3074.14741108 -6 2 2 1 8 0.70699113 -0.11783186 574.59097480 -6 2 2 2 1 -0.36420755 9473.85256467 -1.99242955 -6 2 2 2 2 -0.68556716 -4.01699507 6.33078423 -6 2 2 2 3 0.44990345 -9471.66731935 -1.88530969 -6 2 2 2 4 -0.66414318 -0.02142397 -0.23566371 -6 2 2 2 5 1.15689458 9463.50478537 5.74162495 -6 2 2 2 6 0.51417537 2.16382134 -6.27722430 -6 2 2 2 7 0.51417537 -9463.48336139 -1.99242955 -6 2 2 2 8 -0.81411100 -0.31064762 0.29993563 -6 2 2 3 1 -3080.68172306 -3067.16319565 -1556.43026578 -6 2 2 3 2 11785.79926320 7.56266272 -2.91366042 -6 2 2 3 3 -3080.70314703 -3069.36986494 1556.28029797 -6 2 2 3 4 573.11272061 -0.32135961 -1.13547061 -6 2 2 3 5 -3078.08942224 3062.57846527 -1554.60922802 -6 2 2 3 6 -2962.35711628 7.47696682 -0.19281576 -6 2 2 3 7 -3072.96909252 3057.82234311 1559.83667760 -6 2 2 3 8 2915.93136525 1.29615041 -0.76055107 -6 3 2 1 1 -539.07002640 -90.75195262 536.56342147 -6 3 2 1 2 6.47004006 -2961.05025388 -0.42847947 -6 3 2 1 3 -538.98433050 -90.88049646 -536.54199750 -6 3 2 1 4 -0.78197504 3371.83352572 -0.62129524 -6 3 2 1 5 542.24077450 -87.02418119 -534.18536039 -6 3 2 1 6 -5.08819376 -2964.28527391 -1.26401445 -6 3 2 1 7 535.19228715 -92.16593488 537.72031605 -6 3 2 1 8 0.04284795 2914.21744736 -1.08191067 -6 3 2 2 1 -3078.13227018 3061.57153851 -1558.97971865 -6 3 2 2 2 -2959.55057572 -3.88845123 1.52110213 -6 3 2 2 3 -3078.11084621 3061.48584261 1558.93687070 -6 3 2 2 4 2913.72469596 -0.53559934 0.96407882 -6 3 2 2 5 -3070.33394376 -3054.39450732 -1562.53609829 -6 3 2 2 6 11772.94487897 -3.98485911 1.60679803 -6 3 2 2 7 -3075.47569744 -3061.44299467 1557.33007268 -6 3 2 2 8 574.69809467 1.08191067 1.01763875 -6 3 2 3 1 0.10711987 885.32428943 2.57087684 -6 3 2 3 2 -1.22116650 1.61751001 -3.87773924 -6 3 2 3 3 -0.12854384 -885.40998533 2.48518095 -6 3 2 3 4 0.97479080 -0.47132742 -1.90673366 -6 3 2 3 5 -0.47132742 890.10183557 -7.32699901 -6 3 2 3 6 0.07498391 0.19281576 3.94201116 -6 3 2 3 7 -0.21423974 -892.26565692 2.42090903 -6 3 2 3 8 0.74983908 0.86767094 1.98171757 -6 1 3 1 1 -0.87838292 -537.30254856 -1558.04777580 -6 1 3 1 2 -0.14996782 1558.30486348 536.01711014 -6 1 3 1 3 -74115.85140504 72014.97369547 72011.54585967 -6 1 3 1 4 9472.87777386 -3064.69943867 -3065.55639762 -6 1 3 1 5 -9460.51614104 3056.00130535 3053.43042850 -6 1 3 1 6 74104.26103527 -72005.99705048 -71997.49173292 -6 1 3 1 7 -0.49275140 -1556.81589731 -538.58798699 -6 1 3 1 8 0.85695895 535.47079881 1558.76547892 -6 1 3 2 1 538.57727500 -0.53559934 3077.28602322 -6 1 3 2 2 -889.24487662 -3065.89918120 -94.94033948 -6 1 3 2 3 72016.10916607 -67015.60373523 -80799.33851435 -6 1 3 2 4 -1.82103777 -1562.04334689 -3081.53868200 -6 1 3 2 5 -3053.55897234 -891.70863360 86.21007019 -6 1 3 2 6 -67052.36727411 71999.33419466 80812.21432255 -6 1 3 2 7 -1557.60858433 0.46061543 3076.39692831 -6 1 3 2 8 0.02142397 536.01711014 -3076.11841666 -6 1 3 3 1 -1559.77240568 3077.32887117 -0.17139179 -6 1 3 3 2 -1.39255829 -3078.07871025 538.40588321 -6 1 3 3 3 72015.19864719 -80797.75314029 -67035.14239925 -6 1 3 3 4 -2.93508440 -3080.21039563 -1556.92301718 -6 1 3 3 5 -3058.52933424 89.85214572 -892.13711307 -6 1 3 3 6 -67037.62758020 80805.05871533 72006.91828135 -6 1 3 3 7 536.04924610 3077.13605541 -0.62129524 -6 1 3 3 8 -890.83025068 -93.24784556 -3060.23254015 -6 2 3 1 1 0.19281576 -537.87028387 3077.59667084 -6 2 3 1 2 1561.91480305 1.73534187 -3081.77434571 -6 2 3 1 3 67023.36992570 -72003.36190172 -80795.28938332 -6 2 3 1 4 3066.00630107 889.37342047 -95.07959531 -6 2 3 1 5 -0.65343120 1552.78819025 3069.58410468 -6 2 3 1 6 -72004.07960484 67035.39948694 80811.31451565 -6 2 3 1 7 889.78047597 3061.44299467 90.73052865 -6 2 3 1 8 -536.64911737 0.59987126 -3077.00751156 -6 2 3 2 1 538.02025168 -0.68556716 -1559.64386184 -6 2 3 2 2 3064.65659072 -9472.86706188 -3065.59924557 -6 2 3 2 3 -72001.80866362 74115.74428517 72003.72610927 -6 2 3 2 4 -1558.27272752 0.19281576 536.02782213 -6 2 3 2 5 1557.71570420 -0.98550279 -539.84128945 -6 2 3 2 6 71996.88114967 -74107.15327172 -71994.57807250 -6 2 3 2 7 -3061.87147414 9466.45058175 3061.14305904 -6 2 3 2 8 -535.47079881 -0.83553497 1558.78690289 -6 2 3 3 1 3076.99679958 -1558.28343951 0.49275140 -6 2 3 3 2 -3080.36036345 -2.81725254 1556.80518532 -6 2 3 3 3 -80795.66430286 72009.53200615 67037.97036378 -6 2 3 3 4 -3078.92495721 -1.99242955 -539.02717845 -6 2 3 3 5 3073.98673127 534.33532821 -0.00000000 -6 2 3 3 6 80806.00137017 -67027.96536806 -72006.76831354 -6 2 3 3 7 91.39467183 -3061.70008235 890.16610749 -6 2 3 3 8 -93.42994933 -890.94808253 3060.32894803 -6 3 3 1 1 888.40934165 91.44823176 3061.93574606 -6 3 3 1 2 -539.88413740 -3079.44984457 0.89980690 -6 3 3 1 3 67030.78262060 -80802.25217477 -72004.92585180 -6 3 3 1 4 3064.35665509 -92.35875065 889.48054033 -6 3 3 1 5 -1.83174975 3072.77627676 1561.29350781 -6 3 3 1 6 -72000.46966527 80809.45062994 67027.53688859 -6 3 3 1 7 0.74983908 3077.80019859 -536.42416564 -6 3 3 1 8 1557.86567202 -3077.22175130 0.24637570 -6 3 3 2 1 91.00904030 888.22723787 -3061.72150633 -6 3 3 2 2 -92.80865410 3063.37115230 -888.78426119 -6 3 3 2 3 -80804.21246837 67030.08634146 72004.66876411 -6 3 3 2 4 -3078.46434178 -539.41280997 -0.17139179 -6 3 3 2 5 3073.79391551 -2.31378916 536.32775776 -6 3 3 2 6 80810.86461220 -71997.42746100 -67030.32200517 -6 3 3 2 7 3076.78255984 -0.37491954 -1559.40819813 -6 3 3 2 8 -3077.08249547 1557.77997612 -0.41776749 -6 3 3 3 1 -3062.42849746 3063.36044031 9469.44993807 -6 3 3 3 2 -536.30633379 1559.32250223 2.37806108 -6 3 3 3 3 -72000.33040944 72001.32662422 74100.83319948 -6 3 3 3 4 -1559.31179024 536.30633379 2.31378916 -6 3 3 3 5 1559.47247005 -536.04924610 4.15625090 -6 3 3 3 6 71998.75574737 -72005.97562651 -74115.16583788 -6 3 3 3 7 538.66297089 -1556.82660929 1.63893399 -6 3 3 3 8 3061.33587480 -3061.34658679 -9465.37938307 -6 1 4 1 1 -9471.60304743 0.40705550 -2.03527750 -6 1 4 1 2 0.14996782 -0.62129524 -0.07498391 -6 1 4 1 3 9473.91683659 -0.40705550 -1.88530969 -6 1 4 1 4 -3.07434023 -1.43540624 6.87709556 -6 1 4 1 5 9463.41908947 1.26401445 5.82732085 -6 1 4 1 6 3.12790016 1.30686240 -6.85567159 -6 1 4 1 7 -9465.73287863 0.42847947 -2.03527750 -6 1 4 1 8 -0.10711987 -0.95336683 0.19281576 -6 1 4 2 1 3066.00630107 1561.10069205 -3079.50340450 -6 1 4 2 2 -0.08569589 -0.05355993 2915.09583028 -6 1 4 2 3 -3063.82105575 -1561.12211602 -3079.52482848 -6 1 4 2 4 -0.03213596 5.76304893 11783.78540967 -6 1 4 2 5 3053.64466824 -1560.37227694 -3077.03964753 -6 1 4 2 6 3.79204335 -1.11404663 -2963.51401086 -6 1 4 2 7 -3059.21490140 1555.18767531 -3074.08313915 -6 1 4 2 8 -0.21423974 0.61058325 574.69809467 -6 1 4 3 1 -3065.02079828 -3080.63887511 1556.40884181 -6 1 4 3 2 -0.49275140 573.36980830 -0.94265484 -6 1 4 3 3 -3067.18461962 -3080.70314703 -1556.36599386 -6 1 4 3 4 6.69499178 11783.80683364 -0.98550279 -6 1 4 3 5 3062.64273719 -3078.04657429 -1554.69492391 -6 1 4 3 6 6.63071986 -2960.45038262 -2.07812545 -6 1 4 3 7 3055.57282587 -3072.92624457 1559.90094952 -6 1 4 3 8 1.15689458 2915.63142962 -1.06048670 -6 2 4 1 1 -3065.47070172 1558.52981520 -3078.11084621 -6 2 4 1 2 -0.36420755 -0.83553497 573.34838433 -6 2 4 1 3 3065.38500583 -1558.46554328 -3078.02515032 -6 2 4 1 4 2.83867652 3.06362824 -2957.81523385 -6 2 4 1 5 -3060.86454738 -1552.59537449 -3072.75485278 -6 2 4 1 6 -0.93194286 -7.69120656 11774.29458932 -6 2 4 1 7 3059.60053293 1557.73712818 -3075.58281731 -6 2 4 1 8 -0.21423974 0.27851166 2914.35670319 -6 2 4 2 1 -886.37406415 -0.14996782 -1.22116650 -6 2 4 2 2 -0.08569589 0.09640788 -0.26779967 -6 2 4 2 3 886.35264017 0.10711987 -1.11404663 -6 2 4 2 4 2.36734909 0.21423974 8.76240525 -6 2 4 2 5 891.21588220 -0.47132742 3.29929195 -6 2 4 2 6 -2.32450115 0.23566371 -8.80525319 -6 2 4 2 7 -891.25873015 -0.17139179 -1.00692676 -6 2 4 2 8 0.08569589 0.07498391 0.27851166 -6 2 4 3 1 -96.62212141 535.49222279 538.29876334 -6 2 4 3 2 2915.35291796 -0.07498391 -1.41398226 -6 2 4 3 3 -92.25163078 535.49222279 -538.34161129 -6 2 4 3 4 -2956.61549132 5.80589687 -3.23502003 -6 2 4 3 5 -95.85085836 -531.78587534 539.45565792 -6 2 4 3 6 -2959.88264731 -7.04848735 1.47825419 -6 2 4 3 7 -88.45958743 -538.77009076 -536.02782213 -6 2 4 3 8 3374.40440257 0.86767094 -0.29993563 -6 3 4 1 1 3061.50726659 -3078.17511813 1558.95829468 -6 3 4 1 2 -0.96407882 2913.74611994 0.69627915 -6 3 4 1 3 3063.73535985 -3078.06799826 -1558.89402276 -6 3 4 1 4 -5.72020098 -2959.44345585 -1.00692676 -6 3 4 1 5 -3056.57975264 -3070.26967183 -1562.62179418 -6 3 4 1 6 -5.83803283 11772.90203103 4.11340295 -6 3 4 1 7 -3056.92253622 -3075.51854539 1557.35149665 -6 3 4 1 8 0.70699113 574.76236659 1.43540624 -6 3 4 2 1 -90.75195262 -539.04860242 -536.49914955 -6 3 4 2 2 3371.42647022 -0.93194286 -0.61058325 -6 3 4 2 3 -90.75195262 -539.02717845 536.71338929 -6 3 4 2 4 -2962.88200363 7.66978259 -0.53559934 -6 3 4 2 5 -84.83893588 542.26219848 -534.18536039 -6 3 4 2 6 -2966.17058360 -6.32007224 -1.28543842 -6 3 4 2 7 -90.00211354 535.23513510 537.82743592 -6 3 4 2 8 2913.85323981 0.23566371 -1.19974253 -6 3 4 3 1 -885.30286546 -0.10711987 2.42090903 -6 3 4 3 2 -0.77126305 0.97479080 -2.08883744 -6 3 4 3 3 887.53095873 0.17139179 2.48518095 -6 3 4 3 4 -0.21423974 -1.13547061 -3.81346732 -6 3 4 3 5 892.30850486 -0.47132742 -7.45554285 -6 3 4 3 6 -1.61751001 0.12854384 3.92058719 -6 3 4 3 7 -892.28708089 -0.17139179 2.44233300 -6 3 4 3 8 0.42847947 0.79268703 1.96029359 -6 1 5 1 1 -0.87838292 1553.68799715 534.31390423 -6 1 5 1 2 -0.64271921 -1552.60608647 -531.60377156 -6 1 5 1 3 -9459.57348619 -3053.10906890 -3057.90803901 -6 1 5 1 4 9463.14057781 3055.44428203 3062.17140977 -6 1 5 1 5 -73991.75303735 -71805.36153673 -71877.94595964 -6 1 5 1 6 73991.22814999 71801.93370093 71869.20497837 -6 1 5 1 7 -0.89980690 533.93898469 1555.42333902 -6 1 5 1 8 -0.70699113 -533.93898469 -1553.49518138 -6 1 5 2 1 1558.37984739 -0.21423974 3074.67229843 -6 1 5 2 2 889.58766020 -3059.58982094 -93.55849317 -6 1 5 2 3 3056.93324820 -891.81575347 90.04496149 -6 1 5 2 4 0.81411100 -1559.85810157 -3077.48955097 -6 1 5 2 5 -71803.86185857 -66823.04505956 -80590.94752211 -6 1 5 2 6 66836.87423459 71804.78308944 80598.87439238 -6 1 5 2 7 -537.57034824 -2.94579638 3077.39314309 -6 1 5 2 8 -1.04977471 532.70710620 -3079.16062092 -6 1 5 3 1 -539.11287434 3069.48769679 0.32135961 -6 1 5 3 2 3.79204335 -3073.15119630 539.62704971 -6 1 5 3 3 3054.56589911 85.93155854 -892.00856923 -6 1 5 3 4 5.83803283 -3077.14676739 -1554.97343557 -6 1 5 3 5 -71877.08900069 -80588.14098155 -66909.68360923 -6 1 5 3 6 66910.07995274 80611.85732045 71886.68694091 -6 1 5 3 7 1558.37984739 3080.79955491 2.63514877 -6 1 5 3 8 883.56752359 -109.74430531 -3072.59417298 -6 2 5 1 1 -890.91594657 3056.14056118 90.54842487 -6 2 5 1 2 -1560.11518926 0.74983908 -3077.40385508 -6 2 5 1 3 0.61058325 1557.50146447 3074.06171518 -6 2 5 1 4 -3060.48962784 890.18753147 -92.89434999 -6 2 5 1 5 -66820.81696630 -71804.46172983 -80591.11891390 -6 2 5 1 6 71801.78373312 66838.74883229 80598.74584854 -6 2 5 1 7 -2.72084466 -537.81672393 3077.43599104 -6 2 5 1 8 532.53571441 -0.95336683 -3079.24631682 -6 2 5 2 1 -3053.30188466 -9459.64847010 -3057.79020715 -6 2 5 2 2 3055.46570600 9463.12986583 3062.20354573 -6 2 5 2 3 1552.85246217 -0.25708768 534.91377550 -6 2 5 2 4 -1552.61679846 -0.64271921 -531.63590752 -6 2 5 2 5 -71806.62555117 -73992.68498021 -71879.01715833 -6 2 5 2 6 71804.30105003 73991.54950960 71869.63345784 -6 2 5 2 7 533.75688092 -0.81411100 1555.32693114 -6 2 5 2 8 -533.94969668 -0.70699113 -1553.49518138 -6 2 5 3 1 86.42430993 3053.54826036 -891.22659419 -6 2 5 3 2 -3076.28980845 4.97036190 -1554.36285232 -6 2 5 3 3 3068.44863407 -538.68439487 0.94265484 -6 2 5 3 4 -3072.30494934 2.95650837 539.17714626 -6 2 5 3 5 -80591.60095331 -71876.12492188 -66910.66911202 -6 2 5 3 6 80614.12826166 66911.76173468 71886.42985323 -6 2 5 3 7 3080.70314703 1558.29415149 2.47446896 -6 2 5 3 8 -109.49792961 883.28901193 -3072.56203702 -6 3 5 1 1 -3.87773924 3073.26902815 -538.97361851 -6 3 5 1 2 542.84064577 -3070.80527118 -0.04284795 -6 3 5 1 3 -4.34906666 3075.02579400 1558.05848778 -6 3 5 1 4 -3054.26596348 -87.23842093 890.16610749 -6 3 5 1 5 -66913.88270808 -80606.67271881 -71895.51361808 -6 3 5 1 6 71873.55404503 80595.83218811 66916.83921645 -6 3 5 1 7 -885.58137712 101.47465146 3069.01636937 -6 3 5 1 8 -1554.41641225 -3080.92809875 0.49275140 -6 3 5 2 1 3073.91174736 -3.68492348 1557.70499222 -6 3 5 2 2 -87.21699696 -3054.24453950 890.14468352 -6 3 5 2 3 3070.64459137 -1.75676584 -537.09902081 -6 3 5 2 4 -3070.79455919 542.81922179 -0.04284795 -6 3 5 2 5 -80608.42948465 -66914.67539510 -71896.45627292 -6 3 5 2 6 80602.07727645 71871.11171203 66916.53928081 -6 3 5 2 7 100.88549218 -885.18503361 3068.82355361 -6 3 5 2 8 -3080.93881074 -1554.38427629 0.47132742 -6 3 5 3 1 535.34225497 1561.00428417 2.81725254 -6 3 5 3 2 -533.45694528 -1563.89652062 -6.07369655 -6 3 5 3 3 1559.45104607 536.92762902 3.81346732 -6 3 5 3 4 -1563.13596955 -534.27105629 -6.53431198 -6 3 5 3 5 -71892.86775733 -71890.20047260 -74116.23703657 -6 3 5 3 6 71888.96859411 71884.39457573 74132.30501685 -6 3 5 3 7 -3065.29930993 -3064.78513457 -9458.09523201 -6 3 5 3 8 3071.21232668 3070.83740714 9448.26162808 -6 1 6 1 1 -74108.86718962 67033.99621666 -67027.94394409 -6 1 6 1 2 0.94265484 -7.85188636 -8.58030147 -6 1 6 1 3 74100.05122443 -67048.70377461 -67036.38498973 -6 1 6 1 4 3.67421149 3.17074811 5.16317766 -6 1 6 1 5 73986.62199565 66835.49238828 66912.55442171 -6 1 6 1 6 120.60625998 218.71734757 126.29432500 -6 1 6 1 7 -74102.76135711 -67030.26844523 67035.78511846 -6 1 6 1 8 -0.29993563 -4.61686633 -6.82353563 -6 1 6 2 1 71997.72739663 -72005.91135459 80806.21560991 -6 1 6 2 2 -3.70634745 1.02835074 -2960.10759904 -6 1 6 2 3 -72005.90064260 71997.66312471 80804.07321254 -6 1 6 2 4 -2.50660492 -0.59987126 -2960.06475109 -6 1 6 2 5 71805.62933640 71801.24813377 80611.08605739 -6 1 6 2 6 219.38149075 221.69527991 -328882.41972007 -6 1 6 2 7 -72008.63219925 -72012.83129810 80808.80791073 -6 1 6 2 8 -2.24951724 -2.37806108 11772.36643168 -6 1 6 3 1 -71994.25671289 80814.11034422 -72003.69397331 -6 1 6 3 2 -9.12661280 11771.12384121 -0.88909491 -6 1 6 3 3 -71997.77024458 80814.46383978 72003.19050993 -6 1 6 3 4 -7.32699901 -2964.62805749 -1.41398226 -6 1 6 3 5 71865.99138231 80595.68222030 71885.44435044 -6 1 6 3 6 126.64782056 -328878.02780546 115.13243470 -6 1 6 3 7 72010.58178086 80799.48848216 -72005.41860319 -6 1 6 3 8 5.09890574 -2952.14859281 7.96971822 -6 2 6 1 1 71997.98448432 -72006.48980188 80806.76192124 -6 2 6 1 2 -3.64207553 0.99621478 -2960.13973500 -6 2 6 1 3 -72005.86850664 71997.29891716 80803.90182075 -6 2 6 1 4 -2.47446896 -0.57844729 -2960.08617506 -6 2 6 1 5 71805.05088911 71800.43402277 80610.40049023 -6 2 6 1 6 219.60644248 223.98764510 -328882.22690430 -6 2 6 1 7 -72008.73931912 -72013.22764161 80809.01143848 -6 2 6 1 8 -2.29236519 -2.41019704 11772.27002380 -6 2 6 2 1 -67051.63885901 74101.29381491 -67037.45618841 -6 2 6 2 2 3.59922758 3.70634745 5.31314548 -6 2 6 2 3 67035.00314342 -74109.18854922 -67028.58666330 -6 2 6 2 4 -6.14868045 1.09262266 -7.28415106 -6 2 6 2 5 66839.43439945 73988.12167381 66914.09694781 -6 2 6 2 6 218.62093968 117.68188757 125.30882221 -6 2 6 2 7 -67034.73534375 -74102.69708519 67035.95651025 -6 2 6 2 8 -4.11340295 -0.34278358 -7.03777536 -6 2 6 3 1 80810.80034028 -71998.15587611 72003.28691781 -6 2 6 3 2 -2964.13530609 -7.68049457 -1.53181412 -6 2 6 3 3 80812.82490580 -71994.81373621 -72004.45452438 -6 2 6 3 4 11774.00536567 -7.19845517 -1.58537405 -6 2 6 3 5 80596.59273918 71866.76264537 71886.21561349 -6 2 6 3 6 -328878.56340480 124.62325505 115.75372993 -6 2 6 3 7 80800.32401714 72011.14951616 -72006.03989843 -6 2 6 3 8 -2951.62370545 5.37741740 8.05541411 -6 3 6 1 1 -71993.80680944 80814.76377542 -72003.28691781 -6 3 6 1 2 -8.95522101 11771.27380902 -0.73912709 -6 3 6 1 3 -71996.84901371 80814.72092747 72001.17665640 -6 3 6 1 4 -7.53052676 -2964.67090544 -1.24259047 -6 3 6 1 5 71869.04429857 80598.61730469 71888.22946702 -6 3 6 1 6 121.34538707 -328881.92696867 111.68317493 -6 3 6 1 7 72011.16022815 80800.04550548 -72004.90442782 -6 3 6 1 8 5.76304893 -2952.74846407 8.92308505 -6 3 6 2 1 80810.54325260 -71997.84522849 72003.58685344 -6 3 6 2 2 -2964.26384994 -7.83046239 -1.66035796 -6 3 6 2 3 80812.81419381 -71994.98512800 -72001.81937561 -6 3 6 2 4 11774.05892561 -7.06991132 -1.73534187 -6 3 6 2 5 80597.86746561 71868.09093174 71888.01522728 -6 3 6 2 6 -328877.37437426 124.04480776 110.18349677 -6 3 6 2 7 80798.52440335 72009.45702224 -72003.74753324 -6 3 6 2 8 -2952.30927261 6.09512052 7.20916715 -6 3 6 3 1 -67028.88659893 67027.62258448 -74118.59367368 -6 3 6 3 2 -1.15689458 3.41712381 3.37427586 -6 3 6 3 3 67026.88345739 -67030.23630927 -74119.04357713 -6 3 6 3 4 5.25958554 -1.58537405 4.49903448 -6 3 6 3 5 66910.30490447 66909.74788115 74140.36043096 -6 3 6 3 6 108.66239464 110.80479201 -4.97036190 -6 3 6 3 7 -67020.57409713 -67018.93516314 74089.93910885 -6 3 6 3 8 -0.53559934 -0.84624696 4.67042627 -6 1 7 1 1 9466.54698963 3061.53940255 -3062.02144196 -6 1 7 1 2 -0.32135961 1557.50146447 -538.84507467 -6 1 7 1 3 -1.54252611 -1556.58023360 536.17778994 -6 1 7 1 4 -9464.88663167 -3057.84376708 3056.60117661 -6 1 7 1 5 -1.51039015 -537.67746810 1557.05156102 -6 1 7 1 6 -74103.55404414 -72014.41667215 72011.99576312 -6 1 7 1 7 74104.92517845 72008.84643899 -72003.20122192 -6 1 7 1 8 0.19281576 538.52371507 -1557.84424805 -6 1 7 2 1 -3060.65030764 889.20202868 91.95169515 -6 1 7 2 2 -890.29465133 3057.07250403 -88.71667512 -6 1 7 2 3 -1557.69428023 1.24259047 3076.82540779 -6 1 7 2 4 0.97479080 1554.78061981 -3072.62630894 -6 1 7 2 5 533.77830489 -2.69942069 3080.03900384 -6 1 7 2 6 -67034.12476050 -72011.84579531 80799.93838561 -6 1 7 2 7 72008.20371978 67050.69620416 -80809.91124537 -6 1 7 2 8 -0.21423974 -538.32018732 -3077.42527905 -6 1 7 3 1 3060.37179598 91.28755196 889.26630060 -6 1 7 3 2 -1.13547061 -3075.53996937 -535.94212623 -6 1 7 3 3 -538.63083493 3076.54689613 -0.17139179 -6 1 7 3 4 -2.08883744 -3073.89032339 1559.83667760 -6 1 7 3 5 1553.95579682 3075.92560089 1.67106995 -6 1 7 3 6 67039.09512240 80805.25153109 -71999.59128235 -6 1 7 3 7 -72000.44824129 -80809.11855834 67022.12733523 -6 1 7 3 8 888.70927728 -90.38774507 3062.77128104 -6 2 7 1 1 1.24259047 -1557.94065593 3076.79327183 -6 2 7 1 2 1554.67349994 0.87838292 -3072.77627676 -6 2 7 1 3 889.84474789 -3061.44299467 91.33039991 -6 2 7 1 4 3056.18340912 -889.60908418 -89.33797035 -6 2 7 1 5 -2.62443678 533.54264118 3080.12469974 -6 2 7 1 6 -72012.83129810 -67032.50725049 80800.36686509 -6 2 7 1 7 67052.02449053 72007.28248891 -80809.11855834 -6 2 7 1 8 -538.51300308 -0.13925583 -3077.35029514 -6 2 7 2 1 -1558.42269534 -0.23566371 534.83879159 -6 2 7 2 2 -3057.97231093 -9464.96161558 3056.54761668 -6 2 7 2 3 3061.10021109 9466.39702182 -3062.10713785 -6 2 7 2 4 1556.60165757 0.32135961 -539.45565792 -6 2 7 2 5 -538.03096367 -1.37113432 1557.26580076 -6 2 7 2 6 -72011.13880417 -74104.51812295 72013.10980975 -6 2 7 2 7 72009.48915820 74104.06821950 -72002.17287118 -6 2 7 2 8 538.34161129 0.26779967 -1557.80140010 -6 2 7 3 1 3075.79705705 -537.82743592 -0.69627915 -6 2 7 3 2 -3074.14741108 -2.16382134 1559.78311767 -6 2 7 3 3 90.50557692 3061.27160288 889.86617186 -6 2 7 3 4 -3076.40764030 -0.57844729 -536.54199750 -6 2 7 3 5 3075.63637725 1554.20217252 1.67106995 -6 2 7 3 6 80806.34415375 67036.08505410 -71998.84144327 -6 2 7 3 7 -80807.22253667 -71999.84837003 67021.89167151 -6 2 7 3 8 -90.53771288 888.81639715 3062.85697693 -6 3 7 1 1 -1.24259047 3077.84304654 -1557.54431241 -6 3 7 1 2 534.95662344 -3075.06864194 0.04284795 -6 3 7 1 3 -0.22495172 3076.84683176 538.12737155 -6 3 7 1 4 -3059.61124492 -90.79480057 -890.89452260 -6 3 7 1 5 -885.96700865 100.47843668 -3064.52804688 -6 3 7 1 6 72010.33540516 80798.86718693 -67021.60244787 -6 3 7 1 7 -67039.12725836 -80811.10027591 71996.83830172 -6 3 7 1 8 -1559.02256660 -3077.14676739 -0.44990345 -6 3 7 2 1 3075.94702487 0.40705550 537.43109241 -6 3 7 2 2 -90.98761633 -3059.70765280 -890.93737055 -6 3 7 2 3 3077.62880680 -1.28543842 -1557.65143228 -6 3 7 2 4 -3075.94702487 535.59934265 -0.59987126 -6 3 7 2 5 100.25348496 -885.90273672 -3064.48519893 -6 3 7 2 6 80800.01336952 72009.38203833 -67020.80976084 -6 3 7 2 7 -80809.60059775 -67039.59858578 71997.30962915 -6 3 7 2 8 -3077.29673521 -1558.91544673 -0.33207159 -6 3 7 3 1 -1560.54366873 -534.96733543 1.55323809 -6 3 7 3 2 536.39202968 1559.38677415 3.96343514 -6 3 7 3 3 -536.60626942 -1558.85117481 2.69942069 -6 3 7 3 4 1557.76926414 538.02025168 2.91366042 -6 3 7 3 5 3070.62316740 3071.12663078 -9457.27040902 -6 3 7 3 6 -71998.86286724 -72002.82630238 74085.98638570 -6 3 7 3 7 71993.69968958 71989.92907020 -74110.13120406 -6 3 7 3 8 -3062.42849746 -3061.86076215 9470.25333708 -6 1 8 1 1 0.02142397 0.08569589 -890.03756365 -6 1 8 1 2 0.34278358 0.38563153 1.22116650 -6 1 8 1 3 -0.06427192 -0.06427192 -894.32235839 -6 1 8 1 4 -0.29993563 -0.27851166 1.17831855 -6 1 8 1 5 -0.08569589 -0.04284795 883.56752359 -6 1 8 1 6 -3.35285189 -0.42847947 5.50596124 -6 1 8 1 7 0.06427192 -0.04284795 887.53095873 -6 1 8 1 8 3.40641182 0.47132742 5.53809720 -6 1 8 2 1 -536.49914955 -536.39202968 -91.28755196 -6 1 8 2 2 -0.02142397 0.19281576 3374.16873886 -6 1 8 2 3 536.52057352 536.37060571 -93.32282946 -6 1 8 2 4 -0.77126305 0.66414318 2915.58858168 -6 1 8 2 5 -533.30697747 533.28555349 -110.29061664 -6 1 8 2 6 -5.42026535 -0.29993563 -2952.50208837 -6 1 8 2 7 537.87028387 -537.97740374 -89.42366625 -6 1 8 2 8 1.54252611 4.15625090 -2952.57707228 -6 1 8 3 1 1557.56573639 -3076.71828792 3060.67173161 -6 1 8 3 2 0.40705550 2914.32456723 -1.03906272 -6 1 8 3 3 1557.63000831 -3076.76113587 -3058.65787809 -6 1 8 3 4 0.47132742 574.74094262 -1.26401445 -6 1 8 3 5 -1554.39498828 -3080.38178742 -3071.16947873 -6 1 8 3 6 -6.22366436 11773.20196666 6.08440853 -6 1 8 3 7 -1558.63693507 -3077.03964753 3064.37807907 -6 1 8 3 8 3.08505221 -2951.43088969 0.69627915 -6 2 8 1 1 536.37060571 536.39202968 -91.37324786 -6 2 8 1 2 0.85695895 -0.58915928 2915.58858168 -6 2 8 1 3 -536.43487763 -536.30633379 -93.53706920 -6 2 8 1 4 -0.06427192 -0.06427192 3374.14731488 -6 2 8 1 5 533.24270555 -533.30697747 -110.29061664 -6 2 8 1 6 -1.49967816 -4.24194679 -2952.58778427 -6 2 8 1 7 -537.91313182 537.91313182 -89.40224228 -6 2 8 1 8 5.42026535 0.28922365 -2952.45924042 -6 2 8 2 1 0.02142397 0.02142397 -889.97329173 -6 2 8 2 2 -0.17139179 0.05355993 1.19974253 -6 2 8 2 3 0.08569589 0.02142397 -894.49375018 -6 2 8 2 4 0.01071199 0.10711987 1.30686240 -6 2 8 2 5 0.02142397 -0.02142397 883.48182770 -6 2 8 2 6 -3.05291625 -0.68556716 5.42026535 -6 2 8 2 7 -0.02142397 -0.06427192 887.48811078 -6 2 8 2 8 3.06362824 0.74983908 5.54880919 -6 2 8 3 1 -3076.76113587 1557.60858433 -3060.80027546 -6 2 8 3 2 574.71951864 0.39634351 -0.87838292 -6 2 8 3 3 -3076.67543997 1557.65143228 3058.61503014 -6 2 8 3 4 2914.34599120 0.42847947 -0.70699113 -6 2 8 3 5 -3080.42463537 -1554.35214033 -3070.91239105 -6 2 8 3 6 11773.14840672 -6.34149622 8.05541411 -6 2 8 3 7 -3076.88967971 -1558.72263097 3064.44235099 -6 2 8 3 8 -2951.45231366 3.14932413 2.53874088 -6 3 8 1 1 1557.63000831 -3076.67543997 -3060.69315559 -6 3 8 1 2 0.32135961 574.65524672 1.09262266 -6 3 8 1 3 1557.71570420 -3076.69686395 3060.62888367 -6 3 8 1 4 0.55702332 2914.36741517 0.89980690 -6 3 8 1 5 -1554.43783623 -3080.42463537 3071.08378284 -6 3 8 1 6 3.80275533 -2952.05218492 -1.49967816 -6 3 8 1 7 -1558.72263097 -3076.99679958 -3064.42092701 -6 3 8 1 8 -6.89851953 11773.72685401 -7.03777536 -6 3 8 2 1 -3076.71828792 1557.60858433 3060.75742751 -6 3 8 2 2 2914.45311107 0.51417537 0.73912709 -6 3 8 2 3 -3076.80398381 1557.56573639 -3060.58603572 -6 3 8 2 4 574.58026281 0.34278358 1.09262266 -6 3 8 2 5 -3080.36036345 -1554.39498828 3071.21232668 -6 3 8 2 6 -2952.08432088 3.83489129 -1.56395008 -6 3 8 2 7 -3076.91110368 -1558.55123918 -3064.39950304 -6 3 8 2 8 11773.75898997 -6.91994351 -6.98421543 -6 3 8 3 1 -0.02142397 -0.06427192 -9469.88912953 -6 3 8 3 2 -1.69249392 0.93194286 2.36734909 -6 3 8 3 3 -0.02142397 -0.04284795 -9461.16957223 -6 3 8 3 4 1.69249392 -0.96407882 2.39948506 -6 3 8 3 5 0.04284795 0.08569589 9444.71596043 -6 3 8 3 6 11.97600130 6.87709556 4.90608998 -6 3 8 3 7 -0.00000000 -0.14996782 9471.79586319 -6 3 8 3 8 -11.99742528 -6.80211165 4.92751395 -7 1 1 1 1 -0.02142397 -0.03213596 -5.18460164 -7 1 1 1 2 -9468.73223495 0.06427192 3.06362824 -7 1 1 1 3 0.02142397 0.02142397 0.51417537 -7 1 1 1 4 9468.76437091 -0.02142397 2.93508440 -7 1 1 1 5 -0.02142397 0.02142397 -0.14996782 -7 1 1 1 6 9470.91748027 0.66414318 -0.85695895 -7 1 1 1 7 0.08569589 -0.03213596 0.38563153 -7 1 1 1 8 -9470.85320835 -0.77126305 -0.83553497 -7 1 1 2 1 0.04284795 0.07498391 -11783.73184973 -7 1 1 2 2 3060.43606790 1561.33635576 3077.53239892 -7 1 1 2 3 -0.02142397 0.08569589 -2915.16010220 -7 1 1 2 4 -3060.43606790 -1561.29350781 3077.61809482 -7 1 1 2 5 -0.02142397 -0.04284795 -574.71951864 -7 1 1 2 6 3060.80027546 -1557.43719255 3077.51097495 -7 1 1 2 7 -0.00000000 0.05355993 2963.54614682 -7 1 1 2 8 -3060.82169943 1557.50146447 3077.36100713 -7 1 1 3 1 -1.77818982 -11783.18553841 0.04284795 -7 1 1 3 2 3062.94267283 3079.61052437 1556.34456989 -7 1 1 3 3 0.73912709 -573.58404804 0.02142397 -7 1 1 3 4 3062.94267283 3079.63194834 -1556.21602604 -7 1 1 3 5 -0.80339901 -2915.61000565 -0.00000000 -7 1 1 3 6 -3061.18590698 3076.58974408 -1557.39434460 -7 1 1 3 7 -1.67106995 2959.93620725 0.02142397 -7 1 1 3 8 -3061.20733096 3076.62188004 1557.31936069 -7 2 1 1 1 -0.06427192 -0.05355993 2957.22607457 -7 2 1 1 2 -3063.52112012 1556.38741783 3075.68993718 -7 2 1 1 3 -0.00000000 0.02142397 -573.36980830 -7 2 1 1 4 3063.47827217 -1556.38741783 3075.45427347 -7 2 1 1 5 0.10711987 -0.00000000 -2914.26029531 -7 2 1 1 6 -3061.07878711 -1557.15868089 3076.43977626 -7 2 1 1 7 -0.04284795 -0.01071199 -11773.64115812 -7 2 1 1 8 3061.05736314 1557.21224082 3076.40764030 -7 2 1 2 1 -0.04284795 0.02142397 -2.08883744 -7 2 1 2 2 -888.96636496 0.53559934 2.46375698 -7 2 1 2 3 0.04284795 0.02142397 0.72841511 -7 2 1 2 4 889.03063689 -0.55702332 2.31378916 -7 2 1 2 5 -0.04284795 -0.00000000 -1.97100558 -7 2 1 2 6 888.62358139 -0.92123087 -0.00000000 -7 2 1 2 7 -0.02142397 0.03213596 -1.86388571 -7 2 1 2 8 -888.60215741 0.92123087 0.29993563 -7 2 1 3 1 2960.34326275 -1.68178194 -0.06427192 -7 2 1 3 2 92.01596707 -534.87092755 538.25591539 -7 2 1 3 3 -2914.67806279 0.70699113 -0.02142397 -7 2 1 3 4 92.02667905 -534.93519947 -538.12737155 -7 2 1 3 5 -3373.81524329 -1.07119869 0.19281576 -7 2 1 3 6 90.40916904 535.83500637 537.78458797 -7 2 1 3 7 2963.47116291 -0.05355993 0.03213596 -7 2 1 3 8 90.30204917 535.93141425 -537.81672393 -7 3 1 1 1 -1.02835074 2959.38989592 -0.02142397 -7 3 1 1 2 -3058.87211782 3075.02579400 1559.60101389 -7 3 1 1 3 0.26779967 -2913.70327199 -0.10711987 -7 3 1 1 4 -3058.88282981 3074.94009810 -1559.53674197 -7 3 1 1 5 0.40705550 -574.91233441 0.02142397 -7 3 1 1 6 3060.65030764 3076.03272076 -1559.23680634 -7 3 1 1 7 -3.19217208 -11772.98772692 -0.04284795 -7 3 1 1 8 3060.67173161 3076.07556871 1559.22609435 -7 3 1 2 1 2962.05718064 -2.52802890 0.03213596 -7 3 1 2 2 89.53078612 539.75559355 -536.47772558 -7 3 1 2 3 -3371.54430208 0.55702332 -0.02142397 -7 3 1 2 4 89.61648201 539.75559355 536.62769339 -7 3 1 2 5 -2914.04605557 0.10711987 0.04284795 -7 3 1 2 6 89.59505804 -538.04167566 -536.13494200 -7 3 1 2 7 2965.18508081 -1.56395008 -0.03213596 -7 3 1 2 8 89.61648201 -537.96669175 536.02782213 -7 3 1 3 1 -0.17139179 -0.06427192 4.86324203 -7 3 1 3 2 -890.85167465 -0.14996782 -2.89223645 -7 3 1 3 3 0.04284795 0.02142397 2.16382134 -7 3 1 3 4 890.84096266 0.27851166 -2.74226863 -7 3 1 3 5 -0.05355993 -0.02142397 -2.46375698 -7 3 1 3 6 888.94494099 -0.12854384 1.92815763 -7 3 1 3 7 0.04284795 -0.04284795 -2.71013267 -7 3 1 3 8 -889.00921291 0.11783186 2.02456552 -7 1 2 1 1 -9469.63204185 3060.52176380 3063.70322389 -7 1 2 1 2 74061.56305567 -71906.32201282 -71941.36092181 -7 1 2 1 3 -0.23566371 -1555.85181849 -535.47079881 -7 1 2 1 4 -0.86767094 535.79215842 1555.63757875 -7 1 2 1 5 -0.97479080 -534.48529602 -1556.49453770 -7 1 2 1 6 -1.63893399 1553.28094165 536.41345366 -7 1 2 1 7 -74051.57948392 71904.77948671 71937.50460655 -7 1 2 1 8 9463.26912166 -3057.64023933 -3059.86833260 -7 1 2 2 1 0.32135961 1561.90409106 3079.65337232 -7 1 2 2 2 -71903.50476027 66918.12465487 80698.69939786 -7 1 2 2 3 890.95879452 3065.06364622 93.13001370 -7 1 2 2 4 -535.43866285 -0.36420755 -3078.30366197 -7 1 2 2 5 2.35663711 -537.50607631 3074.53304260 -7 1 2 2 6 1557.34078466 -0.10711987 -3075.02579400 -7 1 2 2 7 66929.13657735 -71897.27038392 -80701.79516206 -7 1 2 2 8 3058.78642193 890.25180339 -90.83764851 -7 1 2 3 1 3.68492348 3078.04657429 1556.69806545 -7 1 2 3 2 -71942.56066434 80699.36354105 66983.76771030 -7 1 2 3 3 2.42090903 3075.49712142 -538.23449142 -7 1 2 3 4 1556.83732128 -3078.92495721 0.47132742 -7 1 2 3 5 890.72313081 93.15143767 3062.87840091 -7 1 2 3 6 -538.50229109 -3072.51918907 -0.27851166 -7 1 2 3 7 66969.97067124 -80706.03710886 -71956.21844758 -7 1 2 3 8 3057.35101569 -88.59884326 890.78740273 -7 2 2 1 1 -3064.22811125 -890.16610749 93.64418907 -7 2 2 1 2 -66921.18828311 71901.97294615 80699.45994893 -7 2 2 1 3 -1561.08998006 0.51417537 3079.07492503 -7 2 2 1 4 0.19281576 535.29940702 -3078.23939005 -7 2 2 1 5 537.73102804 -2.05670148 3074.49019465 -7 2 2 1 6 -890.45533114 -3058.76499795 -90.85907249 -7 2 2 1 7 71899.94838064 -66928.81521775 -80701.81658604 -7 2 2 1 8 -0.79268703 -1558.05848778 -3075.65780122 -7 2 2 2 1 1555.76612260 0.38563153 -535.53507073 -7 2 2 2 2 71905.39006996 -74063.19127767 -71940.86817042 -7 2 2 2 3 -3059.85762061 9470.53184874 3063.07121667 -7 2 2 2 4 -535.97426219 0.70699113 1555.65900273 -7 2 2 2 5 534.53885596 1.19974253 -1556.40884181 -7 2 2 2 6 3057.52240748 -9463.20484974 -3059.96474048 -7 2 2 2 7 -71903.18340067 74052.50071479 71938.10447781 -7 2 2 2 8 -1554.22359649 0.98550279 535.76002246 -7 2 2 3 1 3075.47569744 2.39948506 538.19164347 -7 2 2 3 2 80699.20286125 -71942.28215268 -66983.64987845 -7 2 2 3 3 3077.99301436 3.59922758 -1556.68735347 -7 2 2 3 4 -3078.87139728 1556.77304936 -0.40705550 -7 2 2 3 5 93.18357364 890.76597876 -3062.89982488 -7 2 2 3 6 -88.57741929 3057.37243966 -890.74455478 -7 2 2 3 7 -80705.80144515 66969.91711130 71955.92922393 -7 2 2 3 8 -3072.49776510 -538.48086712 0.32135961 -7 3 2 1 1 -3059.60053293 90.86978447 -889.53410027 -7 3 2 1 2 -66971.23468569 80709.01504120 71950.68035037 -7 3 2 1 3 540.17336104 3075.26145771 -0.38563153 -7 3 2 1 4 -884.69228221 -101.54963537 -3065.25646199 -7 3 2 1 5 -1559.77240568 3079.73906821 1.69249392 -7 3 2 1 6 -0.59987126 -3073.16190828 537.57034824 -7 3 2 1 7 71938.87574086 -80703.88399950 -66977.13699044 -7 3 2 1 8 -3.10647619 -3076.24696050 -1557.69428023 -7 3 2 2 1 3075.43284950 540.00196925 0.51417537 -7 3 2 2 2 80709.48636862 -66969.98138322 -71951.36591753 -7 3 2 2 3 90.28062520 -3060.50033982 890.10183557 -7 3 2 2 4 -101.67817921 -884.85296201 3065.21361404 -7 3 2 2 5 3079.64266033 -1559.92237350 -1.77818982 -7 3 2 2 6 -3076.85754375 -4.00628308 1558.33699944 -7 3 2 2 7 -80703.46623201 71940.03263544 66976.52640719 -7 3 2 2 8 -3072.99051650 -0.78197504 -537.44180439 -7 3 2 3 1 1559.00114263 -536.80979717 -3.22430804 -7 3 2 3 2 71946.00992411 -71945.95636417 -74125.82426480 -7 3 2 3 3 536.80979717 -1559.06541455 -3.19217208 -7 3 2 3 4 3067.75235492 -3067.67737102 -9458.21306386 -7 3 2 3 5 -3058.12227874 3058.14370272 9466.35417387 -7 3 2 3 6 -536.25277385 1559.38677415 2.97793235 -7 3 2 3 7 -71955.67213625 71955.71498420 74118.09021030 -7 3 2 3 8 -1559.40819813 536.26348584 3.02078029 -7 1 3 1 1 -0.12854384 -0.02142397 0.63200722 -7 1 3 1 2 -0.55702332 889.00921291 2.37806108 -7 1 3 1 3 -0.03213596 -0.00000000 -2.22809327 -7 1 3 1 4 0.50346338 -889.00921291 2.52802890 -7 1 3 1 5 0.01071199 0.08569589 -1.97100558 -7 1 3 1 6 -0.87838292 888.70927728 0.29993563 -7 1 3 1 7 -0.00000000 0.04284795 -1.91744565 -7 1 3 1 8 0.85695895 -888.58073344 0.26779967 -7 1 3 2 1 -0.00000000 -0.06427192 -573.47692817 -7 1 3 2 2 -1556.45168975 3063.47827217 3075.73278513 -7 1 3 2 3 -0.00000000 -0.02142397 2957.12966669 -7 1 3 2 4 1556.44097777 -3063.58539204 3075.75420910 -7 1 3 2 5 -0.03213596 -0.04284795 -2914.34599120 -7 1 3 2 6 -1557.22295281 -3061.05736314 3076.31123242 -7 1 3 2 7 -0.12854384 0.02142397 -11773.73756600 -7 1 3 2 8 1557.26580076 3061.05736314 3076.41835229 -7 1 3 3 1 0.62129524 -2914.64592683 -0.01071199 -7 1 3 3 2 -534.89235152 91.97311912 -538.21306745 -7 1 3 3 3 -1.74605386 2960.32183877 -0.06427192 -7 1 3 3 4 -534.96733543 91.86599925 538.38445924 -7 1 3 3 5 -1.04977471 -3373.76168336 0.04284795 -7 1 3 3 6 535.89927829 90.36632109 537.61319618 -7 1 3 3 7 -0.10711987 2963.59970675 -0.00000000 -7 1 3 3 8 536.00639816 90.23777725 -537.87028387 -7 2 3 1 1 -0.00000000 0.03213596 -2914.98871041 -7 2 3 1 2 -1561.29350781 -3058.29367053 3077.46812700 -7 2 3 1 3 0.03213596 -0.08569589 -11782.43569933 -7 2 3 1 4 1561.28279583 3058.35794245 3077.63951879 -7 2 3 1 5 0.05355993 -0.06427192 -574.97660633 -7 2 3 1 6 -1557.45861652 3060.80027546 3077.33958316 -7 2 3 1 7 0.04284795 0.06427192 2962.26070839 -7 2 3 1 8 1557.39434460 -3060.82169943 3077.31815918 -7 2 3 2 1 -0.04284795 0.05355993 0.65343120 -7 2 3 2 2 -0.08569589 9468.66796303 3.06362824 -7 2 3 2 3 -0.00000000 0.02142397 -3.92058719 -7 2 3 2 4 0.05355993 -9468.77508290 2.87081248 -7 2 3 2 5 0.02142397 0.02142397 -0.29993563 -7 2 3 2 6 0.81411100 9468.58226714 -1.02835074 -7 2 3 2 7 0.08569589 -0.02142397 -0.85695895 -7 2 3 2 8 -0.77126305 -9468.67867502 -0.89980690 -7 2 3 3 1 -573.51977611 0.71770312 -0.04284795 -7 2 3 3 2 3079.65337232 3062.89982488 -1556.32314591 -7 2 3 3 3 -11783.20696238 -1.82103777 -0.10711987 -7 2 3 3 4 3079.66408430 3062.87840091 1556.40884181 -7 2 3 3 5 -2915.64214161 -0.77126305 -0.00000000 -7 2 3 3 6 3076.58974408 -3061.14305904 -1557.22295281 -7 2 3 3 7 2959.89335930 -1.59608604 0.05355993 -7 2 3 3 8 3076.54689613 -3061.28231486 1557.22295281 -7 3 3 1 1 0.59987126 -3372.01562950 0.05355993 -7 3 3 1 2 539.75559355 91.84457528 536.45630160 -7 3 3 1 3 -3.70634745 2960.27899083 0.08569589 -7 3 3 1 4 539.74488157 91.78030336 -536.58484545 -7 3 3 1 5 -0.18210378 -2914.51738299 0.02142397 -7 3 3 1 6 -537.95597976 89.53078612 -535.94212623 -7 3 3 1 7 -0.21423974 2963.36404304 0.05355993 -7 3 3 1 8 -538.02025168 89.56292208 536.15636597 -7 3 3 2 1 -2913.72469596 0.19281576 -0.04284795 -7 3 3 2 2 3075.02579400 -3058.89354180 -1559.70813376 -7 3 3 2 3 2959.58271168 -1.04977471 0.08569589 -7 3 3 2 4 3075.01508201 -3058.82926988 1559.62243786 -7 3 3 2 5 -574.90162242 0.53559934 0.04284795 -7 3 3 2 6 3076.07556871 3060.62888367 -1559.19395839 -7 3 3 2 7 -11772.92345500 -3.19217208 0.02142397 -7 3 3 2 8 3075.98987281 3060.59674771 1559.15111044 -7 3 3 3 1 -0.06427192 0.02142397 2.28165320 -7 3 3 3 2 0.17139179 890.78740273 -2.97793235 -7 3 3 3 3 0.01071199 -0.02142397 4.73469819 -7 3 3 3 4 -0.11783186 -890.74455478 -2.78511658 -7 3 3 3 5 -0.03213596 0.10711987 -2.46375698 -7 3 3 3 6 -0.14996782 888.90209304 2.14239737 -7 3 3 3 7 0.04284795 -0.06427192 -2.74226863 -7 3 3 3 8 0.10711987 -889.04134887 2.03527750 -7 1 4 1 1 9469.61061787 -3060.53247578 3063.70322389 -7 1 4 1 2 0.83553497 -535.79215842 1555.59473081 -7 1 4 1 3 0.23566371 1555.85181849 -535.38510292 -7 1 4 1 4 -74061.54163170 71906.24702891 -71941.29664989 -7 1 4 1 5 0.98550279 534.44244807 -1556.49453770 -7 1 4 1 6 -9463.22627371 3057.65095132 -3059.94331651 -7 1 4 1 7 74051.42951611 -71904.56524697 71937.45104661 -7 1 4 1 8 1.62822200 -1553.29165363 536.41345366 -7 1 4 2 1 -0.19281576 -1561.79697119 3079.83547609 -7 1 4 2 2 535.40652689 0.37491954 -3078.38935787 -7 1 4 2 3 -891.06591439 -3065.14934212 93.32282946 -7 1 4 2 4 71903.59045617 -66918.33889461 80696.65340837 -7 1 4 2 5 -2.97793235 538.14879553 3075.36857758 -7 1 4 2 6 -3058.87211782 -890.29465133 -90.75195262 -7 1 4 2 7 -66928.62240198 71896.98116028 -80701.09888292 -7 1 4 2 8 -1557.43719255 0.14996782 -3075.02579400 -7 1 4 3 1 3.57780361 3077.92874243 -1556.90159320 -7 1 4 3 2 1556.81589731 -3078.90353324 -0.46061543 -7 1 4 3 3 2.48518095 3075.53996937 537.99882771 -7 1 4 3 4 -71942.22859275 80699.11716535 -66981.23968141 -7 1 4 3 5 891.35513803 92.55156641 -3063.82105575 -7 1 4 3 6 3057.34030370 -88.56670730 -890.85167465 -7 1 4 3 7 66969.11371229 -80705.05160607 71954.96514512 -7 1 4 3 8 -538.49157911 -3072.49776510 0.32135961 -7 2 4 1 1 3064.33523112 890.27322736 93.85842881 -7 2 4 1 2 -0.17139179 -535.35296696 -3078.27152601 -7 2 4 1 3 1561.03642013 -0.55702332 3079.22489284 -7 2 4 1 4 66921.22041907 -71902.04793006 80697.25327964 -7 2 4 1 5 -538.40588321 2.74226863 3075.41142552 -7 2 4 1 6 0.81411100 1558.03706381 -3075.66851321 -7 2 4 1 7 -71899.32708540 66928.17249854 -80700.88464318 -7 2 4 1 8 890.44461915 3058.66859007 -90.93405640 -7 2 4 2 1 -1555.72327465 -0.40705550 -535.54578272 -7 2 4 2 2 535.94212623 -0.77126305 1555.66971471 -7 2 4 2 3 3059.91118055 -9470.51042477 3063.11406462 -7 2 4 2 4 -71905.26152612 74062.84849409 -71940.58965876 -7 2 4 2 5 -534.53885596 -1.15689458 -1556.40884181 -7 2 4 2 6 1554.25573245 -0.94265484 535.74931047 -7 2 4 2 7 71902.90488901 -74052.17935519 71937.87952608 -7 2 4 2 8 -3057.43671158 9463.18342576 -3059.95402849 -7 2 4 3 1 3075.49712142 2.47446896 -537.96669175 -7 2 4 3 2 -3078.90353324 1556.82660929 0.47132742 -7 2 4 3 3 3077.96087839 3.55637964 1556.88016923 -7 2 4 3 4 80699.42781297 -71942.41069652 66981.71100883 -7 2 4 3 5 92.54085442 891.32300207 3063.75678383 -7 2 4 3 6 -3072.45491715 -538.47015513 -0.29993563 -7 2 4 3 7 -80705.37296567 66969.40293593 -71955.20080883 -7 2 4 3 8 -88.60955525 3057.35101569 890.78740273 -7 3 4 1 1 -3059.60053293 90.88049646 889.51267629 -7 3 4 1 2 -884.66014625 -101.53892338 3065.24575000 -7 3 4 1 3 540.16264905 3075.32572963 0.29993563 -7 3 4 1 4 -66971.19183774 80708.95076928 -71950.53038256 -7 3 4 1 5 -1559.74026972 3079.69622027 -1.75676584 -7 3 4 1 6 -3.09576420 -3076.22553652 1557.65143228 -7 3 4 1 7 71938.79004497 -80704.01254334 66977.15841442 -7 3 4 1 8 -0.62129524 -3073.09763636 -537.49536433 -7 3 4 2 1 3075.34715360 540.05552919 -0.50346338 -7 3 4 2 2 -101.54963537 -884.67085824 -3065.24575000 -7 3 4 2 3 90.23777725 -3060.47891585 -890.20895544 -7 3 4 2 4 80709.01504120 -66968.96374447 71950.61607845 -7 3 4 2 5 3079.61052437 -1559.90094952 1.82103777 -7 3 4 2 6 -3073.14048431 -0.62129524 537.48465234 -7 3 4 2 7 -80703.29484022 71937.99735794 -66976.47284726 -7 3 4 2 8 -3076.24696050 -3.10647619 -1557.70499222 -7 3 4 3 1 -1559.06541455 536.82050916 -3.22430804 -7 3 4 3 2 -3067.69879499 3067.69879499 -9458.20235188 -7 3 4 3 3 -536.78837320 1559.04399057 -3.21359606 -7 3 4 3 4 -71945.75283642 71945.79568437 -74125.70643295 -7 3 4 3 5 3058.11156676 -3058.16512669 9466.39702182 -7 3 4 3 6 1559.46175806 -536.19921392 2.99935632 -7 3 4 3 7 71955.58644035 -71955.57572837 74117.97237844 -7 3 4 3 8 536.19921392 -1559.44033409 2.95650837 -7 1 5 1 1 0.04284795 -0.00000000 -0.63200722 -7 1 5 1 2 -0.77126305 2.33521313 890.12325954 -7 1 5 1 3 0.03213596 -0.08569589 -0.83553497 -7 1 5 1 4 0.81411100 -2.33521313 890.03756365 -7 1 5 1 5 -0.03213596 -0.02142397 -4.00628308 -7 1 5 1 6 -0.74983908 -2.35663711 -886.69542375 -7 1 5 1 7 -0.02142397 0.03213596 -1.41398226 -7 1 5 1 8 0.72841511 2.42090903 -886.62043984 -7 1 5 2 1 -0.02142397 -0.10711987 -2915.89922929 -7 1 5 2 2 -534.76380768 -537.93455579 91.37324786 -7 1 5 2 3 0.12854384 0.14996782 -3374.53294641 -7 1 5 2 4 534.72095973 537.99882771 93.49422125 -7 1 5 2 5 0.62129524 -0.64271921 2950.72389855 -7 1 5 2 6 -537.24898863 533.90684873 101.89241895 -7 1 5 2 7 -0.59987126 0.61058325 2950.72389855 -7 1 5 2 8 537.14186876 -534.06752853 101.95669087 -7 1 5 3 1 -0.83553497 -574.62311076 0.02142397 -7 1 5 3 2 -1556.13033015 3074.79013029 3062.57846527 -7 1 5 3 3 -1.64964598 -2914.51738299 -0.00000000 -7 1 5 3 4 -1556.22673803 3074.81155426 -3062.68558514 -7 1 5 3 5 -3.57780361 2952.82344798 -0.04284795 -7 1 5 3 6 1557.90851997 3080.63887511 -3066.84183604 -7 1 5 3 7 2.72084466 -11774.38028521 -0.01071199 -7 1 5 3 8 1557.88709599 3080.61745113 3066.88468399 -7 2 5 1 1 -0.08569589 -0.16067980 -3374.50081045 -7 2 5 1 2 537.95597976 534.78523165 91.56606362 -7 2 5 1 3 0.05355993 0.08569589 -2915.93136525 -7 2 5 1 4 -537.99882771 -534.76380768 93.57991715 -7 2 5 1 5 0.66414318 -0.70699113 2950.72389855 -7 2 5 1 6 533.94969668 -537.37753247 101.97811484 -7 2 5 1 7 -0.57844729 0.59987126 2950.61677869 -7 2 5 1 8 -533.97112065 537.25970062 102.01025080 -7 2 5 2 1 -0.00000000 0.09640788 -0.80339901 -7 2 5 2 2 -2.39948506 0.83553497 890.16610749 -7 2 5 2 3 -0.06427192 0.02142397 -0.62129524 -7 2 5 2 4 2.37806108 -0.77126305 890.03756365 -7 2 5 2 5 -0.01071199 -0.08569589 -3.98485911 -7 2 5 2 6 -2.42090903 -0.81411100 -886.65257580 -7 2 5 2 7 -0.00000000 -0.03213596 -1.43540624 -7 2 5 2 8 2.44233300 0.74983908 -886.55616792 -7 2 5 3 1 -2914.58165491 -1.71391790 0.03213596 -7 2 5 3 2 3074.68301042 -1556.19460207 -3062.55704130 -7 2 5 3 3 -574.54812685 -0.79268703 0.02142397 -7 2 5 3 4 3074.75799433 -1556.32314591 3062.51419335 -7 2 5 3 5 2952.75917606 -3.51353169 -0.04284795 -7 2 5 3 6 3080.63887511 1557.95136791 -3066.84183604 -7 2 5 3 7 -11774.33743726 2.71013267 0.01071199 -7 2 5 3 8 3080.63887511 1557.91923195 3066.88468399 -7 3 5 1 1 0.38563153 -2914.49595902 -0.10711987 -7 3 5 1 2 -1559.02256660 3078.58217363 -3060.92881930 -7 3 5 1 3 0.37491954 -574.59097480 -0.04284795 -7 3 5 1 4 -1558.92615872 3078.56074966 3061.05736314 -7 3 5 1 5 12.29736091 -11774.44455713 0.06427192 -7 3 5 1 6 1555.10197941 3076.71828792 3068.59860189 -7 3 5 1 7 -5.42026535 2952.75917606 -0.04284795 -7 3 5 1 8 1555.20909928 3076.77184785 -3068.51290599 -7 3 5 2 1 -574.54812685 0.43919146 0.05355993 -7 3 5 2 2 3078.66786953 -1559.00114263 3060.84312340 -7 3 5 2 3 -2914.45311107 0.29993563 0.04284795 -7 3 5 2 4 3078.66786953 -1558.89402276 -3061.10021109 -7 3 5 2 5 -11774.39099720 12.38305680 0.04284795 -7 3 5 2 6 3076.73971189 1555.12340339 3068.64144983 -7 3 5 2 7 2952.69490413 -5.43097733 0.03213596 -7 3 5 2 8 3076.78255984 1555.15553935 -3068.51290599 -7 3 5 3 1 -0.00000000 -0.04284795 -2.49589294 -7 3 5 3 2 3.08505221 -3.04220427 9467.74673216 -7 3 5 3 3 0.01071199 -0.04284795 -2.52802890 -7 3 5 3 4 -3.09576420 3.02078029 9467.51106845 -7 3 5 3 5 -0.03213596 -0.00000000 -11.44040196 -7 3 5 3 6 3.04220427 3.08505221 -9459.49850228 -7 3 5 3 7 -0.04284795 -0.02142397 -0.16067980 -7 3 5 3 8 -3.04220427 -3.04220427 -9459.30568652 -7 1 6 1 1 9466.46129374 3061.60367447 -3061.80720222 -7 1 6 1 2 -0.32135961 1557.51217645 -538.83436268 -7 1 6 1 3 -1.45683021 -1556.70877744 536.30633379 -7 1 6 1 4 -9464.87591968 -3057.82234311 3056.51548071 -7 1 6 1 5 -0.89980690 -536.97047697 1557.95136791 -7 1 6 1 6 -74103.85397977 -72014.58806394 72010.34611715 -7 1 6 1 7 74104.53954693 72008.48223143 -72002.55850270 -7 1 6 1 8 0.23566371 538.51300308 -1557.86567202 -7 1 6 2 1 1.17831855 -1557.84424805 3076.75042388 -7 1 6 2 2 1554.37356431 0.81411100 -3072.79770073 -7 1 6 2 3 889.83403590 -3061.52869056 91.39467183 -7 1 6 2 4 3055.25146627 -889.07348483 -90.02353751 -7 1 6 2 5 -2.58158883 533.54264118 3080.08185179 -7 1 6 2 6 -72014.05246460 -67033.49275328 80801.22382403 -7 1 6 2 7 67054.63821532 72007.59313652 -80809.37564603 -7 1 6 2 8 -538.72724282 -0.11783186 -3077.32887117 -7 1 6 3 1 -1.26401445 3077.80019859 -1557.50146447 -7 1 6 3 2 534.95662344 -3075.09006592 0.02142397 -7 1 6 3 3 -0.25708768 3076.88967971 538.12737155 -7 1 6 3 4 -3059.62195690 -90.79480057 -890.89452260 -7 1 6 3 5 -885.97772063 100.47843668 -3064.57089483 -7 1 6 3 6 72010.31398119 80799.03857872 -67021.49532800 -7 1 6 3 7 -67039.25580220 -80811.22881975 71996.92399762 -7 1 6 3 8 -1559.06541455 -3077.14676739 -0.46061543 -7 2 6 1 1 -3061.55011454 889.89830782 91.34111190 -7 2 6 1 2 -890.38034723 3057.09392801 -88.71667512 -7 2 6 1 3 -1557.85496003 1.15689458 3076.73971189 -7 2 6 1 4 0.99621478 1554.73777186 -3072.64773292 -7 2 6 1 5 533.62833707 -2.57087684 3080.16754769 -7 2 6 1 6 -67031.98236313 -72012.08145902 80799.78841780 -7 2 6 1 7 72007.32533685 67050.06419694 -80809.27923815 -7 2 6 1 8 -0.21423974 -538.32018732 -3077.45741501 -7 2 6 2 1 -1557.50146447 -0.88909491 535.51364676 -7 2 6 2 2 -3057.97231093 -9464.96161558 3056.47263277 -7 2 6 2 3 3061.38943473 9466.41844579 -3062.12856183 -7 2 6 2 4 1556.56952161 0.38563153 -539.51992984 -7 2 6 2 5 -537.79529996 -1.39255829 1557.05156102 -7 2 6 2 6 -72013.51686525 -74104.45385103 72013.23835360 -7 2 6 2 7 72010.49608496 74104.67880276 -72002.91199827 -7 2 6 2 8 538.34161129 0.31064762 -1557.75855215 -7 2 6 3 1 3076.93252766 -0.22495172 538.12737155 -7 2 6 3 2 -91.00904030 -3059.71836478 -890.94808253 -7 2 6 3 3 3077.84304654 -1.24259047 -1557.52288844 -7 2 6 3 4 -3075.94702487 535.53507073 -0.59987126 -7 2 6 3 5 100.45701271 -885.96700865 -3064.57089483 -7 2 6 3 6 80798.04236394 72009.78909383 -67021.04542455 -7 2 6 3 7 -80808.89360662 -67039.12725836 71996.89186166 -7 2 6 3 8 -3077.27531124 -1558.94758269 -0.34278358 -7 3 6 1 1 3061.33587480 90.66625672 889.93044378 -7 3 6 1 2 -1.17831855 -3075.56139334 -535.97426219 -7 3 6 1 3 -538.45944314 3076.69686395 -0.04284795 -7 3 6 1 4 -2.03527750 -3073.95459531 1559.90094952 -7 3 6 1 5 1554.11647662 3075.83990500 1.58537405 -7 3 6 1 6 67036.67421337 80805.08013930 -71999.39846658 -7 3 6 1 7 -71999.18422685 -80808.28302337 67021.28108826 -7 3 6 1 8 888.70927728 -90.40916904 3062.74985706 -7 3 6 2 1 3076.69686395 -538.44873116 0.02142397 -7 3 6 2 2 -3074.14741108 -2.17453333 1559.80454164 -7 3 6 2 3 90.59127282 3061.27160288 889.97329173 -7 3 6 2 4 -3076.40764030 -0.57844729 -536.62769339 -7 3 6 2 5 3075.76492109 1554.13790059 1.58537405 -7 3 6 2 6 80804.25531631 67036.27786986 -71998.77717134 -7 3 6 2 7 -80806.15133799 -71999.23778678 67021.30251224 -7 3 6 2 8 -90.60198480 888.82710914 3062.82484097 -7 3 6 3 1 -1559.47247005 -535.66361458 2.04598949 -7 3 6 3 2 536.34918173 1559.47247005 3.84560328 -7 3 6 3 3 -536.53128551 -1558.72263097 2.54945287 -7 3 6 3 4 1557.88709599 537.97740374 2.74226863 -7 3 6 3 5 3070.17326395 3070.41963965 -9458.21306386 -7 3 6 3 6 -72000.45895328 -72002.03361535 74086.95046451 -7 3 6 3 7 71995.11367184 71991.04311684 -74109.46706088 -7 3 6 3 8 -3063.04979270 -3062.49276938 9469.33210622 -7 1 7 1 1 -0.02142397 0.01071199 -2.65657274 -7 1 7 1 2 -74052.67210658 66926.62997243 66965.96438815 -7 1 7 1 3 0.03213596 -0.02142397 0.08569589 -7 1 7 1 4 74052.53285075 -66926.73709230 66966.00723610 -7 1 7 1 5 -0.09640788 0.02142397 3.55637964 -7 1 7 1 6 74102.02223002 67046.64707313 -67035.09955130 -7 1 7 1 7 0.12854384 -0.06427192 137.28482351 -7 1 7 1 8 -74102.14006187 -67046.68992108 -67035.15311124 -7 1 7 2 1 0.17139179 0.05355993 2964.03889821 -7 1 7 2 2 71893.37122071 -71893.38193270 -80701.97726584 -7 1 7 2 3 0.08569589 -0.00000000 2964.02818623 -7 1 7 2 4 -71893.46762859 71893.45691661 -80702.13794564 -7 1 7 2 5 0.03213596 -0.00000000 -11772.30215976 -7 1 7 2 6 72009.09281468 72009.08210270 -80812.21432255 -7 1 7 2 7 0.21423974 0.03213596 328872.88605177 -7 1 7 2 8 -72009.03925475 -72009.10352667 -80812.11791466 -7 1 7 3 1 -4.94893793 2963.50329887 0.28922365 -7 1 7 3 2 71939.49703610 -80703.33768817 -71955.35077664 -7 1 7 3 3 -3.37427586 -11772.17361592 0.21423974 -7 1 7 3 4 71939.37920424 -80703.18772035 71953.01556351 -7 1 7 3 5 -2.88152446 2953.63755898 0.94265484 -7 1 7 3 6 -71999.40917857 -80812.08577870 71993.89250534 -7 1 7 3 7 131.20041498 328885.77257195 1.11404663 -7 1 7 3 8 -71999.54843440 -80812.07506672 -71993.93535329 -7 2 7 1 1 0.02142397 -0.08569589 2964.02818623 -7 2 7 1 2 71893.41406866 -71893.46762859 -80702.11652167 -7 2 7 1 3 0.06427192 0.04284795 2963.96391430 -7 2 7 1 4 -71893.42478064 71893.37122071 -80702.15936962 -7 2 7 1 5 0.04284795 -0.04284795 -11772.34500771 -7 2 7 1 6 72008.95355886 72009.12495064 -80812.04293076 -7 2 7 1 7 -0.06427192 -0.03213596 328872.57540415 -7 2 7 1 8 -72008.88928693 -72008.85715097 -80811.95723486 -7 2 7 2 1 -0.96407882 0.58915928 0.81411100 -7 2 7 2 2 -66929.43651299 74053.48621758 66966.64995531 -7 2 7 2 3 -0.17139179 -0.06427192 -2.44233300 -7 2 7 2 4 66928.85806570 -74052.35074698 66965.79299637 -7 2 7 2 5 -0.19281576 0.12854384 3.51353169 -7 2 7 2 6 67049.45361369 74102.69708519 -67035.95651025 -7 2 7 2 7 -0.74983908 -2.74226863 136.74922417 -7 2 7 2 8 -67046.88273684 -74101.88297419 -67035.29236707 -7 2 7 3 1 -11768.59581231 -0.77126305 -0.27851166 -7 2 7 3 2 -80707.08688357 71938.37227748 71954.81517730 -7 2 7 3 3 2964.18886603 -5.46311330 -0.17139179 -7 2 7 3 4 -80707.04403562 71938.38298947 -71952.47996417 -7 2 7 3 5 2954.39811004 -2.52802890 -1.00692676 -7 2 7 3 6 -80812.59995407 -72000.57678514 71994.38525674 -7 2 7 3 7 328889.12542384 132.78578903 -0.97479080 -7 2 7 3 8 -80812.51425818 -72000.38396937 -71994.21386495 -7 3 7 1 1 -4.99178587 2963.49258688 0.16067980 -7 3 7 1 2 71939.21852444 -80703.08060049 -71954.99728108 -7 3 7 1 3 -3.27786798 -11772.19503989 0.23566371 -7 3 7 1 4 71939.62557994 -80703.61619983 71953.35834709 -7 3 7 1 5 -2.84938850 2953.70183090 1.00692676 -7 3 7 1 6 -71999.86979400 -80812.27859447 71994.10674508 -7 3 7 1 7 131.39323074 328885.95467573 -0.00000000 -7 3 7 1 8 -71999.46273850 -80812.05364274 -71993.76396150 -7 3 7 2 1 -11768.46726847 -0.86767094 -0.24637570 -7 3 7 2 2 -80706.82979588 71938.14732576 71954.52595365 -7 3 7 2 3 2964.21029000 -5.29172151 -0.14996782 -7 3 7 2 4 -80707.33325927 71938.64007715 -71952.95129159 -7 3 7 2 5 2954.45166998 -2.44233300 -0.85695895 -7 3 7 2 6 -80813.00700957 -72000.94099269 71994.68519237 -7 3 7 2 7 328889.61817523 133.25711645 -0.78197504 -7 3 7 2 8 -80812.62137805 -72000.46966527 -71994.25671289 -7 3 7 3 1 -0.92123087 0.59987126 -1.52110213 -7 3 7 3 2 -66970.35630276 66970.27060687 74116.12991670 -7 3 7 3 3 -0.09640788 -0.08569589 -0.98550279 -7 3 7 3 4 66969.92782329 -66969.67073561 74117.73671473 -7 3 7 3 5 0.42847947 -0.57844729 -2.99935632 -7 3 7 3 6 67024.37685246 67022.41655887 -74107.68887106 -7 3 7 3 7 -1.09262266 -0.42847947 -12.96150409 -7 3 7 3 8 -67022.30943900 -67022.36299894 -74107.73171901 -7 1 8 1 1 -9466.52556566 -3061.57153851 -3062.05357792 -7 1 8 1 2 9464.87591968 3057.76878318 3056.61188860 -7 1 8 1 3 1.46754220 1556.64450552 536.19921392 -7 1 8 1 4 0.29993563 -1557.48004049 -538.89863461 -7 1 8 1 5 1.55323809 537.67746810 1557.09440897 -7 1 8 1 6 -0.23566371 -538.53442705 -1557.82282407 -7 1 8 1 7 -74105.52504972 -72009.39275032 -72003.72610927 -7 1 8 1 8 74103.98252361 72014.89871156 72012.72417823 -7 1 8 2 1 -1.19974253 1557.89780798 3076.75042388 -7 1 8 2 2 -3055.27289024 889.05206086 -89.99140155 -7 1 8 2 3 -889.87688385 3061.52869056 91.39467183 -7 1 8 2 4 -1554.42712424 -0.72841511 -3072.88339663 -7 1 8 2 5 2.61372479 -533.64976105 3080.16754769 -7 1 8 2 6 538.73795480 0.04284795 -3077.21103932 -7 1 8 2 7 -67054.57394340 -72007.56100056 -80809.35422206 -7 1 8 2 8 72014.05246460 67033.43919334 80801.09528019 -7 1 8 3 1 -1.17831855 3077.85375853 1557.53360043 -7 1 8 3 2 -3059.64338088 -90.81622454 890.87309862 -7 1 8 3 3 -0.25708768 3076.91110368 -538.17021950 -7 1 8 3 4 534.92448748 -3075.04721797 -0.04284795 -7 1 8 3 5 -885.96700865 100.43558873 3064.57089483 -7 1 8 3 6 -1558.99043064 -3077.08249547 0.42847947 -7 1 8 3 7 -67039.02013849 -80811.04671598 -71996.72046987 -7 1 8 3 8 72010.21757330 80798.76006706 67021.50603999 -7 2 8 1 1 3061.46441864 -889.86617186 91.37324786 -7 2 8 1 2 -0.96407882 -1554.76990782 -3072.63702093 -7 2 8 1 3 1557.86567202 -1.17831855 3076.69686395 -7 2 8 1 4 890.36963524 -3057.09392801 -88.69525114 -7 2 8 1 5 -533.60691310 2.59230082 3080.12469974 -7 2 8 1 6 0.26779967 538.34161129 -3077.53239892 -7 2 8 1 7 -72007.04682520 -67049.91422912 -80809.05428642 -7 2 8 1 8 67031.82168333 72011.88864325 80799.62773799 -7 2 8 2 1 1556.58023360 1.55323809 536.14565398 -7 2 8 2 2 -1556.60165757 -0.32135961 -539.44494594 -7 2 8 2 3 -3061.47513063 -9466.54698963 -3062.00001798 -7 2 8 2 4 3057.98302291 9464.98303955 3056.51548071 -7 2 8 2 5 537.63462016 1.49967816 1557.11583294 -7 2 8 2 6 -538.33089930 -0.36420755 -1557.75855215 -7 2 8 2 7 -72011.71725146 -74105.63216959 -72003.80109318 -7 2 8 2 8 72015.85207839 74104.74307468 72013.35618545 -7 2 8 3 1 3076.88967971 -0.26779967 -538.13808354 -7 2 8 3 2 -3075.96844884 535.57791868 0.61058325 -7 2 8 3 3 3077.86447051 -1.24259047 1557.56573639 -7 2 8 3 4 -90.99832832 -3059.79334869 890.91594657 -7 2 8 3 5 100.46772470 -885.98843262 3064.54947085 -7 2 8 3 6 -3077.27531124 -1558.93687070 0.29993563 -7 2 8 3 7 -80809.00072649 -67039.17010631 -71996.87043768 -7 2 8 3 8 80797.98880400 72009.68197396 67020.93830468 -7 3 8 1 1 3061.33587480 90.63412076 -889.89830782 -7 3 8 1 2 -2.07812545 -3073.96530730 -1559.90094952 -7 3 8 1 3 -538.43801917 3076.65401600 0.08569589 -7 3 8 1 4 -1.16760657 -3075.53996937 535.94212623 -7 3 8 1 5 1554.07362867 3075.77563308 -1.56395008 -7 3 8 1 6 888.71998927 -90.28062520 -3062.77128104 -7 3 8 1 7 -71999.24849877 -80808.37943125 -67021.17396840 -7 3 8 1 8 67036.70634933 80805.06942731 71999.41989056 -7 3 8 2 1 3076.69686395 -538.44873116 0.01071199 -7 3 8 2 2 -3076.39692831 -0.52488736 536.62769339 -7 3 8 2 3 90.66625672 3061.27160288 -889.99471570 -7 3 8 2 4 -3074.17954704 -2.18524532 -1559.77240568 -7 3 8 2 5 3075.79705705 1554.11647662 -1.56395008 -7 3 8 2 6 -90.54842487 888.88066907 -3062.83555296 -7 3 8 2 7 -80805.93709825 -71999.17351486 -67021.20610436 -7 3 8 2 8 80804.11606048 67036.09576608 71998.86286724 -7 3 8 3 1 1559.49389402 535.68503855 2.06741346 -7 3 8 3 2 -1557.84424805 -537.94526778 2.73155665 -7 3 8 3 3 536.47772558 1558.70120699 2.50660492 -7 3 8 3 4 -536.31704577 -1559.49389402 3.87773924 -7 3 8 3 5 -3070.15183998 -3070.37679170 -9458.21306386 -7 3 8 3 6 3063.03908071 3062.51419335 9469.33210622 -7 3 8 3 7 -71995.11367184 -71990.98955690 -74109.30638108 -7 3 8 3 8 72000.34112143 72001.92649548 74087.11114432 -8 1 1 1 1 -74115.87282902 72001.84079958 72005.95420254 -8 1 1 1 2 9472.97418175 -3064.58160682 -3065.79206133 -8 1 1 1 3 0.61058325 -538.02025168 -1559.70813376 -8 1 1 1 4 -0.34278358 1558.20845560 535.83500637 -8 1 1 1 5 0.95336683 -1557.71570420 -539.81986547 -8 1 1 1 6 0.17139179 536.11351802 1557.82282407 -8 1 1 1 7 -9466.39702182 3061.81791421 3061.18590698 -8 1 1 1 8 74107.92453477 -71997.60956478 -71995.41360747 -8 1 1 2 1 72004.19743669 -67024.52682028 -80796.04993438 -8 1 1 2 2 -1.73534187 -1561.91480305 -3081.73149777 -8 1 1 2 3 537.77387599 -0.36420755 3077.46812700 -8 1 1 2 4 -889.37342047 -3066.02772504 -95.12244326 -8 1 1 2 5 -1553.40948549 -0.25708768 3070.09828004 -8 1 1 2 6 -0.66414318 536.75623723 -3077.03964753 -8 1 1 2 7 -3061.31445083 -889.88759583 90.81622454 -8 1 1 2 8 -67035.52803078 72006.32912208 80811.48590744 -8 1 1 3 1 72007.81808825 -80795.24653537 -67033.79268891 -8 1 1 3 2 -2.84938850 -3080.14612371 -1557.04084903 -8 1 1 3 3 -1558.03706381 3077.63951879 -0.36420755 -8 1 1 3 4 -1.43540624 -3078.11084621 538.19164347 -8 1 1 3 5 536.18850193 3076.65401600 -1.92815763 -8 1 1 3 6 -891.54795380 -92.59441436 -3061.18590698 -8 1 1 3 7 -3061.95717004 91.85528727 -890.47675511 -8 1 1 3 8 -67028.22245575 80799.92767362 72006.51122585 -8 2 1 1 1 67015.53946331 -72016.08774210 -80797.22825294 -8 2 1 1 2 3066.00630107 889.36270848 -95.10101928 -8 2 1 1 3 0.56773530 -538.53442705 3077.36100713 -8 2 1 1 4 1561.95765100 1.71391790 -3081.75292174 -8 2 1 1 5 891.74076956 3053.51612440 86.08152635 -8 2 1 1 6 -536.68125333 0.59987126 -3076.99679958 -8 2 1 1 7 -0.47132742 1557.60858433 3076.34336838 -8 2 1 1 8 -71998.56293161 67051.78882682 80811.25024373 -8 2 1 2 1 -72012.35997067 74112.81991276 72011.38517987 -8 2 1 2 2 -1558.18703163 0.32135961 535.82429438 -8 2 1 2 3 537.31326055 0.57844729 -1558.31557547 -8 2 1 2 4 3064.61374278 -9472.95275777 -3065.77063736 -8 2 1 2 5 -3057.07250403 9458.64154334 3054.80156282 -8 2 1 2 6 -536.15636597 -0.12854384 1557.80140010 -8 2 1 2 7 1557.84424805 0.82482299 -537.75245201 -8 2 1 2 8 72004.04746888 -74100.13692033 -71998.05946823 -8 2 1 3 1 -80797.45320466 72014.82372765 67032.58223439 -8 2 1 3 2 -3078.13227018 -1.45683021 -538.22377943 -8 2 1 3 3 3077.35029514 -1559.83667760 0.17139179 -8 2 1 3 4 -3080.15683570 -2.84938850 1557.11583294 -8 2 1 3 5 89.76644983 -3058.55075822 892.24423294 -8 2 1 3 6 -92.59441436 -891.51581784 3061.20733096 -8 2 1 3 7 3077.14676739 536.03853412 0.64271921 -8 2 1 3 8 80804.09463651 -67036.59922946 -72005.72925081 -8 3 1 1 1 67029.59359006 -80803.52690121 -72004.05818086 -8 3 1 1 2 3063.39257627 -92.84079006 888.77354920 -8 3 1 1 3 888.89138106 90.30204917 3062.64273719 -8 3 1 1 4 -539.39138600 -3078.51790171 0.25708768 -8 3 1 1 5 -2.19595730 3073.89032339 -536.13494200 -8 3 1 1 6 1557.82282407 -3077.12534342 0.44990345 -8 3 1 1 7 -0.53559934 3076.69686395 1559.55816594 -8 3 1 1 8 -71997.62027676 80811.11098790 67028.44740747 -8 3 1 2 1 -80800.98816032 67031.39320385 72003.26549384 -8 3 1 2 2 -3079.37486066 -540.05552919 -0.84624696 -8 3 1 2 3 90.69839269 888.90209304 -3062.92124885 -8 3 1 2 4 -92.99075787 3063.47827217 -888.88066907 -8 3 1 2 5 3071.98358973 -2.93508440 -1560.71506052 -8 3 1 2 6 -3077.31815918 1557.71570420 -0.32135961 -8 3 1 2 7 3077.96087839 0.64271921 536.33846975 -8 3 1 2 8 80810.05050120 -71999.13066691 -67026.02649844 -8 3 1 3 1 -72000.85529679 72000.30898546 74100.67251967 -8 3 1 3 2 -1559.30107826 536.35989372 2.35663711 -8 3 1 3 3 -3063.00694475 3062.57846527 9469.46065006 -8 3 1 3 4 -536.34918173 1559.30107826 2.33521313 -8 3 1 3 5 536.88478108 -1558.65835905 3.66349950 -8 3 1 3 6 3061.34658679 -3061.33587480 -9465.43294300 -8 3 1 3 7 1557.71570420 -537.85957188 2.19595730 -8 3 1 3 8 72003.68326132 -72000.76960090 -74115.27295775 -8 1 2 1 1 9471.68874332 -0.47132742 -2.07812545 -8 1 2 1 2 3.08505221 0.09640788 6.97350344 -8 1 2 1 3 -9471.73159127 0.38563153 -1.94958161 -8 1 2 1 4 -0.10711987 0.81411100 -0.23566371 -8 1 2 1 5 -9463.46193742 -1.19974253 5.78447290 -8 1 2 1 6 0.09640788 0.79268703 0.17139179 -8 1 2 1 7 9463.48336139 -0.40705550 -1.92815763 -8 1 2 1 8 -3.14932413 0.06427192 -6.81282364 -8 1 2 2 1 -3065.94202915 -1561.07926808 -3079.54625245 -8 1 2 2 2 0.08569589 -6.93065549 11785.04942412 -8 1 2 2 3 3066.04914901 1561.10069205 -3079.43913258 -8 1 2 2 4 0.05355993 0.21423974 2915.20295015 -8 1 2 2 5 -3055.74421766 1560.37227694 -3077.10391945 -8 1 2 2 6 0.19281576 -0.79268703 574.37673506 -8 1 2 2 7 3059.08635756 -1555.20909928 -3074.10456313 -8 1 2 2 8 -3.74919540 2.42090903 -2964.73517736 -8 1 2 3 1 -3069.41271289 -3080.59602716 -1556.45168975 -8 1 2 3 2 8.52674154 11786.34557453 2.33521313 -8 1 2 3 3 -3069.39128891 -3080.68172306 1556.58023360 -8 1 2 3 4 -0.18210378 573.04844869 1.09262266 -8 1 2 3 5 3062.64273719 -3077.98230237 1554.78061981 -8 1 2 3 6 1.40327028 2915.95278923 0.81411100 -8 1 2 3 7 3057.86519106 -3072.88339663 -1559.85810157 -8 1 2 3 8 8.37677372 -2963.10695536 0.85695895 -8 2 2 1 1 3063.22118448 -1558.52981520 -3077.96087839 -8 2 2 1 2 -2.91366042 -3.08505221 -2956.56193139 -8 2 2 1 3 -3063.26403243 1558.46554328 -3077.96087839 -8 2 2 1 4 0.43919146 0.85695895 573.51977611 -8 2 2 1 5 3060.88597135 1552.57395051 -3072.51918907 -8 2 2 1 6 0.21423974 -0.36420755 2914.21744736 -8 2 2 1 7 -3059.55768498 -1557.71570420 -3075.56139334 -8 2 2 1 8 0.89980690 7.61622265 11772.99843891 -8 2 2 2 1 886.30979223 0.12854384 -1.11404663 -8 2 2 2 2 -2.39948506 -0.18210378 8.79454121 -8 2 2 2 3 -886.50260799 -0.19281576 -0.98550279 -8 2 2 2 4 0.01071199 -0.14996782 -0.36420755 -8 2 2 2 5 -891.28015412 0.49275140 3.34213990 -8 2 2 2 6 0.03213596 -0.21423974 0.32135961 -8 2 2 2 7 891.25873015 0.19281576 -1.07119869 -8 2 2 2 8 2.31378916 -0.20352775 -8.88023710 -8 2 2 3 1 -94.45830007 535.51364676 -538.23449142 -8 2 2 3 2 -2956.65833927 4.53117044 3.13861215 -8 2 2 3 3 -92.20878283 535.40652689 538.17021950 -8 2 2 3 4 2915.34220598 0.08569589 1.41398226 -8 2 2 3 5 -98.03610368 -531.78587534 -539.54135382 -8 2 2 3 6 3374.43653853 0.85695895 0.34278358 -8 2 2 3 7 -88.48101141 -538.72724282 536.11351802 -8 2 2 3 8 -2959.82908738 -5.74162495 -1.52110213 -8 3 2 1 1 3061.52869056 -3078.06799826 -1558.95829468 -8 3 2 1 2 -3.85631527 -2959.50772777 -0.19281576 -8 3 2 1 3 3061.65723440 -3078.04657429 1559.06541455 -8 3 2 1 4 -0.51417537 2913.70327199 -0.83553497 -8 3 2 1 5 -3056.62260058 -3070.33394376 1562.40755445 -8 3 2 1 6 1.06048670 574.80521454 -1.28543842 -8 3 2 1 7 -3059.12920551 -3075.51854539 -1557.24437678 -8 3 2 1 8 -3.98485911 11773.03057487 -2.94579638 -8 3 2 2 1 -90.73052865 -539.07002640 536.45630160 -8 3 2 2 2 -2962.01433270 7.06991132 -0.17139179 -8 3 2 2 3 -90.75195262 -539.04860242 -536.62769339 -8 3 2 2 4 3371.58715003 -0.87838292 0.62129524 -8 3 2 2 5 -84.79608793 542.19792656 534.24963231 -8 3 2 2 6 2914.01391961 0.04284795 1.22116650 -8 3 2 2 7 -92.20878283 535.19228715 -537.82743592 -8 3 2 2 8 -2965.24935273 -5.73091297 1.93886962 -8 3 2 3 1 885.32428943 0.17139179 2.37806108 -8 3 2 3 2 -0.70699113 0.55702332 -3.27786798 -8 3 2 3 3 -885.36713738 -0.17139179 2.42090903 -8 3 2 3 4 0.70699113 -0.85695895 -1.86388571 -8 3 2 3 5 -892.32992884 0.47132742 -7.34842298 -8 3 2 3 6 -0.66414318 -0.87838292 1.90673366 -8 3 2 3 7 892.30850486 0.12854384 2.44233300 -8 3 2 3 8 0.79268703 0.46061543 3.22430804 -8 1 3 1 1 0.55702332 537.13115677 -1558.27272752 -8 1 3 1 2 -9472.95275777 3064.60303079 -3065.70636543 -8 1 3 1 3 74113.75185562 -72013.62398512 72012.23142683 -8 1 3 1 4 0.29993563 -1558.20845560 535.81358239 -8 1 3 1 5 9458.70581526 -3057.30816774 3054.71586692 -8 1 3 1 6 -0.20352775 -536.13494200 1557.86567202 -8 1 3 1 7 0.19281576 1556.93372916 -538.43801917 -8 1 3 1 8 -74100.38329603 72006.41481797 -71998.22014803 -8 1 3 2 1 -538.53442705 0.54631133 3077.36100713 -8 1 3 2 2 1.69249392 1561.93622702 -3081.71007379 -8 1 3 2 3 -72015.61641468 67015.13240781 -80796.83190942 -8 1 3 2 4 889.36270848 3066.02772504 -95.12244326 -8 1 3 2 5 3053.54826036 891.73005757 86.12437430 -8 1 3 2 6 0.58915928 -536.64911737 -3076.99679958 -8 1 3 2 7 1557.56573639 -0.43919146 3076.37550434 -8 1 3 2 8 67051.25322748 -71998.26299598 80810.76820432 -8 1 3 3 1 -1559.83667760 3077.26459925 0.17139179 -8 1 3 3 2 -2.89223645 -3080.19968365 1557.07298499 -8 1 3 3 3 72014.64162387 -80797.36750877 67032.40013062 -8 1 3 3 4 -1.43540624 -3078.11084621 -538.17021950 -8 1 3 3 5 -3058.51862226 89.87356970 892.17996102 -8 1 3 3 6 -891.52652982 -92.57299038 3061.12163506 -8 1 3 3 7 536.00639816 3077.10391945 0.62129524 -8 1 3 3 8 -67036.44926165 80803.96609267 -72005.49358710 -8 2 3 1 1 -0.34278358 537.85957188 3077.48955097 -8 2 3 1 2 -3065.96345312 -889.34128450 -95.09030729 -8 2 3 1 3 -67024.46254836 72004.09031682 -80795.88925458 -8 2 3 1 4 -1561.93622702 -1.77818982 -3081.75292174 -8 2 3 1 5 -0.21423974 -1553.40948549 3070.05543210 -8 2 3 1 6 536.67054134 -0.51417537 -3076.97537560 -8 2 3 1 7 -889.95186776 -3061.34658679 90.85907249 -8 2 3 1 8 72006.31841009 -67035.52803078 80811.49661943 -8 2 3 2 1 -538.06309963 0.41776749 -1559.62243786 -8 2 3 2 2 1558.16560765 -0.31064762 535.81358239 -8 2 3 2 3 72002.70847052 -74116.87975578 72006.74688956 -8 2 3 2 4 -3064.59231880 9472.95275777 -3065.77063736 -8 2 3 2 5 -1557.61929632 0.77126305 -539.90556137 -8 2 3 2 6 536.15636597 0.14996782 1557.77997612 -8 2 3 2 7 3061.20733096 -9467.33967666 3060.54318777 -8 2 3 2 8 -71997.89878842 74110.20618797 -71995.68140714 -8 2 3 3 1 3077.16819137 -1558.17631964 -0.47132742 -8 2 3 3 2 -3078.00372634 -1.34971034 538.38445924 -8 2 3 3 3 -80797.09970910 72009.10352667 -67037.19910073 -8 2 3 3 4 -3080.25324358 -2.95650837 -1556.88016923 -8 2 3 3 5 3074.86511419 534.99947139 -0.66414318 -8 2 3 3 6 -93.24784556 -890.85167465 -3060.28610009 -8 2 3 3 7 91.56606362 -3061.77506626 -890.29465133 -8 2 3 3 8 80804.97301943 -67028.86517496 72007.52886460 -8 3 3 1 1 888.43076562 91.44823176 -3061.82862619 -8 3 3 1 2 3063.32830435 -93.13001370 -889.01992490 -8 3 3 1 3 67032.64650632 -80802.16647888 72006.93970533 -8 3 3 1 4 -539.95912130 -3079.31058874 -1.02835074 -8 3 3 1 5 -1.86388571 3072.69058086 -1561.14354000 -8 3 3 1 6 1558.31557547 -3077.85375853 -1.19974253 -8 3 3 1 7 0.70699113 3077.73592667 536.39202968 -8 3 3 1 8 -72001.77652766 80810.60752452 -67028.96158284 -8 3 3 2 1 91.22328004 888.34506973 3061.85005017 -8 3 3 2 2 -3079.50340450 -539.91627336 0.93194286 -8 3 3 2 3 -80801.08456820 67027.49404064 -72004.24028464 -8 3 3 2 4 -92.38017462 3064.37807907 889.48054033 -8 3 3 2 5 3074.74728234 -1.67106995 -536.88478108 -8 3 3 2 6 -3077.22175130 1557.88709599 0.27851166 -8 3 3 2 7 3076.97537560 -0.48203941 1559.30107826 -8 3 3 2 8 80807.32965654 -71996.03490271 67029.37935033 -8 3 3 3 1 3062.49276938 -3063.22118448 9469.54634595 -8 3 3 3 2 1559.30107826 -536.37060571 2.34592512 -8 3 3 3 3 72001.01597660 -72001.60513587 74101.21883100 -8 3 3 3 4 536.31704577 -1559.32250223 2.35663711 -8 3 3 3 5 -1558.56195116 536.71338929 3.49210771 -8 3 3 3 6 -3061.32516281 3061.33587480 -9465.49721492 -8 3 3 3 7 -538.47015513 1556.80518532 1.57466207 -8 3 3 3 8 -72000.74817693 72005.72925081 -74115.16583788 -8 1 4 1 1 -0.21423974 -886.43833607 -1.15689458 -8 1 4 1 2 0.06427192 0.35349557 -0.42847947 -8 1 4 1 3 0.17139179 886.35264017 -1.11404663 -8 1 4 1 4 -0.78197504 -1.49967816 8.18395796 -8 1 4 1 5 0.47132742 -891.25873015 3.42783579 -8 1 4 1 6 -0.21423974 0.10711987 0.47132742 -8 1 4 1 7 0.10711987 889.07348483 -1.15689458 -8 1 4 1 8 0.42847947 3.35285189 -8.22680590 -8 1 4 2 1 1558.44411931 -3063.32830435 -3077.96087839 -8 1 4 2 2 0.68556716 0.12854384 573.69116790 -8 1 4 2 3 -1558.48696726 3063.37115230 -3077.98230237 -8 1 4 2 4 -1.78890180 -4.64900229 -2955.24435701 -8 1 4 2 5 1552.63822244 3060.92881930 -3072.79770073 -8 1 4 2 6 -0.17139179 -0.17139179 2914.15317544 -8 1 4 2 7 -1557.71570420 -3055.25146627 -3075.56139334 -8 1 4 2 8 6.38434416 -0.83553497 11771.72371247 -8 1 4 3 1 535.55649471 -94.39402815 538.29876334 -8 1 4 3 2 -0.04284795 2914.96728644 1.04977471 -8 1 4 3 3 535.49222279 -92.27305475 -538.42730718 -8 1 4 3 4 5.79518489 -2958.47937704 0.66414318 -8 1 4 3 5 -531.87157123 -93.75130894 -539.45565792 -8 1 4 3 6 0.86767094 3374.01877104 0.72841511 -8 1 4 3 7 -538.85578666 -88.45958743 536.02782213 -8 1 4 3 8 -6.98421543 -2961.69297309 0.98550279 -8 2 4 1 1 1561.10069205 3065.96345312 -3079.41770861 -8 2 4 1 2 0.10711987 0.12854384 2915.32078200 -8 2 4 1 3 -1561.18638794 -3068.14869844 -3079.35343669 -8 2 4 1 4 -5.72020098 0.10711987 11785.07084809 -8 2 4 1 5 1560.35085297 -3053.62324426 -3076.99679958 -8 2 4 1 6 -0.61058325 0.25708768 574.61239877 -8 2 4 1 7 -1555.25194723 3059.04350961 -3074.12598710 -8 2 4 1 8 1.09262266 -3.71705944 -2964.77802531 -8 2 4 2 1 0.47132742 -9471.71016730 -1.94958161 -8 2 4 2 2 0.77126305 -0.53559934 -0.18210378 -8 2 4 2 3 -0.38563153 9473.85256467 -1.97100558 -8 2 4 2 4 -0.04284795 1.26401445 6.94136748 -8 2 4 2 5 -1.24259047 -9463.44051345 5.57023316 -8 2 4 2 6 0.70699113 -0.25708768 0.19281576 -8 2 4 2 7 -0.25708768 9465.62575876 -1.92815763 -8 2 4 2 8 -0.04284795 -4.90608998 -6.87709556 -8 2 4 3 1 -3080.63887511 -3065.02079828 1556.40884181 -8 2 4 3 2 573.30553638 -0.71770312 1.17831855 -8 2 4 3 3 -3080.70314703 -3067.27031552 -1556.49453770 -8 2 4 3 4 11784.49240080 5.87016880 2.97793235 -8 2 4 3 5 -3078.08942224 3062.59988925 1554.52353212 -8 2 4 3 6 2915.73854949 0.92123087 0.72841511 -8 2 4 3 7 -3073.03336444 3057.90803901 -1559.90094952 -8 2 4 3 8 -2961.09310183 5.68806502 0.24637570 -8 3 4 1 1 -539.07002640 -90.68768070 -536.49914955 -8 3 4 1 2 -0.81411100 3371.80138976 0.61058325 -8 3 4 1 3 -538.96290653 -90.77337659 536.54199750 -8 3 4 1 4 6.39505615 -2961.07167785 0.47132742 -8 3 4 1 5 542.26219848 -86.98133325 534.27105629 -8 3 4 1 6 0.03213596 2914.26029531 1.17831855 -8 3 4 1 7 535.19228715 -92.14451091 -537.80601195 -8 3 4 1 8 -5.07748177 -2964.37096980 1.25330246 -8 3 4 2 1 -3078.02515032 3061.59296248 1559.12968647 -8 3 4 2 2 2913.78896788 -0.72841511 -1.11404663 -8 3 4 2 3 -3078.15369416 3063.73535985 -1559.06541455 -8 3 4 2 4 -2960.10759904 -4.77754614 -2.14239737 -8 3 4 2 5 -3070.33394376 -3054.41593129 1562.49325034 -8 3 4 2 6 574.69809467 0.87838292 -0.92123087 -8 3 4 2 7 -3075.53996937 -3061.37872275 -1557.39434460 -8 3 4 2 8 11773.69471805 -5.00249786 -1.03906272 -8 3 4 3 1 -0.12854384 -885.32428943 2.46375698 -8 3 4 3 2 -0.96407882 0.49275140 -2.00314154 -8 3 4 3 3 0.12854384 885.28144149 2.44233300 -8 3 4 3 4 1.17831855 -1.60679803 -3.92058719 -8 3 4 3 5 0.42847947 -890.12325954 -7.41269490 -8 3 4 3 6 -0.76055107 -0.89980690 1.99242955 -8 3 4 3 7 0.08569589 892.20138499 2.48518095 -8 3 4 3 8 -0.08569589 -0.18210378 3.88845123 -8 1 5 1 1 0.89980690 -1553.73084509 534.31390423 -8 1 5 1 2 -9463.14057781 -3055.47641799 3062.18212176 -8 1 5 1 3 9459.57348619 3053.17334082 -3057.88661503 -8 1 5 1 4 0.58915928 1552.59537449 -531.52878765 -8 1 5 1 5 73992.05297298 71805.66147236 -71878.46013501 -8 1 5 1 6 0.73912709 533.97112065 -1553.53802933 -8 1 5 1 7 0.89980690 -533.97112065 1555.41262703 -8 1 5 1 8 -73991.61378152 -71802.12651670 71869.40850612 -8 1 5 2 1 -1558.10133573 0.33207159 3074.74728234 -8 1 5 2 2 -1.60679803 1560.40441290 -3078.28223800 -8 1 5 2 3 -3056.03344131 891.13018631 90.62340878 -8 1 5 2 4 -889.84474789 3059.66480485 -93.70846099 -8 1 5 2 5 71807.34325429 66823.92344248 -80589.70493163 -8 1 5 2 6 0.24637570 -533.22128157 -3079.95330795 -8 1 5 2 7 537.69889208 2.87081248 3077.29673521 -8 1 5 2 8 -66839.71291110 -71805.01875315 80599.04578417 -8 1 5 3 1 -539.34853805 3069.46627282 -0.25708768 -8 1 5 3 2 5.72020098 -3077.06107150 1555.13411537 -8 1 5 3 3 3053.65538023 86.57427775 891.32300207 -8 1 5 3 4 3.88845123 -3073.18333226 -539.41280997 -8 1 5 3 5 -71878.03165554 -80588.86939666 66908.24820299 -8 1 5 3 6 884.22095479 -109.09087411 3073.52611584 -8 1 5 3 7 1558.22987957 3080.91738677 -2.52802890 -8 1 5 3 8 66911.63319084 80611.27887315 -71885.91567786 -8 2 5 1 1 891.73005757 -3056.87968827 90.04496149 -8 2 5 1 2 3059.68622882 -889.63050815 -93.72988496 -8 2 5 1 3 0.14996782 -1558.27272752 3074.57589055 -8 2 5 1 4 1559.78311767 -0.74983908 -3077.72521468 -8 2 5 1 5 66823.27001128 71804.16179420 -80589.04078845 -8 2 5 1 6 -533.32840144 0.40705550 -3079.99615590 -8 2 5 1 7 2.95650837 537.54892426 3077.41456707 -8 2 5 1 8 -71804.31176201 -66836.57429896 80598.45662489 -8 2 5 2 1 3053.08764492 9459.57348619 -3057.89732702 -8 2 5 2 2 1552.59537449 0.64271921 -531.58234758 -8 2 5 2 3 -1553.75226907 0.89980690 534.27105629 -8 2 5 2 4 -3055.48712998 -9463.14057781 3062.23568169 -8 2 5 2 5 71805.51150454 73991.95656510 -71878.31016719 -8 2 5 2 6 533.93898469 0.74983908 -1553.45233344 -8 2 5 2 7 -533.97112065 0.86767094 1555.40191504 -8 2 5 2 8 -71801.89085298 -73991.48523768 71869.25853830 -8 2 5 3 1 86.53142980 3053.69822817 891.32300207 -8 2 5 3 2 -3073.26902815 3.67421149 -539.56277779 -8 2 5 3 3 3069.42342487 -539.28426613 -0.32135961 -8 2 5 3 4 -3076.40764030 4.82039408 1554.50210815 -8 2 5 3 5 -80588.73014083 -71875.71786638 66908.07681120 -8 2 5 3 6 -109.02660219 884.03885101 3073.52611584 -8 2 5 3 7 3080.91738677 1558.20845560 -2.51731691 -8 2 5 3 8 80610.55045805 66910.65840003 -71885.03729494 -8 3 5 1 1 -2.52802890 3071.37300648 537.61319618 -8 3 5 1 2 -3054.18026758 -87.31340484 -890.29465133 -8 3 5 1 3 -4.50974647 3074.68301042 -1558.12275970 -8 3 5 1 4 542.73352590 -3070.69815131 -0.12854384 -8 3 5 1 5 -66915.01817868 -80608.27951684 71898.53439837 -8 3 5 1 6 -1555.05913146 -3081.62437790 -1.45683021 -8 3 5 1 7 -885.45283328 101.12115589 -3068.78070566 -8 3 5 1 8 71873.93967656 80600.67400617 -66917.49264764 -8 3 5 2 1 3073.46184392 -2.67799671 -1556.92301718 -8 3 5 2 2 -3070.71957528 542.75494987 -0.11783186 -8 3 5 2 3 3071.61938218 -2.16382134 537.89170784 -8 3 5 2 4 -87.32411683 -3054.11599566 -890.35892326 -8 3 5 2 5 -80607.59394968 -66913.73274026 71897.91310314 -8 3 5 2 6 -3081.61366591 -1555.05913146 -1.41398226 -8 3 5 2 7 100.92834013 -885.08862572 -3068.98423341 -8 3 5 2 8 80601.08106167 71870.16905719 -66918.14607884 -8 3 5 3 1 -536.79908518 -1559.33321422 3.94201116 -8 3 5 3 2 1563.07169763 534.27105629 -6.56644794 -8 3 5 3 3 -1560.16874919 -535.94212623 3.38498785 -8 3 5 3 4 533.46765727 1563.95008055 -6.06298456 -8 3 5 3 5 71892.70707753 71890.86461579 -74116.34415644 -8 3 5 3 6 -3071.10520681 -3070.84811912 9448.22949211 -8 3 5 3 7 3064.97795033 3065.24575000 -9458.18092790 -8 3 5 3 8 -71886.12991760 -71888.13305914 74131.61944969 -8 1 6 1 1 -0.04284795 -0.00000000 -890.03756365 -8 1 6 1 2 0.19281576 0.17139179 0.84624696 -8 1 6 1 3 -0.02142397 -0.00000000 -889.95186776 -8 1 6 1 4 -0.17139179 -0.08569589 0.89980690 -8 1 6 1 5 0.08569589 0.02142397 883.43897975 -8 1 6 1 6 -2.02456552 -1.79961379 3.55637964 -8 1 6 1 7 0.04284795 0.02142397 887.55238270 -8 1 6 1 8 2.01385353 1.77818982 3.70634745 -8 1 6 2 1 536.37060571 536.41345366 -91.33039991 -8 1 6 2 2 0.79268703 -0.58915928 2915.63142962 -8 1 6 2 3 -536.43487763 -536.49914955 -93.53706920 -8 1 6 2 4 0.06427192 -0.21423974 3374.36155462 -8 1 6 2 5 533.32840144 -533.30697747 -112.60440580 -8 1 6 2 6 -0.91051888 -3.53495566 -2951.64512942 -8 1 6 2 7 -537.97740374 537.95597976 -89.35939433 -8 1 6 2 8 4.84181806 -0.34278358 -2951.55943353 -8 1 6 3 1 1557.65143228 -3076.63259203 -3060.73600354 -8 1 6 3 2 0.29993563 574.86948646 1.08191067 -8 1 6 3 3 1557.65143228 -3076.65401600 3058.65787809 -8 1 6 3 4 0.48203941 2914.26029531 0.89980690 -8 1 6 3 5 -1554.35214033 -3080.42463537 3070.95523899 -8 1 6 3 6 3.80275533 -2950.76674650 -1.62822200 -8 1 6 3 7 -1558.67978302 -3077.06107150 -3062.21425772 -8 1 6 3 8 -6.81282364 11772.46283957 -7.05919934 -8 2 6 1 1 -536.37060571 -536.37060571 -91.33039991 -8 2 6 1 2 -0.08569589 0.14996782 3374.37226661 -8 2 6 1 3 536.37060571 536.39202968 -93.36567741 -8 2 6 1 4 -0.79268703 0.59987126 2915.67427757 -8 2 6 1 5 -533.24270555 533.28555349 -112.56155785 -8 2 6 1 6 -4.83110607 0.34278358 -2951.62370545 -8 2 6 1 7 537.97740374 -537.93455579 -89.35939433 -8 2 6 1 8 0.92123087 3.57780361 -2951.58085750 -8 2 6 2 1 0.04284795 0.08569589 -890.05898762 -8 2 6 2 2 0.06427192 -0.01071199 1.28543842 -8 2 6 2 3 0.06427192 0.02142397 -894.49375018 -8 2 6 2 4 -0.02142397 -0.00000000 1.24259047 -8 2 6 2 5 -0.02142397 -0.02142397 883.31043591 -8 2 6 2 6 -3.10647619 -0.79268703 5.52738522 -8 2 6 2 7 -0.14996782 0.04284795 887.57380667 -8 2 6 2 8 3.08505221 0.72841511 5.51667323 -8 2 6 3 1 -3076.71828792 1557.60858433 3060.73600354 -8 2 6 3 2 2914.19602338 0.54631133 0.54631133 -8 2 6 3 3 -3076.63259203 1557.67285626 -3058.65787809 -8 2 6 3 4 574.83735050 0.27851166 0.70699113 -8 2 6 3 5 -3080.46748332 -1554.39498828 3071.25517462 -8 2 6 3 6 -2950.77745849 3.87773924 -3.47068374 -8 2 6 3 7 -3076.95395163 -1558.63693507 -3062.14998580 -8 2 6 3 8 11772.51639950 -6.94136748 -8.90166107 -8 3 6 1 1 1557.65143228 -3076.71828792 3060.65030764 -8 3 6 1 2 0.55702332 2914.23887133 -0.85695895 -8 3 6 1 3 1557.54431241 -3076.76113587 -3058.65787809 -8 3 6 1 4 0.35349557 574.82663851 -1.11404663 -8 3 6 1 5 -1554.35214033 -3080.48890729 -3071.16947873 -8 3 6 1 6 -6.86638357 11772.53782347 7.11275927 -8 3 6 1 7 -1558.74405494 -3076.95395163 3062.21425772 -8 3 6 1 8 3.77061937 -2950.79888246 1.56395008 -8 3 6 2 1 -3076.73971189 1557.63000831 -3060.82169943 -8 3 6 2 2 574.82663851 0.50346338 -0.94265484 -8 3 6 2 3 -3076.71828792 1557.56573639 3058.65787809 -8 3 6 2 4 2914.24958332 0.47132742 -0.72841511 -8 3 6 2 5 -3080.44605934 -1554.43783623 -3071.12663078 -8 3 6 2 6 11773.15911871 -6.17010443 7.94829424 -8 3 6 2 7 -3077.08249547 -1558.65835905 3064.46377496 -8 3 6 2 8 -2951.45231366 3.20288407 2.52802890 -8 3 6 3 1 -0.00000000 0.04284795 -9469.88912953 -8 3 6 3 2 -1.32828637 1.16760657 3.02078029 -8 3 6 3 3 0.06427192 0.08569589 -9469.99624940 -8 3 6 3 4 1.24259047 -1.26401445 3.06362824 -8 3 6 3 5 -0.00000000 -0.00000000 9444.75880837 -8 3 6 3 6 9.36227651 9.38370048 8.56958948 -8 3 6 3 7 0.04284795 -0.04284795 9471.86013511 -8 3 6 3 8 -9.44797240 -9.38370048 8.52674154 -8 1 7 1 1 -9466.50414169 -3061.52869056 -3062.05357792 -8 1 7 1 2 9464.89734366 3057.79020715 3056.56904065 -8 1 7 1 3 1.48896617 1556.53738565 536.11351802 -8 1 7 1 4 0.27851166 -1557.43719255 -538.85578666 -8 1 7 1 5 1.49967816 537.65604413 1557.05156102 -8 1 7 1 6 -0.21423974 -538.55585103 -1557.82282407 -8 1 7 1 7 -74105.07514627 -72009.16779859 -72003.50115755 -8 1 7 1 8 74103.76828387 72014.65233586 72012.37068266 -8 1 7 2 1 3061.52869056 -889.86617186 91.33039991 -8 1 7 2 2 -0.96407882 -1554.76990782 -3072.66915689 -8 1 7 2 3 1557.90851997 -1.13547061 3076.78255984 -8 1 7 2 4 890.31607531 -3057.11535198 -88.71667512 -8 1 7 2 5 -533.64976105 2.63514877 3080.18897166 -8 1 7 2 6 0.26779967 538.38445924 -3077.53239892 -8 1 7 2 7 -72007.32533685 -67050.01063700 -80809.16140629 -8 1 7 2 8 67031.95022717 72012.04932306 80799.74556985 -8 1 7 3 1 3061.31445083 90.62340878 -889.91973179 -8 1 7 3 2 -2.05670148 -3073.98673127 -1559.90094952 -8 1 7 3 3 -538.45944314 3076.67543997 -0.06427192 -8 1 7 3 4 -1.16760657 -3075.49712142 535.85643034 -8 1 7 3 5 1554.15932457 3075.79705705 -1.60679803 -8 1 7 3 6 888.75212523 -90.34489712 -3062.77128104 -8 1 7 3 7 -71999.11995492 -80808.28302337 -67021.20610436 -8 1 7 3 8 67036.64207741 80805.02657937 71999.40917857 -8 2 7 1 1 -1.17831855 1557.91923195 3076.72899991 -8 2 7 1 2 -3056.21554508 889.73762802 -89.32725837 -8 2 7 1 3 -889.86617186 3061.48584261 91.35182388 -8 2 7 1 4 -1554.59851603 -0.87838292 -3072.73342881 -8 2 7 1 5 2.64586075 -533.58548913 3080.08185179 -8 2 7 1 6 538.55585103 0.17139179 -3077.38243110 -8 2 7 1 7 -67052.13161040 -72007.22892897 -80809.03286245 -8 2 7 1 8 72012.72417823 67032.37870664 80800.28116919 -8 2 7 2 1 1557.43719255 0.70699113 535.59934265 -8 2 7 2 2 -1556.55880962 -0.34278358 -539.48779388 -8 2 7 2 3 -3060.69315559 -9467.40394858 -3061.40014672 -8 2 7 2 4 3057.98302291 9464.96161558 3056.45120879 -8 2 7 2 5 537.92384380 1.28543842 1557.15868089 -8 2 7 2 6 -538.36303526 -0.34278358 -1557.77997612 -8 2 7 2 7 -72011.18165212 -74105.65359356 -72003.56542947 -8 2 7 2 8 72013.43116936 74106.77835218 72013.15265770 -8 2 7 3 1 3076.69686395 -538.40588321 -0.02142397 -8 2 7 3 2 -3076.46120024 -0.52488736 536.60626942 -8 2 7 3 3 90.66625672 3061.31445083 -889.90901981 -8 2 7 3 4 -3074.16883505 -2.18524532 -1559.68670978 -8 2 7 3 5 3075.79705705 1554.15932457 -1.54252611 -8 2 7 3 6 -90.54842487 888.79497318 -3062.87840091 -8 2 7 3 7 -80806.51554554 -71999.59128235 -67021.60244787 -8 2 7 3 8 80804.48026804 67036.44926165 71999.11995492 -8 3 7 1 1 -1.26401445 3077.82162257 1557.54431241 -8 3 7 1 2 -3059.64338088 -90.82693653 890.85167465 -8 3 7 1 3 -0.21423974 3076.86825574 -538.14879553 -8 3 7 1 4 534.91377550 -3075.11148989 -0.02142397 -8 3 7 1 5 -885.99914461 100.47843668 3064.57089483 -8 3 7 1 6 -1558.97971865 -3077.06107150 0.40705550 -8 3 7 1 7 -67039.08441041 -80810.96102008 -71996.66690993 -8 3 7 1 8 72010.17472536 80798.69579514 67021.52746396 -8 3 7 2 1 3076.82540779 -0.20352775 -538.14879553 -8 3 7 2 2 -3076.88967971 536.22063789 1.25330246 -8 3 7 2 3 3077.88589449 -1.22116650 1557.52288844 -8 3 7 2 4 -91.19114408 -3059.79334869 891.04449041 -8 3 7 2 5 100.47843668 -885.94558467 3064.48519893 -8 3 7 2 6 -3077.50026296 -1558.80832686 0.29993563 -8 3 7 2 7 -80806.79405720 -67039.27722618 -71996.83830172 -8 3 7 2 8 80797.19611698 72009.09281468 67020.41341733 -8 3 7 3 1 1559.60101389 535.57791868 2.20666929 -8 3 7 3 2 -1557.86567202 -537.98811572 2.71013267 -8 3 7 3 3 536.44558962 1558.76547892 2.76369261 -8 3 7 3 4 -536.30633379 -1559.49389402 3.83489129 -8 3 7 3 5 -3070.79455919 -3071.12663078 -9457.31325697 -8 3 7 3 6 3063.01765673 3062.55704130 9469.35353019 -8 3 7 3 7 -71994.68519237 -71990.52894147 -74108.67437385 -8 3 7 3 8 72000.57678514 72002.17287118 74085.15085072 -8 1 8 1 1 74108.80291769 -67033.86767282 -67025.90866658 -8 1 8 1 2 -3.74919540 -3.32071592 4.95964991 -8 1 8 1 3 -74100.09407238 67048.96086229 -67036.34214178 -8 1 8 1 4 -0.42847947 6.79139966 -9.49082035 -8 1 8 1 5 -73987.00762717 -66833.67135052 66912.89720528 -8 1 8 1 6 -0.13925583 4.88466601 -7.49839080 -8 1 8 1 7 74102.84705300 67030.41841305 67035.75298250 -8 1 8 1 8 -120.25276441 -220.12061784 125.99438937 -8 1 8 2 1 -71998.26299598 72006.72546559 80806.82619316 -8 1 8 2 2 2.37806108 0.43919146 -2960.32183877 -8 1 8 2 3 72005.60070697 -71997.25606921 80805.87282633 -8 1 8 2 4 3.72777142 -0.89980690 -2960.27899083 -8 1 8 2 5 -71805.23299288 -71800.56256662 80610.40049023 -8 1 8 2 6 2.89223645 1.84246174 11771.35950492 -8 1 8 2 7 72008.63219925 72013.14194571 80808.95787854 -8 1 8 2 8 -219.87424215 -223.70913344 -328883.09457524 -8 1 8 3 1 -71993.87108137 80814.38885588 72003.47973357 -8 1 8 3 2 -7.36984695 -2964.74588934 1.69249392 -8 1 8 3 3 -71999.11995492 80816.26345358 -72004.30455656 -8 1 8 3 4 -9.12661280 11771.27380902 1.07119869 -8 1 8 3 5 71865.80927854 80595.91788401 -71885.10156686 -8 1 8 3 6 4.52045845 -2952.73775208 -7.06991132 -8 1 8 3 7 72012.25285081 80801.49162371 72004.78659597 -8 1 8 3 8 127.02274010 -328881.83056079 -114.39330760 -8 2 8 1 1 -71998.07018021 72006.52193784 80806.55839349 -8 2 8 1 2 2.42090903 0.42847947 -2960.30041480 -8 2 8 1 3 72005.90064260 -71997.38461305 80806.12991401 -8 2 8 1 4 3.69563546 -0.92123087 -2960.30041480 -8 2 8 1 5 -71805.11516103 -71800.51971867 80610.42191421 -8 2 8 1 6 2.82796453 1.64964598 11771.55232068 -8 2 8 1 7 72008.50365541 72013.13123373 80808.89360662 -8 2 8 1 8 -220.30272162 -223.11997416 -328883.21240709 -8 2 8 2 1 67049.81782124 -74100.98316729 -67035.01385541 -8 2 8 2 2 5.20602561 0.99621478 -8.11968603 -8 2 8 2 3 -67033.01071387 74108.03165464 -67027.08698514 -8 2 8 2 4 -3.77061937 -4.13482693 5.03463382 -8 2 8 2 5 -66833.22144707 -73986.87908333 66912.57584568 -8 2 8 2 6 3.31000394 1.19974253 -7.77690246 -8 2 8 2 7 67035.07812733 74102.60067731 67035.88152634 -8 2 8 2 8 -223.36634986 -120.74551581 124.91247869 -8 2 8 3 1 80814.65665555 -71997.99519630 -72003.32976576 -8 2 8 3 2 11772.19503989 -9.80146797 1.74605386 -8 2 8 3 3 80814.47455177 -71994.53522455 72004.13316477 -8 2 8 3 4 -2964.61734550 -7.30557503 1.75676584 -8 2 8 3 5 80593.21846332 71865.81999052 -71885.20868673 -8 2 8 3 6 -2952.57707228 4.43476256 -7.13418324 -8 2 8 3 7 80799.57417806 72010.67818874 72003.22264589 -8 2 8 3 8 -328876.91375882 128.64025012 -115.12172271 -8 3 8 1 1 -71993.91392931 80810.03978921 72003.31905377 -8 3 8 1 2 -7.45554285 -2964.12459411 1.36042233 -8 3 8 1 3 -71999.54843440 80816.67050908 -72004.69018809 -8 3 8 1 4 -8.52674154 11773.97322971 -0.85695895 -8 3 8 1 5 71865.78785456 80595.98215593 -71885.25153468 -8 3 8 1 6 4.70256223 -2952.24500069 -6.83424761 -8 3 8 1 7 72012.25285081 80799.44563422 72004.86157988 -8 3 8 1 8 126.80850037 -328879.72029938 -112.21877427 -8 3 8 2 1 80814.24960005 -71997.29891716 -72002.78345443 -8 3 8 2 2 11773.09484679 -10.47632314 1.11404663 -8 3 8 2 3 80814.34600793 -71994.23528892 72004.04746888 -8 3 8 2 4 -2964.47808967 -7.15560722 1.56395008 -8 3 8 2 5 80594.00043836 71866.80549331 -71885.93710183 -8 3 8 2 6 -2952.52351235 4.39191461 -7.06991132 -8 3 8 2 7 80797.49605261 72010.98883636 72003.52258152 -8 3 8 2 8 -328876.37815948 126.85134831 -114.42544356 -8 3 8 3 1 67028.69378317 -67026.93701732 -74118.22946612 -8 3 8 3 2 -4.45618653 2.31378916 3.62065156 -8 3 8 3 3 -67026.84060944 67028.80090304 -74118.52940176 -8 3 8 3 4 1.44611823 -3.64207553 3.06362824 -8 3 8 3 5 -66906.88778066 -66906.98418854 74137.23253080 -8 3 8 3 6 1.30686240 1.67106995 3.85631527 -8 3 8 3 7 67020.44555329 67018.21746002 74090.72108389 -8 3 8 3 8 -113.37566885 -113.37566885 -1.74605386 diff --git a/examples/USER/phonon/third_order_command/silicon/silicon_input_file.lmp b/examples/USER/phonon/third_order_command/silicon/silicon_input_file.lmp deleted file mode 100755 index 5066049895..0000000000 --- a/examples/USER/phonon/third_order_command/silicon/silicon_input_file.lmp +++ /dev/null @@ -1,29 +0,0 @@ -LAMMPS description - - 8 atoms - 0 bonds - 0 angles - 0 dihedrals - 0 impropers - - 1 atom types - 0 bond types - 0 angle types - 0 dihedral types - 0 improper types - - - 0.0000000 5.4310000 xlo xhi - 0.0000000 5.4310000 ylo yhi - 0.0000000 5.4310000 zlo zhi - - Atoms - - 1 1 1 0.0000000 0.0000000 0.0000000 0.0000000 - 2 2 1 0.0000000 1.3577500 1.3577500 1.3572000 - 3 3 1 0.0000000 2.7155000 2.7155000 0.0000000 - 4 4 1 0.0000000 4.0732500 4.0732500 1.3572000 - 5 5 1 0.0000000 2.7155000 0.0000000 2.7144000 - 6 6 1 0.0000000 4.0732500 1.3577500 4.0732500 - 7 7 1 0.0000000 0.0000000 2.7155000 2.7155000 - 8 8 1 0.0000000 1.3577500 4.0732500 4.0732500 diff --git a/src/USER-PHONON/README b/src/USER-PHONON/README index b1ffcb9b09..697f4ca086 100644 --- a/src/USER-PHONON/README +++ b/src/USER-PHONON/README @@ -3,12 +3,11 @@ matrices from finite temperature MD simulations, which can then be used to compute phonon dispersion relations, directly from molecular dynamics simulations. -It also contains two commands to compute the dynamical matrix and -the corresponding third order matrix at pre-optimized positions -through finite differences. +It also contains a command to compute the dynamical matrix at +pre-optimized positions through finite differences. See the doc page for the fix phonon command or the dynamical_matrix -third_order commands for detailed usage instructions. +command for detailed usage instructions. Use of this package requires building LAMMPS with FFT suppport, as described in doc/Section_start.html. @@ -30,5 +29,5 @@ The person who created fix phonon is Ling-Ti Kong (konglt at sjtu.edu.cn) at Shanghai Jiao Tong University. Contact him directly if you have questions. -The person who created dynamical_matrix and third_order is -Charlie Sievers at UC Davis. +The person who created the dynamical_matrix command is Charlie Sievers +at UC Davis. Contact him directly if you have questions about his code. diff --git a/src/USER-PHONON/third_order.cpp b/src/USER-PHONON/third_order.cpp deleted file mode 100644 index f7d72687c6..0000000000 --- a/src/USER-PHONON/third_order.cpp +++ /dev/null @@ -1,560 +0,0 @@ -// -// Created by charlie sievers on 7/5/18. -// - - -#include -#include -#include "third_order.h" -#include "atom.h" -#include "complex" -#include "domain.h" -#include "comm.h" -#include "group.h" -#include "force.h" -#include "math_extra.h" -#include "memory.h" -#include "bond.h" -#include "angle.h" -#include "dihedral.h" -#include "improper.h" -#include "kspace.h" -#include "update.h" -#include "neighbor.h" -#include "pair.h" -#include "timer.h" -#include "finish.h" -#include - - -using namespace LAMMPS_NS; -enum{REGULAR,BALLISTICO}; - -/* ---------------------------------------------------------------------- */ - -ThirdOrder::ThirdOrder(LAMMPS *lmp) : Pointers(lmp), fp(NULL) -{ - external_force_clear = 1; -} - -/* ---------------------------------------------------------------------- */ - -ThirdOrder::~ThirdOrder() -{ - if (fp && me == 0) fclose(fp); - memory->destroy(groupmap); - fp = NULL; -} - -/* ---------------------------------------------------------------------- - setup without output or one-time post-init setup - flag = 0 = just force calculation - flag = 1 = reneighbor and force calculation -------------------------------------------------------------------------- */ - -void ThirdOrder::setup() -{ - // setup domain, communication and neighboring - // acquire ghosts - // build neighbor lists - if (triclinic) domain->x2lamda(atom->nlocal); - domain->pbc(); - domain->reset_box(); - comm->setup(); - if (neighbor->style) neighbor->setup_bins(); - comm->exchange(); - comm->borders(); - if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost); - domain->image_check(); - domain->box_too_small_check(); - neighbor->build(1); - neighbor->ncalls = 0; - neighbor->every = 3; // build every this many steps - neighbor->delay = 1; - neighbor->ago = 0; - neighbor->ndanger = 0; - - // compute all forces - - external_force_clear = 0; - eflag=0; - vflag=0; - update_force(); - - if (gcount == atom->natoms) - for (bigint i=0; inatoms; i++) - groupmap[i] = i; - else - create_groupmap(); -} - -/* ---------------------------------------------------------------------- */ - -void ThirdOrder::command(int narg, char **arg) -{ - MPI_Comm_rank(world,&me); - - if (domain->box_exist == 0) - error->all(FLERR,"Third_order command before simulation box is defined"); - if (narg < 2) error->all(FLERR,"Illegal third_oreder command"); - - lmp->init(); - - // orthogonal vs triclinic simulation box - - triclinic = domain->triclinic; - - if (force->pair && force->pair->compute_flag) pair_compute_flag = 1; - else pair_compute_flag = 0; - if (force->kspace && force->kspace->compute_flag) kspace_compute_flag = 1; - else kspace_compute_flag = 0; - - // group and style - - igroup = group->find(arg[0]); - if (igroup == -1) error->all(FLERR,"Could not find third_order group ID"); - groupbit = group->bitmask[igroup]; - gcount = group->count(igroup); - dynlen = (gcount)*3; - memory->create(groupmap,atom->natoms,"total_group_map:totalgm"); - update->setupflag = 1; - - int style = -1; - if (strcmp(arg[1],"regular") == 0) style = REGULAR; - else if (strcmp(arg[1],"ballistico") == 0) style = BALLISTICO; - else error->all(FLERR,"Illegal Dynamical Matrix command"); - - // set option defaults - - binaryflag = 0; - scaleflag = 0; - compressed = 0; - file_flag = 0; - file_opened = 0; - conversion = 1; - - // read options from end of input line - if (style == REGULAR) options(narg-3,&arg[3]); //COME BACK - else if (style == BALLISTICO) options(narg-3,&arg[3]); //COME BACK - else if (comm->me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); - del = force->numeric(FLERR, arg[2]); - - // move atoms by 3-vector or specified variable(s) - - if (style == REGULAR) { - setup(); - timer->init(); - timer->barrier_start(); - calculateMatrix(); - timer->barrier_stop(); - } - - if (style == BALLISTICO) { - setup(); - convert_units(update->unit_style); - conversion = conv_energy/conv_distance/conv_distance; - timer->init(); - timer->barrier_start(); - calculateMatrix(); - timer->barrier_stop(); - } - - Finish finish(lmp); - finish.end(1); -} - -/* ---------------------------------------------------------------------- - parse optional parameters -------------------------------------------------------------------------- */ - -void ThirdOrder::options(int narg, char **arg) -{ - if (narg < 0) error->all(FLERR,"Illegal dynamical_matrix command"); - int iarg = 0; - const char *filename = "third_order.txt"; - - while (iarg < narg) { - if (strcmp(arg[iarg],"file") == 0) { - if (iarg+2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); - filename = arg[iarg + 1]; - file_flag = 1; - iarg += 2; - } - else if (strcmp(arg[iarg],"binary") == 0) { - if (iarg + 2 > narg) error->all(FLERR, "Illegal dynamical_matrix command"); - if (strcmp(arg[iarg+1],"gzip") == 0) { - compressed = 1; - } - else if (strcmp(arg[iarg+1],"yes") == 0) { - binaryflag = 1; - } - iarg += 2; - } else error->all(FLERR,"Illegal dynamical_matrix command"); - } - if (file_flag == 1 && me == 0) { - openfile(filename); - } -} - -/* ---------------------------------------------------------------------- - generic opening of a file - ASCII or binary or gzipped - some derived classes override this function -------------------------------------------------------------------------- */ - -void ThirdOrder::openfile(const char* filename) -{ - // if file already opened, return - if (file_opened) return; - - if (compressed) { -#ifdef LAMMPS_GZIP - char gzip[128]; - sprintf(gzip,"gzip -6 > %s",filename); -#ifdef _WIN32 - fp = _popen(gzip,"wb"); -#else - fp = popen(gzip,"w"); -#endif -#else - error->one(FLERR,"Cannot open gzipped file"); -#endif - } else if (binaryflag) { - fp = fopen(filename,"wb"); - } else { - fp = fopen(filename,"w"); - } - - if (fp == NULL) error->one(FLERR,"Cannot open dump file"); - - file_opened = 1; -} - -/* ---------------------------------------------------------------------- - create dynamical matrix -------------------------------------------------------------------------- */ - -void ThirdOrder::calculateMatrix() -{ - int local_idx; // local index - int local_jdx; // second local index - int local_kdx; // third local index - int nlocal = atom->nlocal; - int natoms = atom->natoms; - int *gm = groupmap; - double **f = atom->f; - - double *dynmat = new double[3*dynlen]; - double *fdynmat = new double[3*dynlen]; - memset(&dynmat[0],0,dynlen*sizeof(double)); - memset(&fdynmat[0],0,dynlen*sizeof(double)); - - if (comm->me == 0 && screen) fprintf(screen,"Calculating Anharmonic Dynamical Matrix...\n"); - - update->nsteps = 0; - for (bigint i=1; i<=natoms; i++){ - local_idx = atom->map(i); - for (bigint alpha=0; alpha<3; alpha++){ - for (bigint j=1; j<=natoms; j++){ - local_jdx = atom->map(j); - for (int beta=0; beta<3; beta++){ - displace_atom(local_idx, alpha, 1); - displace_atom(local_jdx, beta, 1); - update_force(); - for (bigint k=1; k<=natoms; k++){ - local_kdx = atom->map(k); - for (int gamma=0; gamma<3; gamma++){ - if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 - && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; - } - } - } - displace_atom(local_jdx, beta, -2); - update_force(); - for (bigint k=1; k<=natoms; k++){ - local_kdx = atom->map(k); - for (int gamma=0; gamma<3; gamma++){ - if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 - && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; - } - } - } - displace_atom(local_jdx, beta, 1); - displace_atom(local_idx,alpha,-2); - displace_atom(local_jdx, beta, 1); - update_force(); - for (bigint k=1; k<=natoms; k++){ - local_kdx = atom->map(k); - for (int gamma=0; gamma<3; gamma++){ - if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 - && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] -= f[local_kdx][gamma]; - } - } - } - displace_atom(local_jdx, beta, -2); - update_force(); - for (bigint k=1; k<=natoms; k++){ - local_kdx = atom->map(k); - for (int gamma=0; gamma<3; gamma++){ - if (local_idx >= 0 && local_jdx >= 0 && local_kdx >= 0 - && gm[i-1] >= 0 && gm[j-1] >= 0 && gm[k-1] >= 0 - && local_kdx < nlocal) { - dynmat[gm[k-1]*3+gamma] += f[local_kdx][gamma]; - dynmat[gm[k-1]*3+gamma] /= -(4 * del * del); - } - } - } - displace_atom(local_jdx, beta, 1); - displace_atom(local_idx, alpha, 1); - MPI_Reduce(dynmat,fdynmat,3*dynlen,MPI_DOUBLE,MPI_SUM,0,world); - if (me == 0){ - writeMatrix(fdynmat, gm[i-1], alpha, gm[j-1], beta); - } - memset(&dynmat[0],0,dynlen*sizeof(double)); - } - } - } - } - - delete [] dynmat; - delete [] fdynmat; - - if (screen && me ==0 ) fprintf(screen,"Finished Calculating Third Order Tensor\n"); - -} - -/* ---------------------------------------------------------------------- - write dynamical matrix -------------------------------------------------------------------------- */ - -void ThirdOrder::writeMatrix(double *dynmat, int i, int a, int j, int b) -{ - if (me != 0) - return; - - if (!binaryflag && fp) { - clearerr(fp); - for (int k = 0; k < gcount; k++){ - if (dynmat[k*3] > 1.0e-16 - && dynmat[k*3+1] > 1.0e-16 - && dynmat[k*3+2] > 1.0e-16) - fprintf(fp, - "%d %d %d %d %d %7.8f %7.8f %7.8f\n", - i+1, a + 1, j+1, b + 1, groupmap[k]+1, - dynmat[k*3] * conversion, - dynmat[k*3+1] * conversion, - dynmat[k*3+2] * conversion); - } - } - else if (binaryflag && fp){ - clearerr(fp); - fwrite(&dynmat[0], sizeof(double), dynlen, fp); - } - if (ferror(fp)) error->one(FLERR,"Error writing to file"); - -} - -/* ---------------------------------------------------------------------- - Displace atoms - ---------------------------------------------------------------------- */ - -void ThirdOrder::displace_atom(int local_idx, int direction, int magnitude) -{ - if (local_idx < 0) return; - - double **x = atom->x; - int *sametag = atom->sametag; - int j = local_idx; - - x[local_idx][direction] += del*magnitude; - - while (sametag[j] >= 0){ - j = sametag[j]; - x[j][direction] += del*magnitude; - } -} - -/* ---------------------------------------------------------------------- - evaluate potential energy and forces - may migrate atoms due to reneighboring - return new energy, which should include nextra_global dof - return negative gradient stored in atom->f - return negative gradient for nextra_global dof in fextra -------------------------------------------------------------------------- */ - -void ThirdOrder::update_force() -{ - force_clear(); - - timer->stamp(); - - if (pair_compute_flag) { - force->pair->compute(eflag,vflag); - timer->stamp(Timer::PAIR); - } - - if (atom->molecular) { - if (force->bond) force->bond->compute(eflag,vflag); - if (force->angle) force->angle->compute(eflag,vflag); - if (force->dihedral) force->dihedral->compute(eflag,vflag); - if (force->improper) force->improper->compute(eflag,vflag); - timer->stamp(Timer::BOND); - } - - if (kspace_compute_flag) { - force->kspace->compute(eflag,vflag); - timer->stamp(Timer::KSPACE); - } - - if (force->newton) { - comm->reverse_comm(); - timer->stamp(Timer::COMM); - } - ++ update->nsteps; -} - -/* ---------------------------------------------------------------------- - clear force on own & ghost atoms - clear other arrays as needed -------------------------------------------------------------------------- */ - -void ThirdOrder::force_clear() -{ - if (external_force_clear) return; - - // clear global force array - // if either newton flag is set, also include ghosts - - size_t nbytes = sizeof(double) * atom->nlocal; - if (force->newton) nbytes += sizeof(double) * atom->nghost; - - if (nbytes) { - memset(&atom->f[0][0],0,3*nbytes); - } -} - -/* ---------------------------------------------------------------------- */ - -void ThirdOrder::convert_units(const char *style) -{ - // physical constants from: - // http://physics.nist.gov/cuu/Constants/Table/allascii.txt - // using thermochemical calorie = 4.184 J - - if (strcmp(style,"lj") == 0) { - error->all(FLERR,"Conversion Not Set"); - //conversion = 1; // lj -> 10 J/mol - - } else if (strcmp(style,"real") == 0) { - conv_energy = 418.4; // kcal/mol -> 10 J/mol - conv_mass = 1; // g/mol -> g/mol - conv_distance = 1; // angstrom -> angstrom - - } else if (strcmp(style,"metal") == 0) { - conv_energy = 9648.5; // eV -> 10 J/mol - conv_mass = 1; // g/mol -> g/mol - conv_distance = 1; // angstrom -> angstrom - - } else if (strcmp(style,"si") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); - conv_energy = 6.022E22; // J -> 10 J/mol - conv_mass = 6.022E26; // kg -> g/mol - conv_distance = 1E-10; // meter -> angstrom - - } else if (strcmp(style,"cgs") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Multiplication by Large Float"); - conv_energy = 6.022E12; // Erg -> 10 J/mol - conv_mass = 6.022E23; // g -> g/mol - conv_distance = 1E-7; // centimeter -> angstrom - - } else if (strcmp(style,"electron") == 0) { - conv_energy = 262550; // Hartree -> 10 J/mol - conv_mass = 1; // amu -> g/mol - conv_distance = 0.529177249; // bohr -> angstrom - - } else if (strcmp(style,"micro") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); - conv_energy = 6.022E10; // picogram-micrometer^2/microsecond^2 -> 10 J/mol - conv_mass = 6.022E11; // pg -> g/mol - conv_distance = 1E-4; // micrometer -> angstrom - - } else if (strcmp(style,"nano") == 0) { - if (comm->me) error->warning(FLERR,"Conversion Warning: Untested Conversion"); - conv_energy = 6.022E4; // attogram-nanometer^2/nanosecond^2 -> 10 J/mol - conv_mass = 6.022E5; // ag -> g/mol - conv_distance = 0.1; // angstrom -> angstrom - - } else error->all(FLERR,"Units Type Conversion Not Found"); - -} - -/* ---------------------------------------------------------------------- */ - -void ThirdOrder::create_groupmap() -{ - //Create a group map which maps atom order onto group - - int local_idx; // local index - int gid = 0; //group index - int nlocal = atom->nlocal; - int *mask = atom->mask; - bigint natoms = atom->natoms; - int *recv = new int[comm->nprocs]; - int *displs = new int[comm->nprocs]; - int *temp_groupmap = new int[natoms]; - - //find number of local atoms in the group (final_gid) - for (bigint i=1; i<=natoms; i++){ - local_idx = atom->map(i); - if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit) - gid += 1; // gid at the end of loop is final_Gid - } - //create an array of length final_gid - int *sub_groupmap = new int[gid]; - - gid = 0; - //create a map between global atom id and group atom id for each proc - for (bigint i=1; i<=natoms; i++){ - local_idx = atom->map(i); - if ((local_idx >= 0) && (local_idx < nlocal) && mask[local_idx] & groupbit){ - sub_groupmap[gid] = i; - gid += 1; - } - } - - //populate arrays for Allgatherv - for (int i=0; inprocs; i++){ - recv[i] = 0; - } - recv[comm->me] = gid; - MPI_Allreduce(recv,displs,4,MPI_INT,MPI_SUM,world); - for (int i=0; inprocs; i++){ - recv[i]=displs[i]; - if (i>0) displs[i] = displs[i-1]+recv[i-1]; - else displs[i] = 0; - } - - //combine subgroup maps into total temporary groupmap - MPI_Allgatherv(sub_groupmap,gid,MPI_INT,temp_groupmap,recv,displs,MPI_INT,world); - std::sort(temp_groupmap,temp_groupmap+gcount); - - //populate member groupmap based on temp groupmap - for (bigint i=0; icompute is skipped - int kspace_compute_flag; // 0 if kspace->compute is skipped - - int nvec; // local atomic dof = length of xvec - - void update_force(); - void force_clear(); - virtual void openfile(const char* filename); - - - private: - void options(int, char **); - void create_groupmap(); - void calculateMatrix(); - void convert_units(const char *style); - void displace_atom(int local_idx, int direction, int magnitude); - void writeMatrix(double *, int, int, int, int); - - double conversion; - double conv_energy; - double conv_distance; - double conv_mass; - double del; - int igroup,groupbit; - bigint dynlen; - int scaleflag; - int me; - int gcount; // number of atoms in group - int *groupmap; - - int compressed; // 1 if dump file is written compressed, 0 no - int binaryflag; // 1 if dump file is written binary, 0 no - int file_opened; // 1 if openfile method has been called, 0 no - int file_flag; // 1 custom file name, 0 dynmat.dat - - FILE *fp; - }; -} - - -#endif //LMP_THIRD_ORDER_H -#endif - -- GitLab From 1d2eab5e1b6443e70338b8b4a9d33157fc41efe4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 15:26:36 -0500 Subject: [PATCH 0177/1243] update attribution information in Package details documentation --- doc/src/Packages_details.txt | 7 ++++++- src/USER-PHONON/README | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/src/Packages_details.txt b/doc/src/Packages_details.txt index ebfe01d8a7..f5e8c4edbf 100644 --- a/doc/src/Packages_details.txt +++ b/doc/src/Packages_details.txt @@ -1700,14 +1700,19 @@ USER-PHONON package :link(PKG-USER-PHONON),h4 A "fix phonon"_fix_phonon.html command that calculates dynamical matrices, which can then be used to compute phonon dispersion relations, directly from molecular dynamics simulations. +And a "dynamical_matrix" command to compute the dynamical matrix +from finite differences. + +[Authors:] Ling-Ti Kong (Shanghai Jiao Tong University) for "fix phonon" +and Charlie Sievers (UC Davis) for "dynamical_matrix" -[Author:] Ling-Ti Kong (Shanghai Jiao Tong University). [Supporting info:] src/USER-PHONON: filenames -> commands src/USER-PHONON/README "fix phonon"_fix_phonon.html +"dynamical_matrix"_dynamical_matrix.html examples/USER/phonon :ul :line diff --git a/src/USER-PHONON/README b/src/USER-PHONON/README index 697f4ca086..b554eacd5e 100644 --- a/src/USER-PHONON/README +++ b/src/USER-PHONON/README @@ -30,4 +30,5 @@ sjtu.edu.cn) at Shanghai Jiao Tong University. Contact him directly if you have questions. The person who created the dynamical_matrix command is Charlie Sievers -at UC Davis. Contact him directly if you have questions about his code. +(charliesievers at cox.net) at UC Davis. Contact him directly if you +have questions about his code. -- GitLab From 5fd033c0a255024cc6cfe24c431ee4f8164955c9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 15:49:48 -0500 Subject: [PATCH 0178/1243] add one more false positive required by recent changes --- doc/utils/sphinx-config/false_positives.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index bbfdf946f4..99c7831192 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2433,6 +2433,7 @@ shockvel si SiC Siepmann +Sievers Sij Sikandar Silbert -- GitLab From 50fef541c24740cd51c0448f165f2de8548cc8fd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 15:50:59 -0500 Subject: [PATCH 0179/1243] add x-ref --- doc/src/fix_phonon.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_phonon.txt b/doc/src/fix_phonon.txt index 23d4d09552..73f2f4600b 100644 --- a/doc/src/fix_phonon.txt +++ b/doc/src/fix_phonon.txt @@ -179,7 +179,8 @@ settings"_Build_settings.html doc page for details. [Related commands:] -"compute msd"_compute_msd.html +"compute msd"_compute_msd.html, +"dynamical_matrix"_dynamical_matrix.html [Default:] -- GitLab From c555f7e2ed98ae2e33ce30d9ae9fbad36676418d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 17:52:53 -0500 Subject: [PATCH 0180/1243] update permissions --- examples/USER/smtbq/data.Alpha | 0 examples/USER/smtbq/ffield.smtbq.Al | 0 examples/USER/smtbq/ffield.smtbq.Al2O3 | 0 examples/USER/smtbq/ffield.smtbq.TiO2 | 0 examples/USER/smtbq/in.smtbq.Al | 0 examples/USER/smtbq/in.smtbq.Al2O3 | 0 examples/USER/smtbq/in.smtbq.TiO2 | 0 7 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 examples/USER/smtbq/data.Alpha mode change 100755 => 100644 examples/USER/smtbq/ffield.smtbq.Al mode change 100755 => 100644 examples/USER/smtbq/ffield.smtbq.Al2O3 mode change 100755 => 100644 examples/USER/smtbq/ffield.smtbq.TiO2 mode change 100755 => 100644 examples/USER/smtbq/in.smtbq.Al mode change 100755 => 100644 examples/USER/smtbq/in.smtbq.Al2O3 mode change 100755 => 100644 examples/USER/smtbq/in.smtbq.TiO2 diff --git a/examples/USER/smtbq/data.Alpha b/examples/USER/smtbq/data.Alpha old mode 100755 new mode 100644 diff --git a/examples/USER/smtbq/ffield.smtbq.Al b/examples/USER/smtbq/ffield.smtbq.Al old mode 100755 new mode 100644 diff --git a/examples/USER/smtbq/ffield.smtbq.Al2O3 b/examples/USER/smtbq/ffield.smtbq.Al2O3 old mode 100755 new mode 100644 diff --git a/examples/USER/smtbq/ffield.smtbq.TiO2 b/examples/USER/smtbq/ffield.smtbq.TiO2 old mode 100755 new mode 100644 diff --git a/examples/USER/smtbq/in.smtbq.Al b/examples/USER/smtbq/in.smtbq.Al old mode 100755 new mode 100644 diff --git a/examples/USER/smtbq/in.smtbq.Al2O3 b/examples/USER/smtbq/in.smtbq.Al2O3 old mode 100755 new mode 100644 diff --git a/examples/USER/smtbq/in.smtbq.TiO2 b/examples/USER/smtbq/in.smtbq.TiO2 old mode 100755 new mode 100644 -- GitLab From fbc9cf83542a87449981e52773e2d7d4a1d5610b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 17:53:17 -0500 Subject: [PATCH 0181/1243] fix huge memory leak --- src/USER-SMTBQ/pair_smtbq.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/USER-SMTBQ/pair_smtbq.cpp b/src/USER-SMTBQ/pair_smtbq.cpp index c2690dc864..0c259c950a 100644 --- a/src/USER-SMTBQ/pair_smtbq.cpp +++ b/src/USER-SMTBQ/pair_smtbq.cpp @@ -187,6 +187,16 @@ PairSMTBQ::~PairSMTBQ() memory->destroy(potqn); memory->destroy(dpotqn); + memory->destroy(fafbOxOxSurf); + memory->destroy(dfafbOxOxSurf); + memory->destroy(fafbTiOxSurf); + memory->destroy(dfafbTiOxSurf); + + memory->destroy(fafbOxOxBB); + memory->destroy(dfafbOxOxBB); + memory->destroy(fafbTiOxBB); + memory->destroy(dfafbTiOxBB); + memory->destroy(ecov); memory->destroy(sbcov); memory->destroy(coord); -- GitLab From 47b0c77dd9e8ba58555259152f36e50887345dc9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 17:53:50 -0500 Subject: [PATCH 0182/1243] replace variable length arrays with std::vector --- src/USER-SMTBQ/pair_smtbq.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/USER-SMTBQ/pair_smtbq.cpp b/src/USER-SMTBQ/pair_smtbq.cpp index 0c259c950a..1931754427 100644 --- a/src/USER-SMTBQ/pair_smtbq.cpp +++ b/src/USER-SMTBQ/pair_smtbq.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include "pair_smtbq.h" #include "atom.h" #include "comm.h" @@ -252,7 +253,7 @@ void PairSMTBQ::allocate() global settings ------------------------------------------------------------------------- */ -void PairSMTBQ::settings(int narg, char **/*arg*/) +void PairSMTBQ::settings(int narg, char ** /* arg */) { if (narg > 0) error->all(FLERR,"Illegal pair_style command"); } @@ -2539,10 +2540,10 @@ void PairSMTBQ::Charge() // --------------------------- - double enegtotall[nteam+1],enegchkall[nteam+1],enegmaxall[nteam+1],qtota[nteam+1],qtotc[nteam+1]; - double qtotcll[nteam+1],qtotall[nteam+1]; - double sigmaa[nteam+1],sigmac[nteam+1],sigmaall[nteam+1],sigmacll[nteam+1]; - int end[nteam+1], nQEq[nteam+1],nQEqc[nteam+1],nQEqa[nteam+1]; + std::vector enegtotall(nteam+1),enegchkall(nteam+1),enegmaxall(nteam+1); + std::vector qtotcll(nteam+1),qtotall(nteam+1),qtota(nteam+1),qtotc(nteam+1); + std::vector sigmaa(nteam+1),sigmac(nteam+1),sigmaall(nteam+1),sigmacll(nteam+1); + std::vector end(nteam+1), nQEq(nteam+1),nQEqc(nteam+1),nQEqa(nteam+1); iloop = 0; @@ -2553,9 +2554,7 @@ void PairSMTBQ::Charge() dtq = 0.0006; // 0.0006 dtq2 = 0.5*dtq*dtq/qmass; - double enegchk[nteam+1]; - double enegtot[nteam+1]; - double enegmax[nteam+1]; + std::vector enegchk(nteam+1),enegtot(nteam+1),enegmax(nteam+1); @@ -2580,12 +2579,12 @@ void PairSMTBQ::Charge() if (itype == 0) { qtota[gp] += q[i]; nQEqa[gp] += 1; } } - MPI_Allreduce(nQEq,nQEqall,nteam+1,MPI_INT,MPI_SUM,world); - MPI_Allreduce(nQEqc,nQEqcall,nteam+1,MPI_INT,MPI_SUM,world); - MPI_Allreduce(nQEqa,nQEqaall,nteam+1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(nQEq.data(),nQEqall,nteam+1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(nQEqc.data(),nQEqcall,nteam+1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(nQEqa.data(),nQEqaall,nteam+1,MPI_INT,MPI_SUM,world); - MPI_Allreduce(qtotc,qtotcll,nteam+1,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(qtota,qtotall,nteam+1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(qtotc.data(),qtotcll.data(),nteam+1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(qtota.data(),qtotall.data(),nteam+1,MPI_DOUBLE,MPI_SUM,world); MPI_Allreduce(&qtot,&qtotll,1,MPI_DOUBLE,MPI_SUM,world); @@ -2704,8 +2703,8 @@ void PairSMTBQ::Charge() } // Boucle local - MPI_Allreduce(enegchk,enegchkall,nteam+1,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(enegmax,enegmaxall,nteam+1,MPI_DOUBLE,MPI_MAX,world); + MPI_Allreduce(enegchk.data(),enegchkall.data(),nteam+1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(enegmax.data(),enegmaxall.data(),nteam+1,MPI_DOUBLE,MPI_MAX,world); for (gp = 0; gp < nteam+1; gp++) { @@ -2793,8 +2792,8 @@ void PairSMTBQ::Charge() if (itype == 1) sigmac[gp] += (q[i]-TransfAll[gp+cluster])*(q[i]-TransfAll[gp+cluster]); } - MPI_Allreduce(sigmaa,sigmaall,nteam+1,MPI_DOUBLE,MPI_SUM,world); - MPI_Allreduce(sigmac,sigmacll,nteam+1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(sigmaa.data(),sigmaall.data(),nteam+1,MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(sigmac.data(),sigmacll.data(),nteam+1,MPI_DOUBLE,MPI_SUM,world); for (gp = 1; gp < nteam+1; gp++) { sigmaall[gp] = sqrt(sigmaall[gp]/static_cast(nQEqaall[gp])) ; -- GitLab From 87a243203b52cd6755a0648b02030fd53948824d Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Thu, 28 Feb 2019 16:46:21 -0700 Subject: [PATCH 0183/1243] Removed pair_granular.cpp/h from src directory --- src/pair_granular.cpp | 2337 ----------------------------------------- src/pair_granular.h | 120 --- 2 files changed, 2457 deletions(-) delete mode 100644 src/pair_granular.cpp delete mode 100644 src/pair_granular.h diff --git a/src/pair_granular.cpp b/src/pair_granular.cpp deleted file mode 100644 index 82a470f83b..0000000000 --- a/src/pair_granular.cpp +++ /dev/null @@ -1,2337 +0,0 @@ -/* ---------------------------------------------------------------------- -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: Leo Silbert (SNL), Gary Grest (SNL), - Jeremy Lechman (SNL), Dan Bolintineanu (SNL), Ishan Srivastava (SNL) ------------------------------------------------------------------------ */ - -#include -#include -#include -#include -#include "pair_granular.h" -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "modify.h" -#include "fix.h" -#include "fix_neigh_history.h" -#include "comm.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "memory.h" -#include "error.h" -#include "math_const.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -#define PI27SQ 266.47931882941264802866 // 27*PI**2 -#define THREEROOT3 5.19615242270663202362 // 3*sqrt(3) -#define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) -#define INVROOT6 0.40824829046386307274 // 1/sqrt(6) -#define FOURTHIRDS 1.333333333333333 // 4/3 -#define TWOPI 6.28318530717959 // 2*PI - -#define EPSILON 1e-10 - -enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; -enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {TANGENTIAL_NOHISTORY, TANGENTIAL_MINDLIN}; -enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; -enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; - -/* ---------------------------------------------------------------------- */ - -PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 1; - no_virial_fdotr_compute = 1; - fix_history = NULL; - - single_extra = 9; - svector = new double[single_extra]; - - neighprev = 0; - - nmax = 0; - mass_rigid = NULL; - - onerad_dynamic = NULL; - onerad_frozen = NULL; - maxrad_dynamic = NULL; - maxrad_frozen = NULL; - - dt = update->dt; - - // set comm size needed by this Pair if used with fix rigid - - comm_forward = 1; - - use_history = 0; - beyond_contact = 0; - nondefault_history_transfer = 0; - tangential_history_index = 0; - roll_history_index = twist_history_index = 0; - -} - -/* ---------------------------------------------------------------------- */ -PairGranular::~PairGranular() -{ - delete [] svector; - if (fix_history) modify->delete_fix("NEIGH_HISTORY"); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - memory->destroy(cut); - - memory->destroy(normal_coeffs); - memory->destroy(tangential_coeffs); - memory->destroy(roll_coeffs); - memory->destroy(twist_coeffs); - - delete [] onerad_dynamic; - delete [] onerad_frozen; - delete [] maxrad_dynamic; - delete [] maxrad_frozen; - } - memory->destroy(mass_rigid); -} - -void PairGranular::compute(int eflag, int vflag){ -#ifdef TEMPLATED_PAIR_GRANULAR - if (normal == HOOKE){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<0,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<0,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<0,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<0,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<0,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<0,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == HERTZ){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<1,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<1,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<1,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<1,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<1,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<1,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == HERTZ_MATERIAL){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<2,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<2,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<2,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<2,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<2,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<2,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == DMT){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<3,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<3,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<3,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<3,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<3,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<3,2,1,3,2>(eflag, vflag); - } - } - } - } - else if (normal == JKR){ - if (damping == VELOCITY){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,0,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,0,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,0,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,0,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,0,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,0,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,0,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,0,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,0,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,0,1,3,2>(eflag, vflag); - } - } - } - else if (damping == VISCOELASTIC){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,1,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,1,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,1,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,1,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,1,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,1,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,1,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,1,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,1,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,1,1,3,2>(eflag, vflag); - } - } - } - else if (damping == TSUJI){ - if (tangential == TANGENTIAL_NOHISTORY){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,2,0,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,2,0,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,2,0,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,2,0,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,0,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,0,3,2>(eflag, vflag); - } - } - else if (tangential == TANGENTIAL_MINDLIN){ - if (twist == TWIST_NONE){ - if (roll == ROLL_NONE) compute_templated<4,2,1,0,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,0,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,0,2>(eflag, vflag); - } - else if (twist == TWIST_NOHISTORY){ - if (roll == ROLL_NONE) compute_templated<4,2,1,1,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,1,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,1,2>(eflag, vflag); - } - else if (twist == TWIST_SDS){ - if (roll == ROLL_NONE) compute_templated<4,2,1,2,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,2,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,2,2>(eflag, vflag); - } - else if (twist == TWIST_MARSHALL){ - if (roll == ROLL_NONE) compute_templated<4,2,1,3,0>(eflag, vflag); - else if (roll == ROLL_NOHISTORY) compute_templated<4,2,1,3,1>(eflag, vflag); - else if (roll == ROLL_SDS) compute_templated<4,2,1,3,2>(eflag, vflag); - } - } - } - } - -#else - compute_untemplated(Tp_normal, Tp_damping, Tp_tangential, - Tp_roll, Tp_twist, - eflag, vflag); -#endif -} - -#ifdef TEMPLATED_PAIR_GRANULAR -template < int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_twist, int Tp_roll > -void PairGranular::compute_templated(int eflag, int vflag) -#else -void PairGranular::compute_untemplated - (int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_twist, int Tp_roll, int eflag, int vflag) -#endif -{ - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv; - double Reff, delta, dR, dR2; - - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - - double knfac, damp_normal; - double k_tangential, damp_tangential; - double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; - double fs, fs1, fs2, fs3; - - //For JKR - double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; - double t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; - - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - - //Rolling - double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - - //Twisting - double k_twist, damp_twist, mu_twist; - double signtwist, magtwist, magtortwist, Mtcrit; - double tortwist1, tortwist2, tortwist3; - - double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *history,*allhistory,**firsthistory; - - bool touchflag; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int historyupdate = 1; - if (update->setupflag) historyupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - double **x = atom->x; - double **v = atom->v; - double **f = atom->f; - int *type = atom->type; - 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 newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firsthistory = fix_history->firstvalue; - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - itype = type[i]; - radi = radius[i]; - touch = firsttouch[i]; - allhistory = firsthistory[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]; - jtype = type[j]; - rsq = delx*delx + dely*dely + delz*delz; - radj = radius[j]; - radsum = radi + radj; - - E = normal_coeffs[itype][jtype][0]; - Reff = radi*radj/(radi+radj); - touchflag = false; - - if (Tp_normal == JKR){ - if (touch[jj]){ - R2 = Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - a = cbrt(9.0*M_PI*coh*R2/(4*E)); - delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); - dist_pulloff = radsum-delta_pulloff; - touchflag = (rsq < dist_pulloff*dist_pulloff); - } - else{ - touchflag = (rsq < radsum*radsum); - } - } - else{ - touchflag = (rsq < radsum*radsum); - } - - if (!touchflag){ - // unset non-touching neighbors - touch[jj] = 0; - history = &allhistory[size_history*jj]; - for (int k = 0; k < size_history; k++) history[k] = 0.0; - } - else{ - r = sqrt(rsq); - rinv = 1.0/r; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - delta = radsum - r; - dR = delta*Reff; - if (Tp_normal == JKR){ - touch[jj] = 1; - R2=Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - dR2 = dR*dR; - t0 = coh*coh*R2*R2*E; - t1 = PI27SQ*t0; - t2 = 8*dR*dR2*E*E*E; - t3 = 4*dR2*E; - sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues - t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); - t5 = t3/t4 + t4/E; - sqrt2 = MAX(0, 2*dR + t5); - t6 = sqrt(sqrt2); - sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); - a = INVROOT6*(t6 + sqrt(sqrt3)); - a2 = a*a; - knfac = FOURTHIRDS*E*a; - Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - } - else{ - knfac = E; //Hooke - Fne = knfac*delta; - if (Tp_normal != HOOKE) - a = sqrt(dR); - Fne *= a; - if (Tp_normal == DMT) - Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; - } - - //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (Tp_damping == VELOCITY){ - damp_normal = 1; - } - else if (Tp_damping == VISCOELASTIC){ - if (Tp_normal == HOOKE) a = sqrt(dR); - damp_normal = a*meff; - } - else if (Tp_damping == TSUJI){ - damp_normal = sqrt(meff*knfac); - } - - Fdamp = -normal_coeffs[itype][jtype][1]*damp_normal*vnnr; - - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // If any history is needed: - if (use_history){ - touch[jj] = 1; - history = &allhistory[size_history*jj]; - } - - - if (Tp_normal == JKR){ - F_pulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*F_pulloff); - } - else{ - Fcrit = fabs(Fne); - } - - //------------------------------ - //Tangential forces - //------------------------------ - k_tangential = tangential_coeffs[itype][jtype][0]; - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - - if (Tp_tangential > 0){ - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - - // Rotate and update displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (historyupdate) { - rsht = history[0]*nx + history[1]*ny + history[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - history[0] -= rsht*nx; - history[1] -= rsht*ny; - history[2] -= rsht*nz; - //Also rescale to preserve magnitude - history[0] *= scalefac; - history[1] *= scalefac; - history[2] *= scalefac; - } - //Update history - history[0] += vtr1*dt; - history[1] += vtr2*dt; - history[2] += vtr3*dt; - } - - // tangential forces = history + tangential velocity damping - fs1 = -k_tangential*history[0] - damp_tangential*vtr1; - fs2 = -k_tangential*history[1] - damp_tangential*vtr2; - fs3 = -k_tangential*history[2] - damp_tangential*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); - history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); - history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - } - else{ //Classic pair gran/hooke (no history) - fs = meff*damp_tangential*vrel; - if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; - else Ft = 0.0; - fs1 = -Ft*vtr1; - fs2 = -Ft*vtr2; - fs3 = -Ft*vtr3; - } - - //**************************************** - // Rolling resistance - //**************************************** - - if (Tp_roll != ROLL_NONE){ - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - if (Tp_roll > 1){ - int rhist0 = roll_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - - if (historyupdate){ - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - history[rhist0] -= rolldotn*nx; - history[rhist1] -= rolldotn*ny; - history[rhist2] -= rolldotn*nz; - //Also rescale to preserve magnitude - history[rhist0] *= scalefac; - history[rhist1] *= scalefac; - history[rhist2] *= scalefac; - } - history[rhist0] += vrl1*dt; - history[rhist1] += vrl2*dt; - history[rhist2] += vrl3*dt; - } - - k_roll = roll_coeffs[itype][jtype][0]; - damp_roll = roll_coeffs[itype][jtype][1]; - fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; - fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; - fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - } - else{ // - fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; - } - } - - //**************************************** - // Twisting torque, including history effects - //**************************************** - if (Tp_twist != TWIST_NONE){ - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (Tp_twist == TWIST_MARSHALL){ - k_twist = 0.5*k_tangential*a*a;; //eq 32 - damp_twist = 0.5*damp_tangential*a*a; - mu_twist = TWOTHIRDS*a; - } - else{ - k_twist = twist_coeffs[itype][jtype][0]; - damp_twist = twist_coeffs[itype][jtype][1]; - mu_twist = twist_coeffs[itype][jtype][2]; - } - if (Tp_twist > 1){ - if (historyupdate){ - history[twist_history_index] += magtwist*dt; - } - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; - } - } - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - if (Tp_twist != TWIST_NONE){ - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - } - - if (Tp_roll != ROLL_NONE){ - torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = Reff*(nz*fr1 - nx*fr3); - torroll3 = Reff*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - } - - if (force->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 (Tp_twist != TWIST_NONE){ - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - } - if (Tp_roll != ROLL_NONE){ - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } -} - - -/* ---------------------------------------------------------------------- -allocate all arrays -------------------------------------------------------------------------- */ - -void PairGranular::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(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); - memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); - memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); - memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); - - onerad_dynamic = new double[n+1]; - onerad_frozen = new double[n+1]; - maxrad_dynamic = new double[n+1]; - maxrad_frozen = new double[n+1]; -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairGranular::settings(int narg, char **arg) -{ - if (narg == 1){ - cutoff_global = force->numeric(FLERR,arg[0]); - } - else{ - cutoff_global = -1; //Will be set based on particle sizes, model choice - } - tangential_history = 0; - roll_history = twist_history = 0; - normal_set = tangential_set = damping_set = roll_set = twist_set = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairGranular::coeff(int narg, char **arg) -{ - double normal_coeffs_local[4]; - double tangential_coeffs_local[4]; - double roll_coeffs_local[4]; - double twist_coeffs_local[4]; - - if (narg < 2) - error->all(FLERR,"Incorrect args for pair coefficients"); - - if (!allocated) allocate(); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - int iarg = 2; - while (iarg < narg){ - if (strcmp(arg[iarg], "hooke") == 0){ - if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); - if (!normal_set) normal = HOOKE; - else if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_set = 1; - iarg += 3; - } - else if (strcmp(arg[iarg], "hertz") == 0){ - int num_coeffs = 2; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = HERTZ; - else if (normal_set && normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_set = 1; - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "hertz/material") == 0){ - int num_coeffs = 3; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = HERTZ_MATERIAL; - else if (normal != HERTZ) if (normal != HOOKE) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_set = 1; - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "dmt") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - if (!normal_set) normal = DMT; - else if (normal != DMT) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion - normal_set = 1; - iarg += 5; - } - else if (strcmp(arg[iarg], "jkr") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); - beyond_contact = 1; - if (!normal_set) normal = JKR; - else if (normal != JKR) error->all(FLERR, "Illegal pair_coeff command, choice of normal contact model must be the same for all types"); - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion - normal_set = 1; - iarg += 5; - } - else if (strcmp(arg[iarg], "damp") == 0){ - if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); - if (strcmp(arg[iarg+1], "velocity") == 0){ - if (!damping_set) damping = VELOCITY; - else if (damping != VELOCITY) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); - } - else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ - if (!damping_set) damping = VISCOELASTIC; - else if (damping != VISCOELASTIC) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); - } - else if (strcmp(arg[iarg+1], "tsuji") == 0){ - if (!damping_set) damping = TSUJI; - if (damping != TSUJI) error->all(FLERR, "Illegal pair_coeff command, choice of damping contact model must be the same for all types"); - } - damping_set = 1; - iarg += 2; - } - else if (strcmp(arg[iarg], "tangential") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - if (!tangential_set) tangential = TANGENTIAL_NOHISTORY; - else if (tangential != TANGENTIAL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types"); - } - else if (strcmp(arg[iarg+1], "mindlin") == 0){ - if (!tangential_set) tangential = TANGENTIAL_MINDLIN; - else if (tangential != TANGENTIAL_MINDLIN) error->all(FLERR, "Illegal pair_coeff command, choice of tangential contact model must be the same for all types");; - tangential_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); - } - tangential_set = 1; - tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - else if (strcmp(arg[iarg], "rolling") == 0){ - if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ - if (!roll_set) roll = ROLL_NONE; - else if (roll != ROLL_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - if (!roll_set) roll = ROLL_NOHISTORY; - else if (roll != ROLL_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); - } - else if (strcmp(arg[iarg+1], "sds") == 0){ - if (!roll_set) roll = ROLL_SDS; - else if (roll != ROLL_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of rolling friction model must be the same for all types"); - roll_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); - } - roll_set =1 ; - roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kR - roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR - roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. - iarg += 5; - } - } - else if (strcmp(arg[iarg], "twisting") == 0){ - if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ - if (!twist_set) twist = TWIST_NONE; - else if (twist != TWIST_NONE) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); - iarg += 2; - } - else if (strcmp(arg[iarg+1], "marshall") == 0){ - if (!twist_set) twist = TWIST_MARSHALL; - else if (twist != TWIST_MARSHALL) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); - twist_history = 1; - twist_set = 1; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - else if (strcmp(arg[iarg+1], "nohistory") == 0){ - if (!twist_set) twist = TWIST_NOHISTORY; - if (twist != TWIST_NOHISTORY) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); - } - else if (strcmp(arg[iarg+1], "sds") == 0){ - if (!twist_set) twist = TWIST_SDS; - else if (twist != TWIST_SDS) error->all(FLERR, "Illegal pair_coeff command, choice of twisting friction model must be the same for all types"); - twist_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); - } - twist_set = 1; - twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - } - else error->all(FLERR, "Illegal pair coeff command"); - } - - //It is an error not to specify normal or tangential model - if (!normal_set) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); - if (!tangential_set) error->all(FLERR, "Illegal pair coeff command, must specify tangential contact model"); - - //If unspecified, set damping to VISCOELASTIC, twist/roll to NONE (cannot be changed by subsequent pair_coeff commands) - if (!damping_set) damping = VISCOELASTIC; - if (!roll_set) roll = ROLL_NONE; - if (!twist_set) twist = TWIST_NONE; - damping_set = roll_set = twist_set = 1; - - int count = 0; - double damp; - if (damping == TSUJI){ - double cor; - cor = normal_coeffs_local[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_local[1]; - - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_local[0]; - normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; - if (normal != HERTZ && normal != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_local[3]; - - for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_local[k]; - - if (roll != ROLL_NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_local[k]; - - if (twist != TWIST_NONE && twist != TWIST_MARSHALL) - for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_local[k]; - - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairGranular::init_style() -{ - int i; - - // error and warning checks - - if (!atom->radius_flag || !atom->rmass_flag) - error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); - if (comm->ghost_velocity == 0) - error->all(FLERR,"Pair granular requires ghost atoms store velocity"); - - // Determine whether we need a granular neigh list, how large it needs to be - use_history = tangential_history || roll_history || twist_history; - - //For JKR, will need fix/neigh/history to keep track of touch arrays - if (normal == JKR) use_history = 1; - - size_history = 3*tangential_history + 3*roll_history + twist_history; - - //Determine location of tangential/roll/twist histories in array - if (roll_history){ - if (tangential_history) roll_history_index = 3; - else roll_history_index = 0; - } - if (twist_history){ - if (tangential_history){ - if (roll_history) twist_history_index = 6; - else twist_history_index = 3; - } - else{ - if (roll_history) twist_history_index = 3; - else twist_history_index = 0; - } - } - - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->size = 1; - if (use_history) neighbor->requests[irequest]->history = 1; - - dt = update->dt; - - // if history is stored: - // if first init, create Fix needed for storing history - - if (use_history && fix_history == NULL) { - char dnumstr[16]; - sprintf(dnumstr,"%d",size_history); - char **fixarg = new char*[4]; - fixarg[0] = (char *) "NEIGH_HISTORY"; - fixarg[1] = (char *) "all"; - fixarg[2] = (char *) "NEIGH_HISTORY"; - fixarg[3] = dnumstr; - modify->add_fix(4,fixarg,1); - delete [] fixarg; - fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; - fix_history->pair = this; - } - - // check for FixFreeze and set freeze_group_bit - - for (i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"freeze") == 0) break; - if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; - else freeze_group_bit = 0; - - // check for FixRigid so can extract rigid body masses - - fix_rigid = NULL; - for (i = 0; i < modify->nfix; i++) - if (modify->fix[i]->rigid_flag) break; - if (i < modify->nfix) fix_rigid = modify->fix[i]; - - // check for FixPour and FixDeposit so can extract particle radii - - int ipour; - for (ipour = 0; ipour < modify->nfix; ipour++) - if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; - if (ipour == modify->nfix) ipour = -1; - - int idep; - for (idep = 0; idep < modify->nfix; idep++) - if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; - if (idep == modify->nfix) idep = -1; - - // set maxrad_dynamic and maxrad_frozen for each type - // include future FixPour and FixDeposit particles as dynamic - - int itype; - for (i = 1; i <= atom->ntypes; i++) { - onerad_dynamic[i] = onerad_frozen[i] = 0.0; - if (ipour >= 0) { - itype = i; - double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); - if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); - onerad_dynamic[i] = radmax; - } - if (idep >= 0) { - itype = i; - double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); - if (normal == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); - onerad_dynamic[i] = radmax; - } - } - - double *radius = atom->radius; - int *mask = atom->mask; - int *type = atom->type; - int nlocal = atom->nlocal; - - for (i = 0; i < nlocal; i++){ - double radius_cut = radius[i]; - if (normal == JKR){ - radius_cut = radius[i] - 0.5*pulloff_distance(radius[i], type[i]); - } - if (mask[i] & freeze_group_bit){ - onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); - } - else{ - onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius_cut); - } - } - - MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - - // set fix which stores history info - - if (size_history > 0){ - int ifix = modify->find_fix("NEIGH_HISTORY"); - if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); - fix_history = (FixNeighHistory *) modify->fix[ifix]; - } -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairGranular::init_one(int i, int j) -{ - double cutoff; - if (setflag[i][j] == 0) { - - if (normal != HOOKE && normal != HERTZ){ - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], - normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - normal_coeffs[i][j][2] = normal_coeffs[j][i][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], - normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - } - else{ - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); - } - - normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); - if ((normal == JKR) || (normal == DMT)) - normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); - - for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - - - if (roll != ROLL_NONE){ - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); - } - - if (twist != TWIST_NONE && twist != TWIST_MARSHALL){ - for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); - } - } - - // It is possible that cut[i][j] at this point is still 0.0. This can happen when - // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates - // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size - // To avoid this issue, for cases involving cut[i][j] = 0.0 (possible only - // if there is no current information about radius/cutoff of type i and j). - // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. - - if (cutoff_global < 0){ - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || - ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); - } - cutoff = cutmax; - } - } - else{ - cutoff = cutoff_global; - } - return cutoff; -} - - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file - ------------------------------------------------------------------------- */ - -void PairGranular::write_restart(FILE *fp) -{ - int i,j; - fwrite(&normal,sizeof(int),1,fp); - fwrite(&damping,sizeof(int),1,fp); - fwrite(&tangential,sizeof(int),1,fp); - fwrite(&roll,sizeof(int),1,fp); - fwrite(&twist,sizeof(int),1,fp); - 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(&normal_coeffs[i][j],sizeof(double),4,fp); - fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); - fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); - fwrite(&twist_coeffs[i][j],sizeof(double),3,fp); - fwrite(&cut[i][j],sizeof(double),1,fp); - } - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts - ------------------------------------------------------------------------- */ - -void PairGranular::read_restart(FILE *fp) -{ - allocate(); - int i,j; - int me = comm->me; - if (me == 0){ - fread(&normal,sizeof(int),1,fp); - fread(&damping,sizeof(int),1,fp); - fread(&tangential,sizeof(int),1,fp); - fread(&roll,sizeof(int),1,fp); - fread(&twist,sizeof(int),1,fp); - } - MPI_Bcast(&normal,1,MPI_INT,0,world); - MPI_Bcast(&damping,1,MPI_INT,0,world); - MPI_Bcast(&tangential,1,MPI_INT,0,world); - MPI_Bcast(&roll,1,MPI_INT,0,world); - MPI_Bcast(&twist,1,MPI_INT,0,world); - 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(&normal_coeffs[i][j],sizeof(double),4,fp); - fread(&tangential_coeffs[i][j],sizeof(double),3,fp); - fread(&roll_coeffs[i][j],sizeof(double),3,fp); - fread(&twist_coeffs[i][j],sizeof(double),3,fp); - fread(&cut[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); - MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); - MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); - MPI_Bcast(&twist_coeffs[i][j],3,MPI_DOUBLE,0,world); - MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); - } - } - } -} - - -/* ---------------------------------------------------------------------- */ - -void PairGranular::reset_dt() -{ - dt = update->dt; -} - -/* ---------------------------------------------------------------------- */ - -double PairGranular::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, double &fforce) -{ - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; - double dR, dR2; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - - double knfac, damp_normal; - double k_tangential, damp_tangential; - double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; - double fs, fs1, fs2, fs3; - - //For JKR - double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; - double delta, t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; - - - //Rolling - double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - - //Twisting - double k_twist, damp_twist, mu_twist; - double signtwist, magtwist, magtortwist, Mtcrit; - double tortwist1, tortwist2, tortwist3; - - double shrmag,rsht; - int jnum; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *history,*allhistory,**firsthistory; - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - Reff = radi*radj/(radi+radj); - - bool touchflag; - if (normal == JKR){ - R2 = Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - a = cbrt(9.0*M_PI*coh*R2/(4*E)); - delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); - dist_pulloff = radsum+delta_pulloff; - touchflag = (rsq <= dist_pulloff*dist_pulloff); - } - else{ - touchflag = (rsq <= radsum*radsum); - } - - if (touchflag){ - fforce = 0.0; - for (int m = 0; m < single_extra; m++) svector[m] = 0.0; - return 0.0; - } - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - r = sqrt(rsq); - rinv = 1.0/r; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // relative translational velocity - - double **v = atom->v; - 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*nx + vr2*ny + vr3*nz; - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - double *rmass = atom->rmass; - int *mask = atom->mask; - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - delta = radsum - r; - dR = delta*Reff; - - // tangential component - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - double **omega = atom->omega; - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - int *type = atom->type; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - delta = radsum - r; - dR = delta*Reff; - if (normal == JKR){ - dR2 = dR*dR; - t0 = coh*coh*R2*R2*E; - t1 = PI27SQ*t0; - t2 = 8*dR*dR2*E*E*E; - t3 = 4*dR2*E; - sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues - t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); - t5 = t3/t4 + t4/E; - sqrt2 = MAX(0, 2*dR + t5); - t6 = sqrt(sqrt2); - sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); - a = INVROOT6*(t6 + sqrt(sqrt3)); - a2 = a*a; - knfac = FOURTHIRDS*E*a; - Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - } - else{ - knfac = E; - Fne = knfac*delta; - if (normal != HOOKE) - a = sqrt(dR); - Fne *= a; - if (normal == DMT) - Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; - } - - //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping == VELOCITY){ - damp_normal = normal_coeffs[itype][jtype][1]; - } - else if (damping == VISCOELASTIC){ - if (normal == HOOKE) a = sqrt(dR); - damp_normal = normal_coeffs[itype][jtype][1]*a*meff; - } - else if (damping == TSUJI){ - damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); - } - - Fdamp = -damp_normal*vnnr; - - Fntot = Fne + Fdamp; - - jnum = list->numneigh[i]; - jlist = list->firstneigh[i]; - - if (use_history){ - allhistory = fix_history->firstvalue[i]; - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - history = &allhistory[size_history*neighprev]; - } - - //**************************************** - //Tangential force, including history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - Fcrit = fabs(Fne); - if (normal == JKR){ - F_pulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*F_pulloff); - } - - //------------------------------ - //Tangential forces - //------------------------------ - k_tangential = tangential_coeffs[itype][jtype][0]; - if (normal != HOOKE){ - k_tangential *= a; - } - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - - if (tangential_history){ - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - - // tangential forces = history + tangential velocity damping - fs1 = -k_tangential*history[0] - damp_tangential*vtr1; - fs2 = -k_tangential*history[1] - damp_tangential*vtr2; - fs3 = -k_tangential*history[2] - damp_tangential*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); - history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); - history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - } - else{ //Classic pair gran/hooke (no history) - fs = meff*damp_tangential*vrel; - if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; - else Ft = 0.0; - fs1 = -Ft*vtr1; - fs2 = -Ft*vtr2; - fs3 = -Ft*vtr3; - } - - //**************************************** - // Rolling resistance - //**************************************** - - if (roll != ROLL_NONE){ - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - if (roll_history){ - int rhist0 = roll_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - - k_roll = roll_coeffs[itype][jtype][0]; - damp_roll = roll_coeffs[itype][jtype][1]; - fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; - fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; - fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - } - else{ // - fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; - } - } - - //**************************************** - // Twisting torque, including history effects - //**************************************** - if (twist != TWIST_NONE){ - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist == TWIST_MARSHALL){ - k_twist = 0.5*k_tangential*a*a;; //eq 32 - damp_twist = 0.5*damp_tangential*a*a; - mu_twist = TWOTHIRDS*a; - } - else{ - k_twist = twist_coeffs[itype][jtype][0]; - damp_twist = twist_coeffs[itype][jtype][1]; - mu_twist = twist_coeffs[itype][jtype][2]; - } - if (twist_history){ - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; - } - } - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = fr1; - svector[5] = fr2; - svector[6] = fr3; - svector[7] = fr; - svector[8] = magtortwist; - return 0.0; -} - -/* ---------------------------------------------------------------------- */ - -int PairGranular::pack_forward_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++] = mass_rigid[j]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void PairGranular::unpack_forward_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) - mass_rigid[i] = buf[m++]; -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays - ------------------------------------------------------------------------- */ - -double PairGranular::memory_usage() -{ - double bytes = nmax * sizeof(double); - return bytes; -} - -/* ---------------------------------------------------------------------- - mixing of Young's modulus (E) -------------------------------------------------------------------------- */ - -double PairGranular::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) -{ - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); -} - -/* ---------------------------------------------------------------------- - mixing of shear modulus (G) - ------------------------------------------------------------------------- */ - -double PairGranular::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) -{ - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); -} - -/* ---------------------------------------------------------------------- - mixing of everything else -------------------------------------------------------------------------- */ - -double PairGranular::mix_geom(double valii, double valjj) -{ - return sqrt(valii*valjj); -} - - -/* ---------------------------------------------------------------------- - Compute pull-off distance (beyond contact) for a given radius and atom type -------------------------------------------------------------------------- */ - -double PairGranular::pulloff_distance(double radius, int itype) -{ - double E, coh, a, delta_pulloff; - coh = normal_coeffs[itype][itype][3]; - E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], - normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); - a = cbrt(9*M_PI*coh*radius*radius/(4*E)); - return a*a/radius - 2*sqrt(M_PI*coh*a/E); -} - diff --git a/src/pair_granular.h b/src/pair_granular.h deleted file mode 100644 index f39f31e4cb..0000000000 --- a/src/pair_granular.h +++ /dev/null @@ -1,120 +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(granular,PairGranular) - -#else - -#ifndef LMP_PAIR_GRANULAR_H -#define LMP_PAIR_GRANULAR_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairGranular : public Pair { -public: - PairGranular(class LAMMPS *); - virtual ~PairGranular(); - - void compute(int, int); - // comment next line to turn off templating -#define TEMPLATED_PAIR_GRANULAR -#ifdef TEMPLATED_PAIR_GRANULAR - template < int Tp_normal, int Tp_damping, int Tp_tangential, - int Tp_roll, int Tp_twist> - void compute_templated(int, int); -#else - void compute_untemplated(int, int, int, int, int, - int, int); -#endif - - virtual void settings(int, char **); - virtual void coeff(int, char **); - void init_style(); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - void reset_dt(); - virtual double single(int, int, int, int, double, double, double, double &); - int pack_forward_comm(int, int *, double *, int, int *); - void unpack_forward_comm(int, int, double *); - double memory_usage(); - - protected: - double cut_global; - double dt; - int freeze_group_bit; - int use_history; - - int neighprev; - double *onerad_dynamic,*onerad_frozen; - double *maxrad_dynamic,*maxrad_frozen; - double **cut; - - class FixNeighHistory *fix_history; - - // storage of rigid body masses for use in granular interactions - - class Fix *fix_rigid; // ptr to rigid body fix, NULL if none - double *mass_rigid; // rigid mass for owned+ghost atoms - int nmax; // allocated size of mass_rigid - - virtual void allocate(); - -private: - int size_history; - - //Models - int normal, damping, tangential, roll, twist; - - //History flags - int tangential_history, roll_history, twist_history; - - //Indices of history entries - int tangential_history_index, roll_history_index, twist_history_index; - - //Flags for whether model choices have been set - int normal_set, tangential_set, damping_set, roll_set, twist_set; - - //Per-type coefficients, set in pair coeff command - double ***normal_coeffs; - double ***tangential_coeffs; - double ***roll_coeffs; - double ***twist_coeffs; - - //Optional user-specified global cutoff - double cutoff_global; - - double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); - double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); - double mix_geom(double valii, double valjj); - double pulloff_distance(double radius, int itype); -}; - -} - -#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. - - */ -- GitLab From d8845b681778adb5776165f19e99b730eb4ff66c Mon Sep 17 00:00:00 2001 From: mkanski Date: Fri, 1 Mar 2019 13:13:11 +0100 Subject: [PATCH 0184/1243] Added initialization of the entire num_bonds and num_hbonds arrays --- src/USER-REAXC/fix_reaxc.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/USER-REAXC/fix_reaxc.cpp b/src/USER-REAXC/fix_reaxc.cpp index c470173663..1323ff4da7 100644 --- a/src/USER-REAXC/fix_reaxc.cpp +++ b/src/USER-REAXC/fix_reaxc.cpp @@ -49,8 +49,7 @@ FixReaxC::FixReaxC(LAMMPS *lmp,int narg, char **arg) : // initialize arrays to MIN so atom migration is OK the 1st time - int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) + for (int i = 0; i < atom->nmax; i++) num_bonds[i] = num_hbonds[i] = MIN_REAX_BONDS; // set comm sizes needed by this fix -- GitLab From 0f0a65bb4803332b86f3eb53dec6e303c60b386c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 27 Feb 2019 17:49:34 -0500 Subject: [PATCH 0185/1243] plug small memory leak in USER-ADIOS --- src/USER-ADIOS/dump_custom_adios.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/USER-ADIOS/dump_custom_adios.cpp b/src/USER-ADIOS/dump_custom_adios.cpp index cd14195d45..67f3deeb64 100644 --- a/src/USER-ADIOS/dump_custom_adios.cpp +++ b/src/USER-ADIOS/dump_custom_adios.cpp @@ -154,6 +154,7 @@ DumpCustomADIOS::~DumpCustomADIOS() internal->fh.Close(); } delete internal->ad; + delete internal; } /* ---------------------------------------------------------------------- */ -- GitLab From 30ee2f3d78655b3145cf271202158b252630ab3a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 28 Feb 2019 19:27:55 -0500 Subject: [PATCH 0186/1243] avoid windows portability issues with int32_t --- src/USER-PTM/compute_ptm_atom.h | 2 +- src/USER-PTM/ptm_neighbour_ordering.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/USER-PTM/compute_ptm_atom.h b/src/USER-PTM/compute_ptm_atom.h index 5c10e0c443..586d7a44cd 100644 --- a/src/USER-PTM/compute_ptm_atom.h +++ b/src/USER-PTM/compute_ptm_atom.h @@ -35,7 +35,7 @@ class ComputePTMAtom : public Compute { private: int nmax; - int32_t input_flags; + smallint input_flags; double rmsd_threshold; class NeighList *list; double **output; diff --git a/src/USER-PTM/ptm_neighbour_ordering.h b/src/USER-PTM/ptm_neighbour_ordering.h index 4a4fb8ce8b..2a619880bb 100644 --- a/src/USER-PTM/ptm_neighbour_ordering.h +++ b/src/USER-PTM/ptm_neighbour_ordering.h @@ -11,6 +11,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #define PTM_NEIGHBOUR_ORDERING_H #include +#include namespace ptm { -- GitLab From 5ecbb8bd0130881b97370e24f7a48ef2daf5b77d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 1 Mar 2019 09:46:13 -0500 Subject: [PATCH 0187/1243] fix int vs. bigint issue and add NULL file pointer check to dynamical_matrix --- src/USER-PHONON/dynamical_matrix.cpp | 5 +++-- src/USER-PHONON/dynamical_matrix.h | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index cef59b3a63..372f4e4e31 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -316,9 +316,10 @@ void DynamicalMatrix::calculateMatrix() void DynamicalMatrix::writeMatrix(double **dynmat) { - if (me != 0) - return; + if (me != 0 || fp == NULL) return; + // print file comment lines + if (!binaryflag && fp) { clearerr(fp); for (int i = 0; i < 3; i++) { diff --git a/src/USER-PHONON/dynamical_matrix.h b/src/USER-PHONON/dynamical_matrix.h index 187968c8f7..56de814e97 100644 --- a/src/USER-PHONON/dynamical_matrix.h +++ b/src/USER-PHONON/dynamical_matrix.h @@ -54,10 +54,10 @@ namespace LAMMPS_NS { double conv_mass; double del; int igroup,groupbit; - int gcount; // number of atoms in group + bigint gcount; // number of atoms in group + bigint dynlen; // rank of dynamical matrix int scaleflag; int me; - bigint dynlen; int *groupmap; int compressed; // 1 if dump file is written compressed, 0 no @@ -71,4 +71,4 @@ namespace LAMMPS_NS { #endif //LMP_DYNAMICAL_MATRIX_H -#endif \ No newline at end of file +#endif -- GitLab From f0ec2e3279ccb08e86e2b47950c660d3abf5cd99 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 1 Mar 2019 18:47:34 -0700 Subject: [PATCH 0188/1243] refactoring of global and local hyper, including amended doc pages --- doc/src/compute.txt | 7 +- doc/src/fix.txt | 6 +- doc/src/fix_ave_histo.txt | 19 +- doc/src/fix_hyper_global.txt | 45 ++- doc/src/fix_hyper_local.txt | 235 +++++++---- examples/hyper/in.hyper.global | 6 +- examples/hyper/in.hyper.local | 6 + src/REPLICA/fix_hyper_global.cpp | 157 ++++---- src/REPLICA/fix_hyper_global.h | 6 +- src/REPLICA/fix_hyper_local.cpp | 671 +++++++++++++++++++------------ src/REPLICA/fix_hyper_local.h | 85 ++-- src/REPLICA/hyper.cpp | 158 +++----- src/fix_ave_histo.cpp | 84 ++-- src/thermo.cpp | 3 +- 14 files changed, 861 insertions(+), 627 deletions(-) diff --git a/doc/src/compute.txt b/doc/src/compute.txt index 4886e73ab6..87dbee57d6 100644 --- a/doc/src/compute.txt +++ b/doc/src/compute.txt @@ -54,9 +54,10 @@ local quantities have the word "local" in their style, e.g. {bond/local}. Styles with neither "atom" or "local" in their style produce global quantities. -Note that a single compute produces either global or per-atom or local -quantities, but never more than one of these (with only a few -exceptions, as documented by individual compute commands). +Note that a single compute can produce either global or per-atom or +local quantities, but not both global and per-atom. It can produce +local quantities in tandem with global or per-atom quantities. The +compute doc page will explain. Global, per-atom, and local quantities each come in three kinds: a single scalar value, a vector of values, or a 2d array of values. The diff --git a/doc/src/fix.txt b/doc/src/fix.txt index 395f2ad7a9..9b48ee13bf 100644 --- a/doc/src/fix.txt +++ b/doc/src/fix.txt @@ -83,8 +83,10 @@ not in the specified fix group. Local quantities are calculated by each processor based on the atoms it owns, but there may be zero or more per atoms. -Note that a single fix may produces either global or per-atom or local -quantities (or none at all), but never more than one of these. +Note that a single fix can produce either global or per-atom or local +quantities (or none at all), but not both global and per-atom. It can +produce local quantities in tandem with global or per-atom quantities. +The fix doc page will explain. Global, per-atom, and local quantities each come in three kinds: a single scalar value, a vector of values, or a 2d array of values. The diff --git a/doc/src/fix_ave_histo.txt b/doc/src/fix_ave_histo.txt index 79f4d53481..6f99685682 100644 --- a/doc/src/fix_ave_histo.txt +++ b/doc/src/fix_ave_histo.txt @@ -35,6 +35,7 @@ keyword = {mode} or {file} or {ave} or {start} or {beyond} or {overwrite} or {ti {mode} arg = {scalar} or {vector} scalar = all input values are scalars vector = all input values are vectors + {kind} arg = {global} or {peratom} or {local} {file} arg = filename filename = name of file to output histogram(s) to {ave} args = {one} or {running} or {window} @@ -92,7 +93,8 @@ either all global, all per-atom, or all local quantities. Inputs of different kinds (e.g. global and per-atom) cannot be mixed. Atom attributes are per-atom vector values. See the doc page for individual "compute" and "fix" commands to see what kinds of -quantities they generate. +quantities they generate. See the optional {kind} keyword below for +how to force the fix ave/histo command to dis-ambiguate if necessary. Note that the output of this command is a single histogram for all input values combined together, not one histogram per input value. @@ -231,6 +233,14 @@ keyword is set to {vector}, then all input values must be global or per-atom or local vectors, or columns of global or per-atom or local arrays. +The {kind} keyword only needs to be set if a compute or fix produces +more than one kind of output (global, per-atom, local). If this is +not the case, then LAMMPS will determine what kind of input is +provided and whether all the input arguments are consistent. If a +compute or fix produces more than one kind of output, the {kind} +keyword should be used to specify which output will be used. The +remaining input arguments must still be consistent. + The {beyond} keyword determines how input values that fall outside the {lo} to {hi} bounds are treated. Values such that {lo} <= value <= {hi} are assigned to one bin. Values on a bin boundary are assigned @@ -240,7 +250,7 @@ If {beyond} is set to {end} then values < {lo} are counted in the first bin and values > {hi} are counted in the last bin. If {beyond} is set to {extend} then two extra bins are created, so that there are Nbins+2 total bins. Values < {lo} are counted in the first bin and -values > {hi} are counted in the last bin (Nbins+1). Values between +values > {hi} are counted in the last bin (Nbins+2). Values between {lo} and {hi} (inclusive) are counted in bins 2 through Nbins+1. The "coordinate" stored and printed for these two extra bins is {lo} and {hi}. @@ -354,5 +364,6 @@ ave/chunk"_fix_ave_chunk.html, "fix ave/time"_fix_ave_time.html, [Default:] none -The option defaults are mode = scalar, ave = one, start = 0, no file -output, beyond = ignore, and title 1,2,3 = strings as described above. +The option defaults are mode = scalar, kind = figured out from input +arguments, ave = one, start = 0, no file output, beyond = ignore, and +title 1,2,3 = strings as described above. diff --git a/doc/src/fix_hyper_global.txt b/doc/src/fix_hyper_global.txt index a7a938b144..81404ac6a2 100644 --- a/doc/src/fix_hyper_global.txt +++ b/doc/src/fix_hyper_global.txt @@ -102,7 +102,7 @@ Bi = exp(beta * Vij(max)) :pre where beta = 1/kTequil, and {Tequil} is the temperature of the system and an argument to this fix. Note that Bi >= 1 at every step. -NOTE: To run GHD, the input script must also use the "fix +NOTE: To run a GHD simulation, the input script must also use the "fix langevin"_fix_langevin.html command to thermostat the atoms at the same {Tequil} as specified by this fix, so that the system is running constant-temperature (NVT) dynamics. LAMMPS does not check that this @@ -166,9 +166,9 @@ correctly. There will just be fewer events because the hyper time NOTE: If you have no physical intuition as to the smallest barrier height in your system, a reasonable strategy to determine the largest -{Vmax} you can use for an LHD model, is to run a sequence of +{Vmax} you can use for a GHD model, is to run a sequence of simulations with smaller and smaller {Vmax} values, until the event -rate does not change. +rate does not change (as a function of hyper time). The {Tequil} argument is the temperature at which the system is simulated; see the comment above about the "fix @@ -177,7 +177,8 @@ beta term in the exponential factor that determines how much boost is achieved as a function of the bias potential. In general, the lower the value of {Tequil} and the higher the value -of {Vmax}, the more boost will be achievable by the GHD algorithm. +of {Vmax}, the more time boost will be achievable by the GHD +algorithm. :line @@ -190,41 +191,43 @@ The "fix_modify"_fix_modify.html {energy} option is supported by this fix to add the energy of the bias potential to the the system's potential energy as part of "thermodynamic output"_thermo_style.html. -This fix computes a global scalar and global vector of length 11, which +This fix computes a global scalar and global vector of length 12, which can be accessed by various "output commands"_Howto_output.html. The scalar is the magnitude of the bias potential (energy units) applied on the current timestep. The vector stores the following quantities: 1 = boost factor on this step (unitless) -2 = max strain Eij of any bond on this step (unitless) +2 = max strain Eij of any bond on this step (absolute value, unitless) 3 = ID of first atom in the max-strain bond 4 = ID of second atom in the max-strain bond 5 = average # of bonds/atom on this step :ul -6 = fraction of timesteps with bias = 0.0 during this run -7 = max drift distance of any atom during this run (distance units) -8 = max bond length during this run (distance units) :ul +6 = fraction of timesteps where the biased bond has bias = 0.0 during this run +7 = fraction of timesteps where the biased bond has negative strain during this run +8 = max drift distance of any atom during this run (distance units) +9 = max bond length during this run (distance units) :ul -9 = cumulative hyper time since fix was defined (time units) -10 = cumulative count of event timesteps since fix was defined -11 = cumulative count of atoms in events since fix was defined :ul +10 = cumulative hyper time since fix was defined (time units) +11 = cumulative count of event timesteps since fix was defined +12 = cumulative count of atoms in events since fix was defined :ul -The first 5 quantities are for the current timestep. Quantities 6-8 -are for the current hyper run. Quantities 9-11 are cumulative across -multiple runs (since the fix was defined in the input script). +The first 5 quantities are for the current timestep. Quantities 6-9 +are for the current hyper run. They are reset each time a new hyper +run is performed. Quantities 19-12 are cumulative across multiple +runs (since the point in the input script the fix was defined). -For value 7, drift is the distance an atom moves between timesteps -when the bond list is reset, i.e. between events. Atoms involved in -an event will typically move the greatest distance since others are -typically oscillating around their lattice site. +For value 8, drift is the distance an atom moves between two quenched +states when the second quench determines an event has occurred. Atoms +involved in an event will typically move the greatest distance since +others typically remain near their original quenched position. -For value 10, events are checked for by the "hyper"_hyper.html command +For value 11, events are checked for by the "hyper"_hyper.html command once every {Nevent} timesteps. This value is the count of those timesteps on which one (or more) events was detected. It is NOT the number of distinct events, since more than one event may occur in the same {Nevent} time window. -For value 11, each time the "hyper"_hyper.html command checks for an +For value 12, each time the "hyper"_hyper.html command checks for an event, it invokes a compute to flag zero or more atoms as participating in one or more events. E.g. atoms that have displaced more than some distance from the previous quench state. Value 11 is diff --git a/doc/src/fix_hyper_local.txt b/doc/src/fix_hyper_local.txt index c34b9ba7da..7f12e37999 100644 --- a/doc/src/fix_hyper_local.txt +++ b/doc/src/fix_hyper_local.txt @@ -22,10 +22,9 @@ Dcut = minimum distance between boosted bonds (distance units) :l alpha = boostostat relaxation time (time units) :l Btarget = desired time boost factor (unitless) :l zero or more keyword/value pairs may be appended :l -keyword = {lost} or {check/bias} or {check/coeff} - {lostbond} value = error/warn/ignore - {check/bias} values = Nevery error/warn/ignore - {check/coeff} values = Nevery error/warn/ignore :pre +keyword = {check/ghost} or {check/bias} :l + {check/ghost} values = none + {check/bias} values = Nevery error/warn/ignore :pre :ule [Examples:] @@ -65,8 +64,8 @@ To understand this description, you should first read the description of the GHD algorithm on the "fix hyper/global"_fix_hyper_global.html doc page. This description of LHD builds on the GHD description. -The definition of bonds, Eij, and Emax are the same for GHD and LHD. -The formulas for Vij(max) and Fij(max) are also the same except for a +The definition of bonds and Eij are the same for GHD and LHD. The +formulas for Vij(max) and Fij(max) are also the same except for a pre-factor Cij, explained below. The bias energy Vij applied to a bond IJ with maximum strain is @@ -117,11 +116,11 @@ where Vkl(max) is the bias energy of the maxstrain bond KL within bond IJ's neighborhood, beta = 1/kTequil, and {Tequil} is the temperature of the system and an argument to this fix. -NOTE: To run LHD, the input script must also use the "fix -langevin"_fix_langevin.html command to thermostat the atoms at the -same {Tequil} as specified by this fix, so that the system is running -constant-temperature (NVT) dynamics. LAMMPS does not check that this -is done. +NOTE: To run an LHD simulation, the input script must also use the +"fix langevin"_fix_langevin.html command to thermostat the atoms at +the same {Tequil} as specified by this fix, so that the system is +running constant-temperature (NVT) dynamics. LAMMPS does not check +that this is done. Note that if IJ = KL, then bond IJ is a biased bond on that timestep, otherwise it is not. But regardless, the boost factor Bij can be @@ -216,20 +215,20 @@ each pair. E.g. something like 2x the cutoff of the interatomic potential. In practice a {Dcut} value of ~10 Angstroms seems to work well for many solid-state systems. -NOTE: You must also insure that ghost atom communication is performed -for a distance of at least {Dcut} + {cutevent} where {cutevent} = the -distance one or more atoms move (between quenched states) to be -considered an "event". It is an argument to the "compute -event/displace" command used to detect events. By default the ghost -communication distance is set by the pair_style cutoff, which will -typically be < {Dcut}. The "comm_modify cutoff"_comm_modify.html -command can be used to set the ghost cutoff explicitly, e.g. +NOTE: You should insure that ghost atom communication is performed for +a distance of at least {Dcut} + {cutevent} = the distance one or more +atoms move (between quenched states) to be considered an "event". It +is an argument to the "compute event/displace" command used to detect +events. By default the ghost communication distance is set by the +pair_style cutoff, which will typically be < {Dcut}. The "comm_modify +cutoff"_comm_modify.html command should be used to override the ghost +cutoff explicitly, e.g. comm_modify cutoff 12.0 :pre -This fix does not know the {cutevent} parameter, but uses half the -bond length as an estimate to warn if the ghost cutoff is not long -enough. +Note that this fix does not know the {cutevent} parameter, but uses +half the {cutbond} parameter as an estimate to warn if the ghost +cutoff is not long enough. As described above the {alpha} argument is a pre-factor in the boostostat update equation for each bond's Cij prefactor. {Alpha} is @@ -269,7 +268,30 @@ NOTE: If you have no physical intuition as to the smallest barrier height in your system, a reasonable strategy to determine the largest {Btarget} you can use for an LHD model, is to run a sequence of simulations with smaller and smaller {Btarget} values, until the event -rate does not change. +rate does not change (as a function of hyper time). + +:line + +Here is additional information on the optional keywords for this fix. + +The {check/ghost} keyword turns on extra computation each timestep to +compute statistics about ghost atoms used to determine which bonds to +bias. The output of these stats are the vector values 14 and 15, +described below. If this keyword is not enabled, the output +of the stats will be zero. + +The {check/bias} keyword turns on extra computation and communcation +to check if any biased bonds are closer than {Dcut} to each other, +which should not be the case if LHD is operating correctly. Thus it +is a debugging check. The {Nevery} setting determines how often the +check is made. The {error}, {warn}, or {ignore} setting determines +what is done if the count of too-close bonds is not zero. Either the +code will exit, or issue a warning, or silently tally the count. The +count can be output as vector value 17, as described below. If this +keyword is not enabled, the output of that statistic will be 0. + +Note that both of these computations are costly, hence they are only +enabled by these keywords. :line @@ -282,95 +304,120 @@ The "fix_modify"_fix_modify.html {energy} option is supported by this fix to add the energy of the bias potential to the the system's potential energy as part of "thermodynamic output"_thermo_style.html. -This fix computes a global scalar and global vector of length 23, -which can be accessed by various "output -commands"_Howto_output.html. The scalar is the magnitude of -the bias potential (energy units) applied on the current timestep, -summed over all biased bonds. The vector stores the following -quantities: +This fix computes a global scalar and global vector of length 21, +which can be accessed by various "output commands"_Howto_output.html. +The scalar is the magnitude of the bias potential (energy units) +applied on the current timestep, summed over all biased bonds. The +vector stores the following quantities: 1 = # of biased bonds on this step -2 = max strain Eij of any bond on this step (unitless) -3 = average bias potential for all biased bonds on this step (energy units) +2 = max strain Eij of any bond on this step (absolute value, unitless) +3 = average bias coeff for all bonds on this step (unitless) 4 = average # of bonds/atom on this step 5 = average neighbor bonds/bond on this step within {Dcut} :ul -6 = fraction of steps and bonds with no bias during this run -7 = max drift distance of any atom during this run (distance units) -8 = max bond length during this run (distance units) -9 = average # of biased bonds/step during this run -10 = average bias potential for all biased bonds during this run (energy units) -11 = max bias potential for any biased bond during this run (energy units) -12 = min bias potential for any biased bond during this run (energy units) -13 = max distance from my sub-box of any ghost atom with maxstrain < qfactor during this run (distance units) -14 = max distance outside my box of any ghost atom with any maxstrain during this run (distance units) -15 = count of ghost neighbor atoms not found on reneighbor steps during this run -16 = count of lost bond partners during this run -17 = average bias coeff for lost bond partners during this run -18 = count of bias overlaps found during this run -19 = count of non-matching bias coefficients found during this run :ul - -20 = cumulative hyper time since fix created (time units) -21 = cumulative count of event timesteps since fix created -22 = cumulative count of atoms in events since fix created -23 = cumulative # of new bonds since fix created :ul +6 = max bond length during this run (distance units) +7 = average # of biased bonds/step during this run +8 = fraction of biased bonds with no bias during this run +9 = fraction of biased bonds with negative strain during this run +10 = average bias coeff for all bonds during this run (unitless) +11 = min bias coeff for any bond during this run (unitless) +12 = max bias coeff for any bond during this run (unitless) + +13 = max drift distance of any bond atom during this run (distance units) +14 = max distance from proc subbox of any ghost atom with maxstrain < qfactor during this run (distance units) +15 = max distance outside my box of any ghost atom with any maxstrain during this run (distance units) +16 = count of ghost atoms that could not be found on reneighbor steps during this run +17 = count of bias overlaps (< Dcut) found during this run + +18 = cumulative hyper time since fix created (time units) +19 = cumulative count of event timesteps since fix created +20 = cumulative count of atoms in events since fix created +21 = cumulative # of new bonds formed since fix created :ul The first quantities (1-5) are for the current timestep. Quantities -6-19 are for the current hyper run. They are reset each time a new -hyper run is performed. Quantities 20-23 are cumulative across -multiple runs (since the fix was defined in the input script). +6-17 are for the current hyper run. They are reset each time a new +hyper run is performed. Quantities 18-21 are cumulative across +multiple runs (since the point in the input script the fix was +defined). -For value 6, the numerator is a count of all biased bonds on every +For value 8, the numerator is a count of all biased bonds on each timestep whose bias energy = 0.0 due to Eij >= {qfactor}. The denominator is the count of all biased bonds on all timesteps. -For value 7, drift is the distance an atom moves between timesteps -when the bond list is reset, i.e. between events. Atoms involved in -an event will typically move the greatest distance since others are -typically oscillating around their lattice site. - -For values 13 and 14, the maxstrain of a ghost atom is the maxstrain -of any bond it is part of, and it is checked for ghost atoms within -the bond neighbor cutoff. - -Values 15-19 are mostly useful for debugging and diagnostic purposes. - -For values 15-17, it is possible that a ghost atom owned by another -processor will move far enough (e.g. as part of an event-in-progress) -that it will no longer be within the communication cutoff distance for -acquiring ghost atoms. Likewise it may be a ghost atom bond partner -that cannot be found because it has moved too far. These values count -those occurrences. Because they typically involve atoms that are part -of events, they do not usually indicate bad dynamics. Value 16 is the -average bias coefficient for bonds where a partner atom was lost. - -For value 18, no two bonds should be biased if they are within a +For value 9, the numerator is a count of all biased bonds on each +timestep with negative strain. The denominator is the count of all +biased bonds on all timesteps. + +Values 13-17 are mostly useful for debugging and diagnostic purposes. + +For value 13, drift is the distance an atom moves between two quenched +states when the second quench determines an event has occurred. Atoms +involved in an event will typically move the greatest distance since +others typically remain near their original quenched position. + +For values 14-16, neighbor atoms in the full neighbor list with cutoff +{Dcut} may be ghost atoms outside a processor's sub-box. Before the +next event occurs they may move further than {Dcut} away from the +sub-box boundary. Value 14 is the furthest (from the sub-box) any +ghost atom in the neighbor list with maxstrain < {qfactor} was +accessed during the run. Value 15 is the same except that the ghost +atom's maxstrain may be >= {qfactor}, which may mean it is about to +participate in an event. Value 16 is a count of how many ghost atoms +could not be found on reneighbor steps, presumably because they moved +too far away due to their participation in an event (which will likely +be detected at the next quench). + +Typical values for 14 and 15 should be slightly larger than {Dcut}, +which accounts for ghost atoms initially at a {Dcut} distance moving +thermally before the next event takes place. + +Note that for values 14 and 15 to be computed, the optional keyword +{check/ghost} must be specified. Otherwise these values will be zero. +This is because computing them incurs overhead, so the values are only +computed if requested. + +Value 16 should be zero or small. As explained above a small count +likely means some ghost atoms were participating in their own events +and moved a longer distance. If the value is large, it likely means +the communication cutoff for ghosts is too close to {Dcut} leading to +many not-found ghost atoms before the next event. This may lead to a +reduced number of bonds being selected for biasing, since the code +assumes those atoms are part of highly strained bonds. As explained +above, the "comm_modify cutoff"_comm_modify.html command can be used +to set a longer cutoff. + +For value 17, no two bonds should be biased if they are within a {Dcut} distance of each other. This value should be zero, indicating -that no pair of bonds "overlap", meaning they are closer than {Dcut} -from each other. +that no pair of biased bonds are closer than {Dcut} from each other. + +Note that for values 17 to be computed, the optional keyword +{check/bias} must be specified and it determines how often this check +is performed. This is because performing the check incurs overhead, +so if only computed as often as requested. -For value 19, the same bias coefficient is stored by both atoms in an -IJ bond. This value should be zero, indicating that for all bonds, -each atom in the bond stores the a bias coefficient with the same -value. +The result at the end of the run is the cumulative total from every +timestep the check was made. Note that the value is a count of atoms +in bonds which found other atoms in bonds too close, so it is almost +always an over-count of the number of too-close bonds. -Value 20 is simply the specified {boost} factor times the number of -timestep times the timestep size. +Value 18 is simply the specified {boost} factor times the number of +timesteps times the timestep size. -For value 21, events are checked for by the "hyper"_hyper.html command +For value 19, events are checked for by the "hyper"_hyper.html command once every {Nevent} timesteps. This value is the count of those timesteps on which one (or more) events was detected. It is NOT the number of distinct events, since more than one event may occur in the same {Nevent} time window. -For value 22, each time the "hyper"_hyper.html command checks for an +For value 20, each time the "hyper"_hyper.html command checks for an event, it invokes a compute to flag zero or more atoms as participating in one or more events. E.g. atoms that have displaced -more than some distance from the previous quench state. Value 22 is +more than some distance from the previous quench state. Value 20 is the cumulative count of the number of atoms participating in any of the events that were found. -Value 23 tallies the number of new bonds created by the bond reset +Value 21 tallies the number of new bonds created by the bond reset operation. Bonds between a specific I,J pair of atoms may persist for the entire hyperdynamics simulation if neither I or J are involved in an event. @@ -378,6 +425,16 @@ an event. The scalar and vector values calculated by this fix are all "intensive". +This fix also computes a local vector of length the number of bonds +currently in the system. The value for each bond is its Cij prefactor +(bias coefficient). These values can be can be accessed by various +"output commands"_Howto_output.html. A particularly useful one is the +"fix ave/histo"_fix_ave_histo.html command which can be used to +histogram the Cij values to see if they are distributed reasonably +close to 1.0, which indicates a good choice of {Vmax}. + +The local values calculated by this fix are unitless. + 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. @@ -392,7 +449,9 @@ doc page for more info. "hyper"_hyper.html, "fix hyper/global"_fix_hyper_global.html -[Default:] None +[Default:] + +The check/ghost and check/bias keywords are not enabled by default. :line diff --git a/examples/hyper/in.hyper.global b/examples/hyper/in.hyper.global index 22b3b4251b..eba5c7bf89 100644 --- a/examples/hyper/in.hyper.global +++ b/examples/hyper/in.hyper.global @@ -12,6 +12,8 @@ variable cutevent index 1.1 variable steps index 100000 variable nevent index 1000 variable zoom index 1.8 +variable seed index 826626413 +variable tol index 1.0e-15 units metal atom_style atomic @@ -45,7 +47,7 @@ neighbor 0.5 bin neigh_modify every 1 delay 5 check yes fix 1 mobile nve -fix 2 mobile langevin ${Tequil} ${Tequil} 1.0 858872873 zero yes +fix 2 mobile langevin ${Tequil} ${Tequil} 1.0 ${seed} zero yes timestep 0.005 @@ -92,4 +94,4 @@ dump_modify 1 pad 6 amap 1 3 sa 1 3 blue red green # run -hyper ${steps} ${nevent} HG event min 1.0e-6 1.0e-6 100 100 dump 1 +hyper ${steps} ${nevent} HG event min ${tol} ${tol} 1000 1000 dump 1 diff --git a/examples/hyper/in.hyper.local b/examples/hyper/in.hyper.local index ef8ed4d042..cdf478ac38 100644 --- a/examples/hyper/in.hyper.local +++ b/examples/hyper/in.hyper.local @@ -107,6 +107,12 @@ dump 1 all image 10000000 local.*.jpg v_acolor type size 1024 1024 & zoom ${zoom} adiam 2.5 view 0.0 0.0 up 0 1 0 axes yes 0.9 0.01 dump_modify 1 pad 6 amap 1 3 sa 1 3 blue red green +# test of histogramming and dump output of bias coeffs + +#fix histo all ave/histo 10 100 1000 0.9 1.1 100 f_HL & +# mode vector kind local file tmp.histo +#dump 2 all local 1000 tmp.local f_HL + # run hyper ${steps} ${nevent} HL event min ${tol} ${tol} 1000 1000 dump 1 diff --git a/src/REPLICA/fix_hyper_global.cpp b/src/REPLICA/fix_hyper_global.cpp index e43f1431a9..6924fe2d93 100644 --- a/src/REPLICA/fix_hyper_global.cpp +++ b/src/REPLICA/fix_hyper_global.cpp @@ -37,7 +37,7 @@ using namespace FixConst; // possible enhancements // should there be a virial contribution from boosted bond? -// allow newton off? see Note in pre_reverse() +// allow newton off? /* ---------------------------------------------------------------------- */ @@ -52,7 +52,7 @@ FixHyperGlobal::FixHyperGlobal(LAMMPS *lmp, int narg, char **arg) : hyperflag = 1; scalar_flag = 1; vector_flag = 1; - size_vector = 11; + size_vector = 12; global_freq = 1; extscalar = 0; extvector = 0; @@ -76,6 +76,7 @@ FixHyperGlobal::FixHyperGlobal(LAMMPS *lmp, int narg, char **arg) : maxold = 0; xold = NULL; tagold = NULL; + old2now = NULL; me = comm->me; firstflag = 1; @@ -94,6 +95,7 @@ FixHyperGlobal::~FixHyperGlobal() memory->sfree(blist); memory->destroy(xold); memory->destroy(tagold); + memory->destroy(old2now); } /* ---------------------------------------------------------------------- */ @@ -114,6 +116,7 @@ void FixHyperGlobal::init_hyper() maxdriftsq = 0.0; maxbondlen = 0.0; nobias = 0; + negstrain = 0; } /* ---------------------------------------------------------------------- */ @@ -155,14 +158,16 @@ void FixHyperGlobal::setup_pre_neighbor() void FixHyperGlobal::setup_pre_reverse(int eflag, int vflag) { - // no increment in nobias or hyper time when pre-run forces are calculated + // no increment in these quantities when pre-run forces are calculated int nobias_hold = nobias; + int negstrain_hold = negstrain; double t_hyper_hold = t_hyper; pre_reverse(eflag,vflag); nobias = nobias_hold; + negstrain = negstrain_hold; t_hyper = t_hyper_hold; } @@ -171,7 +176,7 @@ void FixHyperGlobal::setup_pre_reverse(int eflag, int vflag) void FixHyperGlobal::pre_neighbor() { int i,m,iold,jold,ilocal,jlocal; - double distsq; + // double distsq; // reset local indices for owned bond atoms, since atoms have migrated // must be done after ghost atoms are setup via comm->borders() @@ -182,6 +187,7 @@ void FixHyperGlobal::pre_neighbor() // closest_image() returns the ghost atom index in that case // also compute max drift of any atom in a bond // drift = displacement from quenched coord while event has not yet occured + // NOTE: drift calc is now done in bond_build(), between 2 quenched states for (i = 0; i < nall_old; i++) old2now[i] = -1; @@ -199,8 +205,8 @@ void FixHyperGlobal::pre_neighbor() if (ilocal < 0) error->one(FLERR,"Fix hyper/global bond atom not found"); old2now[iold] = ilocal; - distsq = MathExtra::distsq3(x[ilocal],xold[iold]); - maxdriftsq = MAX(distsq,maxdriftsq); + //distsq = MathExtra::distsq3(x[ilocal],xold[iold]); + //maxdriftsq = MAX(distsq,maxdriftsq); } if (jlocal < 0) { jlocal = atom->map(tagold[jold]); @@ -208,40 +214,13 @@ void FixHyperGlobal::pre_neighbor() if (jlocal < 0) error->one(FLERR,"Fix hyper/global bond atom not found"); old2now[jold] = jlocal; - distsq = MathExtra::distsq3(x[jlocal],xold[jold]); - maxdriftsq = MAX(distsq,maxdriftsq); + //distsq = MathExtra::distsq3(x[jlocal],xold[jold]); + //maxdriftsq = MAX(distsq,maxdriftsq); } blist[m].i = ilocal; blist[m].j = jlocal; } - - /* old way - nblocal loop is re-doing index-find calculation - - // NOTE: drift may not include J atoms moving (if not themselves bond owners) - - int flag = 0; - - for (m = 0; m < nblocal; m++) { - iold = blist[m].iold; - jold = blist[m].jold; - ilocal = atom->map(tagold[iold]); - jlocal = atom->map(tagold[jold]); - ilocal = domain->closest_image(xold[iold],ilocal); - jlocal = domain->closest_image(xold[iold],jlocal); - blist[m].i = ilocal; - blist[m].j = jlocal; - - if (ilocal < 0 || jlocal < 0) flag++; - else { - distsq = MathExtra::distsq3(x[ilocal],xold[iold]); - maxdriftsq = MAX(distsq,maxdriftsq); - } - } - - if (flag) error->one(FLERR,"Fix hyper/global bond atom not found"); - - */ } /* ---------------------------------------------------------------------- */ @@ -254,12 +233,12 @@ void FixHyperGlobal::pre_reverse(int /* eflag */, int /* vflag */) double ebias,vbias,fbias,fbiasr; // compute current strain of each owned bond - // eabs_max = maximum absolute value of strain of any bond I own + // emax = maximum abs value of strain of any bond I own // imax,jmax = local indices of my 2 atoms in that bond // rmax,r0max = current and relaxed lengths of that bond double **x = atom->x; - double estrain_maxabs = 0.0; + double emax = 0.0; for (m = 0; m < nblocal; m++) { i = blist[m].i; @@ -272,8 +251,8 @@ void FixHyperGlobal::pre_reverse(int /* eflag */, int /* vflag */) r0 = blist[m].r0; estrain = fabs(r-r0) / r0; - if (estrain > estrain_maxabs) { - estrain_maxabs = estrain; + if (estrain > emax) { + emax = estrain; rmax = r; r0max = r0; imax = i; @@ -285,7 +264,7 @@ void FixHyperGlobal::pre_reverse(int /* eflag */, int /* vflag */) // finds max strain and what proc owns it // owner = proc that owns that bond - pairme.value = estrain_maxabs; + pairme.value = emax; pairme.proc = me; MPI_Allreduce(&pairme,&pairall,1,MPI_DOUBLE_INT,MPI_MAXLOC,world); owner = pairall.proc; @@ -311,16 +290,14 @@ void FixHyperGlobal::pre_reverse(int /* eflag */, int /* vflag */) // Fix = x component of force on atom I // = Fbias dEbias/dr dr/dxi, dEbias/dr = 1/r0, dr/dxi = delx/r // dt_boost = time boost factor = exp(Vbias/kT) - // NOTE: logic here would need to be different for newton off double **f = atom->f; vbias = fbias = 0.0; dt_boost = 1.0; - if (estrain_maxabs < qfactor) { - //ebias = (rmax-r0max) / r0max; - ebias = fabs(rmax-r0max) / r0max; + if (emax < qfactor) { + ebias = (rmax-r0max) / r0max; vbias = vmax * (1.0 - ebias*ebias*invqfactorsq); fbias = 2.0 * vmax * ebias * invqfactorsq; dt_boost = exp(beta*vbias); @@ -338,13 +315,15 @@ void FixHyperGlobal::pre_reverse(int /* eflag */, int /* vflag */) f[jmax][1] -= dely*fbiasr; f[jmax][2] -= delz*fbiasr; + if (ebias < 0.0) negstrain++; + } else nobias++; // output quantities outvec[0] = vbias; outvec[1] = dt_boost; - outvec[2] = ebias; + outvec[2] = emax; outvec[3] = atom->tag[imax]; outvec[4] = atom->tag[jmax]; @@ -356,8 +335,8 @@ void FixHyperGlobal::pre_reverse(int /* eflag */, int /* vflag */) void FixHyperGlobal::build_bond_list(int natom) { - int i,j,ii,jj,inum,jnum; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int i,j,m,ii,jj,iold,jold,ilocal,jlocal,inum,jnum; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq,distsq; int *ilist,*jlist,*numneigh,**firstneigh; if (natom) { @@ -365,6 +344,27 @@ void FixHyperGlobal::build_bond_list(int natom) nevent_atom += natom; } + // compute max distance any bond atom has moved between 2 quenched states + // xold[iold] = last quenched coord for iold + // x[ilocal] = current quenched coord for same atom + + double **x = atom->x; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + for (m = 0; m < nblocal; m++) { + iold = blist[m].iold; + ilocal = atom->map(tagold[iold]); + ilocal = domain->closest_image(xold[iold],ilocal); + distsq = MathExtra::distsq3(x[ilocal],xold[iold]); + maxdriftsq = MAX(distsq,maxdriftsq); + jold = blist[m].jold; + jlocal = atom->map(tagold[jold]); + jlocal = domain->closest_image(xold[iold],jlocal); + distsq = MathExtra::distsq3(x[jlocal],xold[jold]); + maxdriftsq = MAX(distsq,maxdriftsq); + } + // trigger neighbor list build neighbor->build_one(list); @@ -372,7 +372,6 @@ void FixHyperGlobal::build_bond_list(int natom) // identify bonds assigned to each owned atom // do not create a bond between two non-group atoms - double **x = atom->x; int *mask = atom->mask; inum = list->inum; @@ -415,10 +414,12 @@ void FixHyperGlobal::build_bond_list(int natom) } } - // store IDs and coords for owned+ghost atoms at time of bond creation - // realloc xold and tagold as needed + // store per-atom quantities for owned+ghost atoms at time of bond creation + // nall_old = value of nall at time bonds are built - if (atom->nmax > maxold) { + tagint *tag = atom->tag; + + if (nall > maxold) { memory->destroy(xold); memory->destroy(tagold); memory->destroy(old2now); @@ -428,16 +429,11 @@ void FixHyperGlobal::build_bond_list(int natom) memory->create(old2now,maxold,"hyper/global:old2now"); } - tagint *tag = atom->tag; - int nall = atom->nlocal + atom->nghost; - nall_old = nall; + memcpy(&xold[0][0],&x[0][0],3*nall*sizeof(double)); + for (i = 0; i < nall; i++) tagold[i] = tag[i]; - for (i = 0; i < nall; i++) { - xold[i][0] = x[i][0]; - xold[i][1] = x[i][1]; - xold[i][2] = x[i][2]; - tagold[i] = tag[i]; - } + nlocal_old = nlocal; + nall_old = nall; } /* ---------------------------------------------------------------------- @@ -473,7 +469,7 @@ double FixHyperGlobal::compute_vector(int i) bcastflag = 0; } - // 11 vector outputs returned for i = 0-10 + // 12 vector outputs returned for i = 0-11 // i = 0 = boost factor on this step // i = 1 = max strain of any bond on this step (positive or negative) @@ -481,13 +477,14 @@ double FixHyperGlobal::compute_vector(int i) // i = 3 = ID of atom J in max-strain bond on this step // i = 4 = ave bonds/atom on this step - // i = 5 = fraction of steps with no bias during this run - // i = 6 = max drift of any atom during this run - // i = 7 = max bond length during this run + // i = 5 = fraction of steps where bond has no bias during this run + // i = 6 = fraction of steps where bond has negative strain during this run + // i = 7 = max drift distance of any atom during this run + // i = 8 = max bond length during this run - // i = 8 = cummulative hyper time since fix created - // i = 9 = cummulative # of event timesteps since fix created - // i = 10 = cummulative # of atoms in events since fix created + // i = 9 = cummulative hyper time since fix created + // i = 10 = cummulative # of event timesteps since fix created + // i = 11 = cummulative # of atoms in events since fix created if (i == 0) return outvec[1]; if (i == 1) return outvec[2]; @@ -509,20 +506,27 @@ double FixHyperGlobal::compute_vector(int i) } if (i == 6) { + if (update->ntimestep == update->firststep) return 0.0; + int allnegstrain; + MPI_Allreduce(&negstrain,&allnegstrain,1,MPI_INT,MPI_SUM,world); + return 1.0*allnegstrain / (update->ntimestep - update->firststep); + } + + if (i == 7) { double alldriftsq; MPI_Allreduce(&maxdriftsq,&alldriftsq,1,MPI_DOUBLE,MPI_MAX,world); return sqrt(alldriftsq); } - if (i == 7) { + if (i == 8) { double allbondlen; MPI_Allreduce(&maxbondlen,&allbondlen,1,MPI_DOUBLE,MPI_MAX,world); return allbondlen; } - if (i == 8) return t_hyper; - if (i == 9) return (double) nevent; - if (i == 10) return (double) nevent_atom; + if (i == 9) return t_hyper; + if (i == 10) return (double) nevent; + if (i == 11) return (double) nevent_atom; return 0.0; } @@ -534,13 +538,14 @@ double FixHyperGlobal::compute_vector(int i) double FixHyperGlobal::query(int i) { - if (i == 1) return compute_vector(8); // cummulative hyper time - if (i == 2) return compute_vector(9); // nevent - if (i == 3) return compute_vector(10); // nevent_atom + if (i == 1) return compute_vector(9); // cummulative hyper time + if (i == 2) return compute_vector(10); // nevent + if (i == 3) return compute_vector(11); // nevent_atom if (i == 4) return compute_vector(4); // ave bonds/atom - if (i == 5) return compute_vector(6); // maxdrift - if (i == 6) return compute_vector(7); // maxbondlen + if (i == 5) return compute_vector(7); // maxdrift + if (i == 6) return compute_vector(8); // maxbondlen if (i == 7) return compute_vector(5); // fraction with zero bias + if (i == 8) return compute_vector(6); // fraction with negative strain error->all(FLERR,"Invalid query to fix hyper/global"); diff --git a/src/REPLICA/fix_hyper_global.h b/src/REPLICA/fix_hyper_global.h index 42dd64e145..a62f80b54a 100644 --- a/src/REPLICA/fix_hyper_global.h +++ b/src/REPLICA/fix_hyper_global.h @@ -56,6 +56,7 @@ class FixHyperGlobal : public FixHyper { double maxbondlen; // max length of any bond double maxdriftsq; // max distance any atom drifts from original pos int nobias; // # of steps when bias = 0, b/c bond too long + int negstrain; // # of steps when biased bond has negative strain class NeighList *list; @@ -70,12 +71,13 @@ class FixHyperGlobal : public FixHyper { double r0; // relaxed bond length }; - struct OneBond *blist; // list of owned bonds - int nblocal; // # of owned bonds + OneBond *blist; // list of owned bonds + int nblocal; // # of owned bonds // coords and IDs of owned+ghost atoms when bonds were formed // persists on a proc from one event until the next + int nlocal_old; // nlocal for old atoms int nall_old; // nlocal+nghost for old atoms int maxold; // allocated size of old atoms diff --git a/src/REPLICA/fix_hyper_local.cpp b/src/REPLICA/fix_hyper_local.cpp index 99dd1945ad..a2af3dff6e 100644 --- a/src/REPLICA/fix_hyper_local.cpp +++ b/src/REPLICA/fix_hyper_local.cpp @@ -36,8 +36,7 @@ using namespace FixConst; #define DELTABOND 16384 #define DELTABIAS 16 #define COEFFINIT 1.0 -#define COEFFMAX 1.2 -#define MAXBONDPERATOM 30 +#define FCCBONDS 12 #define BIG 1.0e20 enum{STRAIN,STRAINDOMAIN,BIASFLAG,BIASCOEFF}; @@ -46,12 +45,11 @@ enum{IGNORE,WARN,ERROR}; /* ---------------------------------------------------------------------- */ FixHyperLocal::FixHyperLocal(LAMMPS *lmp, int narg, char **arg) : - FixHyper(lmp, narg, arg), old2now(NULL), xold(NULL), tagold(NULL), - blist(NULL), maxstrain(NULL), maxstrain_domain(NULL), - biasflag(NULL), bias(NULL) + FixHyper(lmp, narg, arg), blist(NULL), biascoeff(NULL), numbond(NULL), + maxhalf(NULL), eligible(NULL), maxhalfstrain(NULL), old2now(NULL), + tagold(NULL), xold(NULL), maxstrain(NULL), maxstrain_domain(NULL), + biasflag(NULL), bias(NULL), cpage(NULL), clist(NULL), numcoeff(NULL) { - // NOTE: need to add vecs/arrays to constructor list - // error checks if (atom->map_style == 0) @@ -64,7 +62,11 @@ FixHyperLocal::FixHyperLocal(LAMMPS *lmp, int narg, char **arg) : hyperflag = 2; scalar_flag = 1; vector_flag = 1; - size_vector = 23; + size_vector = 21; + local_flag = 1; + size_local_rows = 0; + size_local_cols = 0; + local_freq = 1; global_freq = 1; extscalar = 0; @@ -89,11 +91,15 @@ FixHyperLocal::FixHyperLocal(LAMMPS *lmp, int narg, char **arg) : // optional args + checkghost = 0; checkbias = 0; int iarg = 10; while (iarg < narg) { - if (strcmp(arg[iarg],"check/bias") == 0) { + if (strcmp(arg[iarg],"check/ghost") == 0) { + checkghost = 1; + iarg++; + } else if (strcmp(arg[iarg],"check/bias") == 0) { if (iarg+3 > narg) error->all(FLERR,"Illegal fix hyper/local command"); checkbias = 1; checkbias_every = force->inumeric(FLERR,arg[iarg+1]); @@ -102,14 +108,15 @@ FixHyperLocal::FixHyperLocal(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg+2],"ignore") == 0) checkbias_flag = IGNORE; else error->all(FLERR,"Illegal fix hyper/local command"); iarg += 3; - } else error->all(FLERR,"Illegal fix hyper/local command"); } // per-atom data structs - maxbond = 0; + maxbond = nblocal = 0; blist = NULL; + biascoeff = NULL; + allbonds = 0; maxatom = 0; maxstrain = NULL; @@ -130,24 +137,30 @@ FixHyperLocal::FixHyperLocal(LAMMPS *lmp, int narg, char **arg) : nbias = maxbias = 0; bias = NULL; + // data structs for persisting bias coeffs when bond list is reformed + // maxbondperatom = max # of bonds any atom is part of + // FCCBONDS = 12 is a good estimate for fcc lattices + // will be reset in build_bond() if necessary + maxcoeff = 0; - maxcoeffperatom = 0; + maxbondperatom = FCCBONDS; numcoeff = NULL; clist = NULL; + cpage = new MyPage; + cpage->init(maxbondperatom,1024*maxbondperatom,1); - // maxbondperatom = max # of bonds any atom is part of - // will be reset in bond_build() // set comm sizes needed by this fix - // NOTE: remove MBPA when minimize reverse Cij comm + // reverse = 2 is for sending atom index + value, though total likely < 1 + // reverse comm for bias coeffs has variable size, so not tallied here - maxbondperatom = 1; comm_forward = 1; - comm_reverse = MAXBONDPERATOM; + comm_reverse = 2; me = comm->me; firstflag = 1; - allbias = 0.0; + sumbiascoeff = 0.0; + avebiascoeff = 0.0; starttime = update->ntimestep; nostrainyet = 1; @@ -162,6 +175,7 @@ FixHyperLocal::FixHyperLocal(LAMMPS *lmp, int narg, char **arg) : FixHyperLocal::~FixHyperLocal() { memory->destroy(blist); + memory->destroy(biascoeff); memory->destroy(maxstrain); memory->destroy(maxstrain_domain); @@ -179,7 +193,8 @@ FixHyperLocal::~FixHyperLocal() memory->destroy(bias); memory->destroy(numcoeff); - memory->destroy(clist); + memory->sfree(clist); + delete cpage; } /* ---------------------------------------------------------------------- */ @@ -202,11 +217,12 @@ void FixHyperLocal::init_hyper() checkbias_count = 0; maxdriftsq = 0.0; maxbondlen = 0.0; - maxbiascoeff = 0.0; + avebiascoeff = 0.0; minbiascoeff = BIG; - sumbiascoeff = 0.0; + maxbiascoeff = 0.0; nbias_running = 0; nobias_running = 0; + negstrain_running = 0; rmaxever = 0.0; rmaxeverbig = 0.0; @@ -254,11 +270,12 @@ void FixHyperLocal::init() // need occasional full neighbor list with cutoff = Dcut // used for finding maxstrain of neighbor bonds out to Dcut // do not need to include neigh skin in cutoff, - // b/c this list will be built every time bond_build() is called + // b/c this list will be built every time build_bond() is called // NOTE: what if pair style list cutoff > Dcut // or what if neigh skin is huge? int irequest_full = neighbor->request(this,instance_me); + neighbor->requests[irequest_full]->id = 1; neighbor->requests[irequest_full]->pair = 0; neighbor->requests[irequest_full]->fix = 1; neighbor->requests[irequest_full]->half = 0; @@ -271,9 +288,10 @@ void FixHyperLocal::init() // used for building local bond list // no specified cutoff, should be longer than cutbond // this list will also be built (or derived/copied) - // every time bond_build() is called + // every time build_bond() is called int irequest_half = neighbor->request(this,instance_me); + neighbor->requests[irequest_half]->id = 2; neighbor->requests[irequest_half]->pair = 0; neighbor->requests[irequest_half]->fix = 1; neighbor->requests[irequest_half]->occasional = 1; @@ -297,7 +315,6 @@ void FixHyperLocal::init_list(int id, NeighList *ptr) void FixHyperLocal::setup_pre_neighbor() { // called for dynamics and minimization - // NOTE: check if needed for min, I think so b/c of Cij persist? pre_neighbor(); } @@ -308,7 +325,8 @@ void FixHyperLocal::setup_pre_reverse(int eflag, int vflag) { // only called for dynamics, not minimization // setupflag prevents boostostat update of bias coeffs in setup - // also prevents increments of nbias_running, nobias_running, sumbiascoeff + // also prevents increments of nbias_running, nobias_running, + // negstrain_running, sumbiascoeff setupflag = 1; pre_reverse(eflag,vflag); @@ -320,7 +338,7 @@ void FixHyperLocal::setup_pre_reverse(int eflag, int vflag) void FixHyperLocal::pre_neighbor() { int i,m,iold,jold,ilocal,jlocal; - double distsq; + // double distsq; // reset local indices for owned bond atoms, since atoms have migrated // must be done after ghost atoms are setup via comm->borders() @@ -331,6 +349,7 @@ void FixHyperLocal::pre_neighbor() // closest_image() returns the ghost atom index in that case // also compute max drift of any atom in a bond // drift = displacement from quenched coord while event has not yet occured + // NOTE: drift calc is now done in bond_build(), between 2 quenched states for (i = 0; i < nall_old; i++) old2now[i] = -1; @@ -348,17 +367,17 @@ void FixHyperLocal::pre_neighbor() if (ilocal < 0) error->one(FLERR,"Fix hyper/local bond atom not found"); old2now[iold] = ilocal; - distsq = MathExtra::distsq3(x[ilocal],xold[iold]); - maxdriftsq = MAX(distsq,maxdriftsq); + //distsq = MathExtra::distsq3(x[ilocal],xold[iold]); + //maxdriftsq = MAX(distsq,maxdriftsq); } if (jlocal < 0) { jlocal = atom->map(tagold[jold]); - jlocal = domain->closest_image(xold[iold],jlocal); // closest to iold + jlocal = domain->closest_image(xold[iold],jlocal); // close to I atom if (jlocal < 0) error->one(FLERR,"Fix hyper/local bond atom not found"); old2now[jold] = jlocal; - distsq = MathExtra::distsq3(x[jlocal],xold[jold]); - maxdriftsq = MAX(distsq,maxdriftsq); + //distsq = MathExtra::distsq3(x[jlocal],xold[jold]); + //maxdriftsq = MAX(distsq,maxdriftsq); } blist[m].i = ilocal; @@ -374,11 +393,11 @@ void FixHyperLocal::pre_neighbor() // b/c old2now is only used to access maxstrain() or biasflag() // which will be identical for every copy of the same atom ID - for (i = 0; i < nall_old; i++) { - if (old2now[i] >= 0) continue; - if (tagold[i] == 0) continue; - ilocal = atom->map(tagold[i]); - old2now[i] = ilocal; + for (iold = 0; iold < nall_old; iold++) { + if (old2now[iold] >= 0) continue; + if (tagold[iold] == 0) continue; + ilocal = atom->map(tagold[iold]); + old2now[iold] = ilocal; if (ilocal < 0) ghost_toofar++; } } @@ -389,26 +408,31 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) { int i,j,m,ii,jj,inum,jnum,iold,jold,ibond,nbond,ijhalf,ncount; double xtmp,ytmp,ztmp,delx,dely,delz; - double r,r0,estrain,emax,ebias,vbias,fbias,fbiasr,biascoeff; + double r,r0,estrain,emax,ebias,vbias,fbias,fbiasr; double halfstrain,selfstrain; int *ilist,*jlist,*numneigh,**firstneigh; //double time1,time2,time3,time4,time5,time6,time7,time8; //time1 = MPI_Wtime(); - // reallocate local vectors if necessary + nostrainyet = 0; + + // reallocate per-atom maxstrain and biasflag vectors if necessary int nlocal = atom->nlocal; int nall = nlocal + atom->nghost; if (maxatom < nall) { + memory->destroy(maxstrain); + memory->destroy(maxstrain_domain); + if (checkbias) memory->destroy(biasflag); maxatom = atom->nmax; - memory->grow(maxstrain,maxatom,"hyper/local:maxstrain"); - memory->grow(maxstrain_domain,maxatom,"hyper/local:maxstrain_domain"); - if (checkbias) memory->grow(biasflag,maxatom,"hyper/local:biasflag"); + memory->create(maxstrain,maxatom,"hyper/local:maxstrain"); + memory->create(maxstrain_domain,maxatom,"hyper/local:maxstrain_domain"); + if (checkbias) memory->create(biasflag,maxatom,"hyper/local:biasflag"); } - // each old atom I's owned bond with max strain is eligible for biasing + // one max strain bond per old owned atom is eligible for biasing for (iold = 0; iold < nlocal_old; iold++) eligible[iold] = 1; @@ -423,7 +447,7 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) // mark atom I ineligible if it has no bonds // also store: // maxhalf = which owned bond is maxstrain for each old atom I - // maxhalfstrain = strain of that bond for each old atom I + // maxhalfstrain = abs value strain of that bond for each old atom I for (i = 0; i < nall; i++) maxstrain[i] = 0.0; @@ -479,7 +503,6 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) // ------------------------------------------------------------- // use full Dcut neighbor list to check maxstrain of all neighbor atoms - // NOTE: is II loop the same as iold over nlocal_old ?? // neighlist is from last event // has old indices for I,J (reneighboring may have occurred) // use old2now[] to convert to current indices @@ -503,8 +526,12 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) double *sublo = domain->sublo; double *subhi = domain->subhi; + // first two lines of outer loop should be identical to this: + // for (iold = 0; iold < nlocal_old; iold++) + for (ii = 0; ii < inum; ii++) { iold = ilist[ii]; + if (eligible[iold] == 0) continue; jlist = firstneigh[iold]; jnum = numneigh[iold]; @@ -533,29 +560,30 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) emax = MAX(emax,maxstrain[j]); if (selfstrain == maxstrain[j]) ncount++; - // diagnostic + // optional diagnostic // tally largest distance from subbox that a ghost atom is (rmaxbig) // and the largest distance if strain < qfactor (rmax) - // NOTE: could this be removed from loop ?? - - if (j >= nlocal) { - if (x[j][0] < sublo[0]) rmaxbig = MAX(rmaxbig,sublo[0]-x[j][0]); - if (x[j][1] < sublo[1]) rmaxbig = MAX(rmaxbig,sublo[1]-x[j][1]); - if (x[j][2] < sublo[2]) rmaxbig = MAX(rmaxbig,sublo[2]-x[j][2]); - if (x[j][0] > subhi[0]) rmaxbig = MAX(rmaxbig,x[j][0]-subhi[0]); - if (x[j][1] > subhi[1]) rmaxbig = MAX(rmaxbig,x[j][1]-subhi[1]); - if (x[j][2] > subhi[2]) rmaxbig = MAX(rmaxbig,x[j][2]-subhi[2]); - if (maxstrain[j] < qfactor) { - if (x[j][0] < sublo[0]) rmax = MAX(rmax,sublo[0]-x[j][0]); - if (x[j][1] < sublo[1]) rmax = MAX(rmax,sublo[1]-x[j][1]); - if (x[j][2] < sublo[2]) rmax = MAX(rmax,sublo[2]-x[j][2]); - if (x[j][0] > subhi[0]) rmax = MAX(rmax,x[j][0]-subhi[0]); - if (x[j][1] > subhi[1]) rmax = MAX(rmax,x[j][1]-subhi[1]); - if (x[j][2] > subhi[2]) rmax = MAX(rmax,x[j][2]-subhi[2]); + + if (checkghost) { + if (j >= nlocal) { + if (x[j][0] < sublo[0]) rmaxbig = MAX(rmaxbig,sublo[0]-x[j][0]); + if (x[j][1] < sublo[1]) rmaxbig = MAX(rmaxbig,sublo[1]-x[j][1]); + if (x[j][2] < sublo[2]) rmaxbig = MAX(rmaxbig,sublo[2]-x[j][2]); + if (x[j][0] > subhi[0]) rmaxbig = MAX(rmaxbig,x[j][0]-subhi[0]); + if (x[j][1] > subhi[1]) rmaxbig = MAX(rmaxbig,x[j][1]-subhi[1]); + if (x[j][2] > subhi[2]) rmaxbig = MAX(rmaxbig,x[j][2]-subhi[2]); + if (maxstrain[j] < qfactor) { + if (x[j][0] < sublo[0]) rmax = MAX(rmax,sublo[0]-x[j][0]); + if (x[j][1] < sublo[1]) rmax = MAX(rmax,sublo[1]-x[j][1]); + if (x[j][2] < sublo[2]) rmax = MAX(rmax,sublo[2]-x[j][2]); + if (x[j][0] > subhi[0]) rmax = MAX(rmax,x[j][0]-subhi[0]); + if (x[j][1] > subhi[1]) rmax = MAX(rmax,x[j][1]-subhi[1]); + if (x[j][2] > subhi[2]) rmax = MAX(rmax,x[j][2]-subhi[2]); + } } } } - + if (maxhalfstrain[iold] < selfstrain) eligible[iold] = 0; if (selfstrain < emax) eligible[iold] = 0; else if (ncount > 1) { @@ -565,15 +593,6 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) maxstrain_domain[i] = emax; } - // diagnostic // NOTE: optional, should skip - - double rmax2[2],rmax2all[2]; - rmax2[0] = rmax; - rmax2[1] = rmaxbig; - MPI_Allreduce(&rmax2,&rmax2all,2,MPI_DOUBLE,MPI_MAX,world); - rmaxever = rmax2all[0]; - rmaxeverbig = rmax2all[1]; - //time4 = MPI_Wtime(); // reverse comm to acquire maxstrain_domain from ghost atoms @@ -607,7 +626,7 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) maxbias += DELTABIAS; memory->grow(bias,maxbias,"hyper/local:bias"); } - bias[nbias++] = ibond; + bias[nbias++] = maxhalf[iold]; } //time6 = MPI_Wtime(); @@ -620,6 +639,7 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) double **f = atom->f; int nobias = 0; + int negstrain = 0; mybias = 0.0; for (int ibias = 0; ibias < nbias; ibias++) { @@ -637,11 +657,9 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) delz = x[i][2] - x[j][2]; r = sqrt(delx*delx + dely*dely + delz*delz); r0 = blist[m].r0; - //ebias = (r-r0) / r0; - ebias = fabs(r-r0) / r0; - biascoeff = blist[m].biascoeff; - vbias = biascoeff * vmax * (1.0 - ebias*ebias*invqfactorsq); - fbias = biascoeff * 2.0 * vmax * ebias * invqfactorsq; + ebias = (r-r0) / r0; + vbias = biascoeff[m] * vmax * (1.0 - ebias*ebias*invqfactorsq); + fbias = biascoeff[m] * 2.0 * vmax * ebias * invqfactorsq; fbiasr = fbias / r0 / r; f[i][0] += delx*fbiasr; @@ -652,6 +670,7 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) f[j][1] -= dely*fbiasr; f[j][2] -= delz*fbiasr; + if (ebias < 0.0) negstrain++; mybias += vbias; } @@ -662,50 +681,59 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) // ------------------------------------------------------------- // no boostostat update when pre_reverse called from setup() - // nbias_running, nobias_running, sumbiascoeff only incremented on run steps - // NOTE: maybe should also not bias any bonds on firststep of this fix + // nbias_running, nobias_running, negstrain_running only incremented + // on run steps if (setupflag) return; nbias_running += nbias; nobias_running += nobias; + negstrain_running += negstrain; // loop over bonds I own to adjust bias coeff // delta in boost coeff is function of maxboost_domain vs target boost // maxboost_domain is function of two maxstrain_domains for I,J - double mybias = 0.0; - double emaxi,emaxj,maxboost_domain; + double emaxi,emaxj,maxboost_domain,bc; + double mybiascoeff = 0.0; for (m = 0; m < nblocal; m++) { i = blist[m].i; j = blist[m].j; - emaxi = fabs(maxstrain_domain[i]); - emaxj = fabs(maxstrain_domain[j]); + emaxi = maxstrain_domain[i]; + emaxj = maxstrain_domain[j]; emax = MAX(emaxi,emaxj); if (emax < qfactor) vbias = vmax * (1.0 - emax*emax*invqfactorsq); else vbias = 0.0; - biascoeff = blist[m].biascoeff; - maxboost_domain = exp(beta * biascoeff*vbias); - biascoeff -= alpha * (maxboost_domain-boost_target) / boost_target; - blist[m].biascoeff = biascoeff; + maxboost_domain = exp(beta * biascoeff[m]*vbias); + biascoeff[m] -= alpha * (maxboost_domain-boost_target) / boost_target; // stats - mybias += biascoeff; - maxbiascoeff = MAX(maxbiascoeff,biascoeff); - minbiascoeff = MIN(minbiascoeff,biascoeff); + bc = biascoeff[m]; + mybiascoeff += bc; + minbiascoeff = MIN(minbiascoeff,bc); + maxbiascoeff = MAX(maxbiascoeff,bc); } - // running stats - - MPI_Allreduce(&mybias,&allbias,1,MPI_DOUBLE,MPI_SUM,world); - if (allbonds) sumbiascoeff += allbias/allbonds; - // ------------------------------------------------------------- - // extra diagnostics if requested + // diagnostics, some optional // ------------------------------------------------------------- + MPI_Allreduce(&mybiascoeff,&sumbiascoeff,1,MPI_DOUBLE,MPI_SUM,world); + if (allbonds) avebiascoeff += sumbiascoeff/allbonds; + + // if requested, monitor ghost distance from processor sub-boxes + + if (checkghost) { + double rmax2[2],rmax2all[2]; + rmax2[0] = rmax; + rmax2[1] = rmaxbig; + MPI_Allreduce(&rmax2,&rmax2all,2,MPI_DOUBLE,MPI_MAX,world); + rmaxever = rmax2all[0]; + rmaxeverbig = rmax2all[1]; + } + // if requsted, check for any biased bonds that are too close to each other // keep a running count for output // requires 2 additional local comm operations @@ -713,7 +741,7 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) if (checkbias && update->ntimestep % checkbias_every == 0) { // mark each atom in a biased bond with ID of partner - // nbias loop will mark some ghost atoms + // this may mark some ghost atoms for (i = 0; i < nall; i++) biasflag[i] = 0; @@ -728,13 +756,13 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) } // reverse comm to acquire biasflag from ghost atoms - // needed b/c above loop may set biasflag of ghost atoms - // forward comm to acquire biasflag of all ghost atoms + // forward comm to set biasflag for all ghost atoms commflag = BIASFLAG; comm->reverse_comm_fix(this); comm->forward_comm_fix(this); + // loop over Dcut full neighbor list // I and J may be ghost atoms // only continue if I is a biased atom // if J is unknown (drifted ghost) just ignore @@ -755,6 +783,19 @@ void FixHyperLocal::pre_reverse(int /* eflag */, int /* vflag */) if (biasflag[j] && biasflag[j] != tag[i]) checkbias_count++; } } + + if (checkbias_flag != IGNORE) { + int allcount; + MPI_Allreduce(&checkbias_count,&allcount,1,MPI_INT,MPI_SUM,world); + if (allcount) { + char str[128]; + sprintf(str,"Fix hyper/local biased bonds too close: " + "cumulative atom count %d",allcount); + if (checkbias_flag == WARN) { + if (me == 0) error->warning(FLERR,str); + } else error->all(FLERR,str); + } + } } } @@ -769,9 +810,9 @@ void FixHyperLocal::min_pre_neighbor() void FixHyperLocal::build_bond_list(int natom) { - int i,j,ii,jj,m,n,inum,jnum,nbond; + int i,j,ii,jj,m,n,iold,jold,ilocal,jlocal,inum,jnum,nbond; tagint itag,jtag; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq,oldcoeff; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq,distsq,oldcoeff; int *ilist,*jlist,*numneigh,**firstneigh; double time1,time2; @@ -782,80 +823,117 @@ void FixHyperLocal::build_bond_list(int natom) nevent_atom += natom; } - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; + // compute max distance any bond atom has moved between 2 quenched states + // xold[iold] = last quenched coord for iold + // x[ilocal] = current quenched coord for same atom + // use of old2now calculates distsq only once per atom + + double **x = atom->x; + + for (i = 0; i < nall_old; i++) old2now[i] = -1; + + for (m = 0; m < nblocal; m++) { + iold = blist[m].iold; + if (old2now[iold] < 0) { + ilocal = atom->map(tagold[iold]); + ilocal = domain->closest_image(xold[iold],ilocal); + if (ilocal < 0) error->one(FLERR,"Fix hyper/local bond atom not found"); + old2now[iold] = ilocal; + distsq = MathExtra::distsq3(x[ilocal],xold[iold]); + maxdriftsq = MAX(distsq,maxdriftsq); + } + jold = blist[m].jold; + if (old2now[jold] < 0) { + jold = blist[m].jold; + jlocal = atom->map(tagold[jold]); + jlocal = domain->closest_image(xold[iold],jlocal); // close to I atom + if (jlocal < 0) error->one(FLERR,"Fix hyper/local bond atom not found"); + old2now[jold] = jlocal; + distsq = MathExtra::distsq3(x[jlocal],xold[jold]); + maxdriftsq = MAX(distsq,maxdriftsq); + } + } - // acquire old bond coeffs so can persist them in new blist - // while loop is to allow new value of maxcoeffperatom - // will loop at most 2 times, just once when maxcoeffperatom is large enough - // just reverse comm needed, - // b/c new bond list will be bonds of current owned atoms + // store old bond coeffs so can persist them in new blist + // while loop allows growing value of maxbondperatom + // will loop at most 2 times, stops when maxbondperatom is large enough + // requires reverse comm, no forward comm: + // b/c new coeff list is stored only by current owned atoms tagint *tag = atom->tag; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; if (maxcoeff < nall) { + memory->destroy(numcoeff); + memory->sfree(clist); maxcoeff = atom->nmax; - grow_coeff(); + memory->create(numcoeff,maxcoeff,"hyper/local:numcoeff"); + clist = (OneCoeff **) memory->smalloc(maxcoeff*sizeof(OneCoeff *), + "hyper/local:clist"); } while (1) { if (firstflag) break; for (i = 0; i < nall; i++) numcoeff[i] = 0; + for (i = 0; i < nall; i++) clist[i] = NULL; + cpage->reset(); for (m = 0; m < nblocal; m++) { i = blist[m].i; j = blist[m].j; - if (numcoeff[i] < maxcoeffperatom) { - clist[i][numcoeff[i]].biascoeff = blist[m].biascoeff; - clist[i][numcoeff[i]].jtag = tag[j]; + if (numcoeff[i] == 0) clist[i] = cpage->get(maxbondperatom); + if (numcoeff[j] == 0) clist[j] = cpage->get(maxbondperatom); + + if (numcoeff[i] < maxbondperatom) { + clist[i][numcoeff[i]].biascoeff = biascoeff[m]; + clist[i][numcoeff[i]].tag = tag[j]; } numcoeff[i]++; - if (numcoeff[j] < maxcoeffperatom) { - clist[j][numcoeff[j]].biascoeff = blist[m].biascoeff; - clist[j][numcoeff[i]].jtag = tag[i]; + if (numcoeff[j] < maxbondperatom) { + clist[j][numcoeff[j]].biascoeff = biascoeff[m]; + clist[j][numcoeff[j]].tag = tag[i]; } numcoeff[j]++; } - int maxcol = 0; - for (i = 0; i < nall; i++) maxcol = MAX(maxcol,numcoeff[i]); - int maxcolall; - MPI_Allreduce(&maxcol,&maxcolall,1,MPI_INT,MPI_MAX,world); + int mymax = 0; + for (i = 0; i < nall; i++) mymax = MAX(mymax,numcoeff[i]); + int maxcoeffall; + MPI_Allreduce(&mymax,&maxcoeffall,1,MPI_INT,MPI_MAX,world); - if (maxcolall > maxcoeffperatom) { - maxcoeffperatom = maxcolall; - grow_coeff(); - memory->destroy(clist); - memory->create(clist,maxcoeff,maxcoeffperatom,"hyper/local:clist"); + if (maxcoeffall > maxbondperatom) { + maxbondperatom = maxcoeffall; + cpage->init(maxbondperatom,1024*maxbondperatom,1); continue; } commflag = BIASCOEFF; - comm->reverse_comm_fix(this); + comm->reverse_comm_fix_variable(this); - maxcol = 0; - for (i = 0; i < nall; i++) maxcol = MAX(maxcol,numcoeff[i]); - MPI_Allreduce(&maxcol,&maxcolall,1,MPI_INT,MPI_MAX,world); - if (maxcolall <= maxcoeffperatom) break; + mymax = 0; + for (i = 0; i < nall; i++) mymax = MAX(mymax,numcoeff[i]); + MPI_Allreduce(&mymax,&maxcoeffall,1,MPI_INT,MPI_MAX,world); + if (maxcoeffall <= maxbondperatom) break; - maxcoeffperatom = maxcolall; - grow_coeff(); + maxbondperatom = maxcoeffall; + cpage->init(maxbondperatom,1024*maxbondperatom,1); } - // reallocate vectors that are maxnew xold and tagold if necessary - // initialize xold to current coords - // initialize tagold to zero, so atoms not in neighbor list will remain zero + // reallocate vectors that are maxlocal and maxall length if necessary if (nlocal > maxlocal) { memory->destroy(eligible); memory->destroy(numbond); memory->destroy(maxhalf); + memory->destroy(maxhalfstrain); maxlocal = nlocal; memory->create(eligible,maxlocal,"hyper/local:eligible"); memory->create(numbond,maxlocal,"hyper/local:numbond"); memory->create(maxhalf,maxlocal,"hyper/local:maxhalf"); + memory->create(maxhalfstrain,maxlocal,"hyper/local:maxhalfstrain"); } if (nall > maxall) { @@ -870,23 +948,26 @@ void FixHyperLocal::build_bond_list(int natom) // nlocal_old = value of nlocal at time bonds are built // nall_old = value of nall at time bonds are built - // archive current peratom info in old vecs + // archive current atom coords in xold + // tagold will be set to non-zero below for accessed atoms + // numbond will be set below nlocal_old = nlocal; nall_old = nall; - double **x = atom->x; - memcpy(&xold[0][0],&x[0][0],3*nall*sizeof(double)); for (i = 0; i < nall; i++) tagold[i] = 0; for (i = 0; i < nlocal; i++) numbond[i] = 0; - // trigger builds for both neighbor lists - // NOTE: insure the I atoms are in same order? - + // trigger neighbor list builds for both lists + // insure the I loops in both are from 1 to nlocal + neighbor->build_one(listfull); neighbor->build_one(listhalf); + if (listfull->inum != nlocal || listhalf->inum != nlocal) + error->one(FLERR,"Invalid neighbor list in fix hyper/local bond build"); + // set tagold = 1 for all J atoms used in full neighbor list // tagold remains 0 for unused atoms, skipped in pre_neighbor @@ -897,12 +978,13 @@ void FixHyperLocal::build_bond_list(int natom) for (ii = 0; ii < inum; ii++) { i = ilist[ii]; + tagold[i] = tag[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; - tagold[j] = 1; + tagold[j] = tag[j]; } } @@ -916,7 +998,6 @@ void FixHyperLocal::build_bond_list(int natom) numneigh = listhalf->numneigh; firstneigh = listhalf->firstneigh; - bigint bondcount = 0; nblocal = 0; for (ii = 0; ii < inum; ii++) { @@ -966,16 +1047,16 @@ void FixHyperLocal::build_bond_list(int natom) jtag = tag[j]; n = numcoeff[i]; for (m = 0; m < n; m++) { - if (clist[i][m].jtag == jtag) { + if (clist[i][m].tag == jtag) { oldcoeff = clist[i][m].biascoeff; break; } } } - if (oldcoeff > 0.0) blist[nblocal].biascoeff = oldcoeff; + if (oldcoeff > 0.0) biascoeff[nblocal] = oldcoeff; else { - blist[nblocal].biascoeff = COEFFINIT; + biascoeff[nblocal] = COEFFINIT; nnewbond++; } @@ -984,9 +1065,15 @@ void FixHyperLocal::build_bond_list(int natom) } numbond[i] = nbond; - bondcount += nbond; } - + + // this fix allows access to biascoeffs as local data + + size_local_rows = nblocal; + + // allbonds = total # of bonds in system + + bigint bondcount = nblocal; MPI_Allreduce(&bondcount,&allbonds,1,MPI_LMP_BIGINT,MPI_SUM,world); time2 = MPI_Wtime(); @@ -1010,6 +1097,7 @@ int FixHyperLocal::pack_forward_comm(int n, int *list, double *buf, // STRAIN // pack maxstrain vector + // must send to all ghosts out to Dcut if (commflag == STRAIN) { for (i = 0; i < n; i++) { @@ -1019,6 +1107,8 @@ int FixHyperLocal::pack_forward_comm(int n, int *list, double *buf, // STRAINDOMAIN // pack maxstrain_domain vector + // could just send to nearby ghosts in bonds + // don't see easy way to determine precisely which atoms that is } else if (commflag == STRAINDOMAIN) { for (i = 0; i < n; i++) { @@ -1028,6 +1118,7 @@ int FixHyperLocal::pack_forward_comm(int n, int *list, double *buf, // BIASFLAG // pack biasflag vector + // must send to all ghosts out to Dcut } else if (commflag == BIASFLAG) { for (i = 0; i < n; i++) { @@ -1085,22 +1176,37 @@ int FixHyperLocal::pack_reverse_comm(int n, int first, double *buf) // STRAIN // pack maxstrain vector + // only pack for nonzero values if (commflag == STRAIN) { + int nonzero = 0; + m++; // placeholder for count of atoms for (i = first; i < last; i++) { - buf[m++] = maxstrain[i]; + if (maxstrain[i] == 0.0) continue; + nonzero++; + buf[m++] = ubuf(i-first).d; // which atom is next + buf[m++] = maxstrain[i]; // value } + buf[0] = ubuf(nonzero).d; // STRAINDOMAIN // pack maxstrain_domain vector + // only pack for nonzero values } else if (commflag == STRAINDOMAIN) { + int nonzero = 0; + m++; // placeholder for count of atoms for (i = first; i < last; i++) { - buf[m++] = maxstrain_domain[i]; + if (maxstrain[i] == 0.0) continue; + nonzero++; + buf[m++] = ubuf(i-first).d; // which atom is next + buf[m++] = maxstrain_domain[i]; // value } + buf[0] = ubuf(nonzero).d; // BIASFLAG // pack biasflag vector + // could just pack for nonzero values, like STRAIN and STRAINDOMAIN } else if (commflag == BIASFLAG) { for (i = first; i < last; i++) { @@ -1109,22 +1215,46 @@ int FixHyperLocal::pack_reverse_comm(int n, int first, double *buf) // BIASCOEFF // pack list of biascoeffs + // only pack for atoms with nonzero # of bias coeffs + // this will skip majority of ghost atoms } else if (commflag == BIASCOEFF) { int ncoeff; + int nonzero = 0; + m++; // placeholder for count of atoms for (i = first; i < last; i++) { + if (numcoeff[i] == 0) continue; + nonzero++; ncoeff = numcoeff[i]; - buf[m++] = ubuf(ncoeff).d; + buf[m++] = ubuf(i-first).d; // which atom is next + buf[m++] = ubuf(ncoeff).d; // # of bias coeffs for (j = 0; j < ncoeff; j++) { buf[m++] = clist[i][j].biascoeff; - buf[m++] = ubuf(clist[i][j].jtag).d; + buf[m++] = ubuf(clist[i][j].tag).d; } } + buf[0] = ubuf(nonzero).d; } return m; } +/* ---------------------------------------------------------------------- + callback by comm->reverse_comm_fix_variable() in build_bond() + same logic as BIASCOEFF option in pack_reverse_comm() + m = returned size of message +------------------------------------------------------------------------- */ + +int FixHyperLocal::pack_reverse_comm_size(int n, int first) +{ + int last = first + n; + int m = 1; + for (int i = first; i < last; i++) { + if (numcoeff[i]) m += 2 + 2*numcoeff[i]; + } + return m; +} + /* ---------------------------------------------------------------------- */ void FixHyperLocal::unpack_reverse_comm(int n, int *list, double *buf) @@ -1135,23 +1265,32 @@ void FixHyperLocal::unpack_reverse_comm(int n, int *list, double *buf) // STRAIN // unpack maxstrain vector + // nonzero # of entries, each has offset to which atom in receiver's list // use MAX, b/c want maximum abs value strain for each atom's bonds if (commflag == STRAIN) { - for (i = 0; i < n; i++) { - j = list[i]; + int offset; + int nonzero = (int) ubuf(buf[m++]).i; // # of atoms with values + for (int iatom = 0; iatom < nonzero; iatom++) { + offset = (int) ubuf(buf[m++]).i; // offset into list for which atom + j = list[offset]; maxstrain[j] = MAX(maxstrain[j],buf[m]); m++; } // STRAINDOMAIN // unpack maxstrain_domain vector - // use SUM, b/c exactly one ghost or owned value per atom ID is non-zero + // use MAX, b/c want maximum abs value strain for each atom's domain + // could also use SUM, b/c exactly one ghost or owned value is non-zero } else if (commflag == STRAINDOMAIN) { - for (i = 0; i < n; i++) { - j = list[i]; - maxstrain_domain[j] += buf[m++]; + int offset; + int nonzero = (int) ubuf(buf[m++]).i; // # of atoms with values + for (int iatom = 0; iatom < nonzero; iatom++) { + offset = (int) ubuf(buf[m++]).i; // offset into list for which atom + j = list[offset]; + maxstrain_domain[j] = MAX(maxstrain_domain[j],buf[m]); + m++; } // BIASFLAG @@ -1164,19 +1303,23 @@ void FixHyperLocal::unpack_reverse_comm(int n, int *list, double *buf) } // BIASCOEFF - // unpack list of biascoeffs and add to atom J's list - // protect against overflow of clist columns - // if that happens, caller will realloc clist and reverse comm again + // unpack list of biascoeffs + // nonzero # of entries, each has offset to which atom in receiver's list + // protect against overflow of clist vector + // if that happens, caller will re-setup cpage and reverse comm again - } else if (commflag == BIASFLAG) { - int ncoeff; - for (i = 0; i < n; i++) { - j = list[i]; - ncoeff = (int) ubuf(buf[m++]).i; + } else if (commflag == BIASCOEFF) { + int offset,ncoeff; + int nonzero = (int) ubuf(buf[m++]).i; // # of atoms with coeffs + for (int iatom = 0; iatom < nonzero; iatom++) { + offset = (int) ubuf(buf[m++]).i; // offset into list for which atom + j = list[offset]; + ncoeff = (int) ubuf(buf[m++]).i; // # of bias coeffs for (k = 0; k < ncoeff; k++) { - if (numcoeff[j] < maxcoeffperatom) { + if (numcoeff[j] == 0) clist[j] = cpage->get(maxbondperatom); + if (numcoeff[j] < maxbondperatom) { clist[j][numcoeff[j]].biascoeff = buf[m++]; - clist[j][numcoeff[j]].jtag = (tagint) ubuf(buf[m++]).i; + clist[j][numcoeff[j]].tag = (tagint) ubuf(buf[m++]).i; } else m += 2; numcoeff[j]++; } @@ -1185,7 +1328,7 @@ void FixHyperLocal::unpack_reverse_comm(int n, int *list, double *buf) } /* ---------------------------------------------------------------------- - grow bond list by a chunk + grow bond list and bias coeff vector by a chunk ------------------------------------------------------------------------- */ void FixHyperLocal::grow_bond() @@ -1195,16 +1338,8 @@ void FixHyperLocal::grow_bond() maxbond += DELTABOND; blist = (OneBond *) memory->srealloc(blist,maxbond*sizeof(OneBond),"hyper/local:blist"); -} - -/* ---------------------------------------------------------------------- - reallocate 2-dimensional clist -------------------------------------------------------------------------- */ - -void FixHyperLocal::grow_coeff() -{ - memory->destroy(clist); - memory->create(clist,maxcoeff,maxcoeffperatom,"hyper/local:clist"); + memory->grow(biascoeff,maxbond,"hyper/local:biascoeff"); + vector_local = biascoeff; } /* ---------------------------------------------------------------------- */ @@ -1220,41 +1355,35 @@ double FixHyperLocal::compute_scalar() double FixHyperLocal::compute_vector(int i) { - // 23 vector outputs returned for i = 0-22 + // 21 vector outputs returned for i = 0-20 // i = 0 = # of biased bonds on this step // i = 1 = max strain of any bond on this step - // i = 2 = average bias potential for all bonds on this step + // i = 2 = average bias coeff for all bonds on this step // i = 3 = ave bonds/atom on this step // i = 4 = ave neighbor bonds/bond on this step - // i = 5 = fraction of steps and bonds with no bias during this run - // i = 6 = max drift distance of any atom during this run - // i = 7 = max bond length during this run - // i = 8 = average # of biased bonds/step during this run - // i = 9 = average bias potential for all bonds during this run - // i = 10 = max bias potential for any bond during this run - // i = 11 = min bias potential for any bond during this run - // i = 12 = max dist from my box of any ghost atom with - // maxstain < qfactor during this run - // i = 13 = max dist from my box of any ghost atom with + // i = 5 = max bond length during this run + // i = 6 = average # of biased bonds/step during this run + // i = 7 = fraction of biased bonds with no bias during this run + // i = 8 = fraction of biased bonds with negative strain during this run + // i = 9 = average bias coeff for all bonds during this run + // i = 10 = min bias coeff for any bond during this run + // i = 11 = max bias coeff for any bond during this run + + // i = 12 = max drift distance of any atom during this run + // i = 13 = max distance from proc subbox of any ghost atom with + // maxstrain < qfactor during this run + // i = 14 = max distance from proc subbox of any ghost atom with // any maxstrain during this run - // i = 14 = count of ghost atoms that could not be found - // by any proc at any reneighbor step during this run - - // NOTE: these 2 are no longer relevant - // i = 15 = count of lost bond partners during this run - // i = 16 = average bias coeff for lost bond partners during this run + // i = 15 = count of ghost atoms that could not be found + // on reneighbor steps during this run + // i = 16 = count of bias overlaps (< Dcut) found during this run - // i = 17 = count of bias overlaps found during this run - - // NOTE: this is no longer relevant - // i = 18 = count of non-matching bias coefficients found during this run - - // i = 19 = cummulative hyper time - // i = 20 = cummulative # of event timesteps since fix created - // i = 21 = cummulative # of atoms in events since fix created - // i = 22 = cummulative # of new bonds formed since fix created + // i = 17 = cumulative hyper time since fix created + // i = 18 = cumulative # of event timesteps since fix created + // i = 19 = cumulative # of atoms in events since fix created + // i = 20 = cumulative # of new bonds formed since fix created if (i == 0) { int nbiasall; @@ -1274,7 +1403,7 @@ double FixHyperLocal::compute_vector(int i) } if (i == 2) { - if (allbias && allbonds) return allbias/allbonds * vmax; + if (allbonds) return sumbiascoeff/allbonds; return 1.0; } @@ -1294,75 +1423,84 @@ double FixHyperLocal::compute_vector(int i) } if (i == 5) { - int allbias_running,allnobias_running; - MPI_Allreduce(&nbias_running,&allbias_running,1,MPI_INT,MPI_SUM,world); - MPI_Allreduce(&nobias_running,&allnobias_running,1,MPI_INT,MPI_SUM,world); - if (allbias_running) return 1.0*allnobias_running / allbias_running; - return 0.0; + double allbondlen; + MPI_Allreduce(&maxbondlen,&allbondlen,1,MPI_DOUBLE,MPI_MAX,world); + return allbondlen; } if (i == 6) { - double alldriftsq; - MPI_Allreduce(&maxdriftsq,&alldriftsq,1,MPI_DOUBLE,MPI_MAX,world); - return (double) sqrt(alldriftsq); + if (update->ntimestep == update->firststep) return 0.0; + int allbias_running; + MPI_Allreduce(&nbias_running,&allbias_running,1,MPI_INT,MPI_SUM,world); + return 1.0*allbias_running / (update->ntimestep - update->firststep); } if (i == 7) { - double allbondlen; - MPI_Allreduce(&maxbondlen,&allbondlen,1,MPI_DOUBLE,MPI_MAX,world); - return allbondlen; + int allbias_running,allnobias_running; + MPI_Allreduce(&nbias_running,&allbias_running,1,MPI_INT,MPI_SUM,world); + MPI_Allreduce(&nobias_running,&allnobias_running,1,MPI_INT,MPI_SUM,world); + if (allbias_running) return 1.0*allnobias_running / allbias_running; + return 0.0; } if (i == 8) { - if (update->ntimestep == update->firststep) return 0.0; - int allbias_running; + int allbias_running,allnegstrain_running; MPI_Allreduce(&nbias_running,&allbias_running,1,MPI_INT,MPI_SUM,world); - return 1.0*allbias_running / (update->ntimestep - update->firststep); + MPI_Allreduce(&negstrain_running,&allnegstrain_running,1,MPI_INT, + MPI_SUM,world); + if (allbias_running) return 1.0*allnegstrain_running / allbias_running; + return 0.0; } if (i == 9) { if (update->ntimestep == update->firststep) return 0.0; - return sumbiascoeff * vmax / (update->ntimestep - update->firststep); + return avebiascoeff / (update->ntimestep - update->firststep); } if (i == 10) { - double allbiascoeff; - MPI_Allreduce(&maxbiascoeff,&allbiascoeff,1,MPI_DOUBLE,MPI_MAX,world); - return allbiascoeff * vmax; + double biascoeff; + MPI_Allreduce(&minbiascoeff,&biascoeff,1,MPI_DOUBLE,MPI_MIN,world); + return biascoeff; } if (i == 11) { - double allbiascoeff; - MPI_Allreduce(&minbiascoeff,&allbiascoeff,1,MPI_DOUBLE,MPI_MAX,world); - return allbiascoeff * vmax; + double biascoeff; + MPI_Allreduce(&maxbiascoeff,&biascoeff,1,MPI_DOUBLE,MPI_MAX,world); + return biascoeff; + } + + if (i == 12) { + double alldriftsq; + MPI_Allreduce(&maxdriftsq,&alldriftsq,1,MPI_DOUBLE,MPI_MAX,world); + return (double) sqrt(alldriftsq); } - if (i == 12) return rmaxever; - if (i == 13) return rmaxeverbig; + if (i == 13) return rmaxever; + if (i == 14) return rmaxeverbig; - if (i == 14) { + if (i == 15) { int allghost_toofar; MPI_Allreduce(&ghost_toofar,&allghost_toofar,1,MPI_INT,MPI_SUM,world); return 1.0*allghost_toofar; } - if (i == 17) { + if (i == 16) { int allclose; MPI_Allreduce(&checkbias_count,&allclose,1,MPI_INT,MPI_SUM,world); return 1.0*allclose; } - if (i == 19) { + if (i == 17) { return boost_target * update->dt * (update->ntimestep - starttime); } - if (i == 20) return (double) nevent; - if (i == 21) return (double) nevent_atom; + if (i == 18) return (double) nevent; + if (i == 19) return (double) nevent_atom; - if (i == 22) { - int allnew; - MPI_Allreduce(&nnewbond,&allnew,1,MPI_INT,MPI_SUM,world); - return (double) 0.5*allnew; + if (i == 20) { + int allnewbond; + MPI_Allreduce(&nnewbond,&allnewbond,1,MPI_INT,MPI_SUM,world); + return (double) allnewbond; } return 0.0; @@ -1375,32 +1513,30 @@ double FixHyperLocal::compute_vector(int i) double FixHyperLocal::query(int i) { - if (i == 1) return compute_vector(19); // cummulative hyper time - if (i == 2) return compute_vector(20); // nevent - if (i == 3) return compute_vector(21); // nevent_atom + if (i == 1) return compute_vector(17); // cummulative hyper time + if (i == 2) return compute_vector(18); // nevent + if (i == 3) return compute_vector(19); // nevent_atom if (i == 4) return compute_vector(3); // ave bonds/atom - if (i == 5) return compute_vector(6); // maxdrift - if (i == 6) return compute_vector(7); // maxbondlen - if (i == 7) return compute_vector(5); // fraction with zero bias + if (i == 5) return compute_vector(12); // maxdrift + if (i == 6) return compute_vector(5); // maxbondlen + if (i == 7) return compute_vector(7); // fraction with zero bias + if (i == 8) return compute_vector(8); // fraction with negative strain // unique to local hyper - if (i == 8) return compute_vector(22); // number of new bonds - if (i == 9) return 1.0*maxbondperatom; // max bonds/atom - if (i == 10) return compute_vector(8); // ave # of biased bonds/step - if (i == 11) return compute_vector(9); // ave bias coeff over all bonds - if (i == 12) return compute_vector(10); // max bias cooef for any bond - if (i == 13) return compute_vector(11); // max bias cooef for any bond - if (i == 14) return compute_vector(4); // neighbor bonds/bond - if (i == 15) return compute_vector(2); // ave bias coeff now - if (i == 16) return time_bondbuild; // CPU time for bond_build calls - if (i == 17) return rmaxever; // ghost atom distance for < maxstrain - if (i == 18) return rmaxeverbig; // ghost atom distance for any strain - if (i == 19) return compute_vector(14); // count of ghost atoms not found - //if (i == 20) return compute_vector(15); // count of lost bond partners - //if (i == 21) return compute_vector(16); // ave bias coeff of long bonds - if (i == 22) return compute_vector(17); // count of bias overlaps - //if (i == 23) return compute_vector(18); // count of non-matching bias coeffs + if (i == 9) return compute_vector(20); // number of new bonds + if (i == 10) return 1.0*maxbondperatom; // max bonds/atom + if (i == 11) return compute_vector(6); // ave # of biased bonds/step + if (i == 12) return compute_vector(9); // ave bias coeff over all bonds + if (i == 13) return compute_vector(10); // min bias cooef for any bond + if (i == 14) return compute_vector(11); // max bias cooef for any bond + if (i == 15) return compute_vector(4); // neighbor bonds/bond + if (i == 16) return compute_vector(2); // ave bias coeff now + if (i == 17) return time_bondbuild; // CPU time for build_bond calls + if (i == 18) return rmaxever; // ghost atom distance for < maxstrain + if (i == 19) return rmaxeverbig; // ghost atom distance for any strain + if (i == 20) return compute_vector(15); // count of ghost atoms not found + if (i == 21) return compute_vector(16); // count of bias overlaps error->all(FLERR,"Invalid query to fix hyper/local"); @@ -1408,21 +1544,22 @@ double FixHyperLocal::query(int i) } /* ---------------------------------------------------------------------- - memory usage of per-atom and per-bond arrays + memory usage of per-atom and per-bond data structs ------------------------------------------------------------------------- */ double FixHyperLocal::memory_usage() { - int nmax = atom->nmax; - double bytes = maxbond * sizeof(OneBond); // bond list + double bytes = maxbond * sizeof(OneBond); // blist + bytes = maxbond * sizeof(double); // per-bond bias coeffs bytes += 3*maxlocal * sizeof(int); // numbond,maxhalf,eligible bytes += maxlocal * sizeof(double); // maxhalfstrain bytes += maxall * sizeof(int); // old2now bytes += maxall * sizeof(tagint); // tagold bytes += 3*maxall * sizeof(double); // xold - bytes += 2*nmax * sizeof(double); // maxstrain,maxstrain_domain - if (checkbias) bytes += nmax * sizeof(tagint); // biasflag - bytes += maxcoeff*maxcoeffperatom * sizeof(OneCoeff); // clist - bytes += maxcoeff * sizeof(int); // numcoeff + bytes += 2*maxall * sizeof(double); // maxstrain,maxstrain_domain + if (checkbias) bytes += maxall * sizeof(tagint); // biasflag + bytes += maxcoeff * sizeof(int); // numcoeff + bytes += maxcoeff * sizeof(OneCoeff *); // clist + bytes += maxlocal*maxbondperatom * sizeof(OneCoeff); // cpage estimate return bytes; } diff --git a/src/REPLICA/fix_hyper_local.h b/src/REPLICA/fix_hyper_local.h index 67361ce3ac..f0075c185c 100644 --- a/src/REPLICA/fix_hyper_local.h +++ b/src/REPLICA/fix_hyper_local.h @@ -21,6 +21,7 @@ FixStyle(hyper/local,FixHyperLocal) #define LMP_FIX_HYPER_LOCAL_H #include "fix_hyper.h" +#include "my_page.h" namespace LAMMPS_NS { @@ -43,6 +44,7 @@ class FixHyperLocal : public FixHyper { int pack_forward_comm(int, int *, double *, int, int *); void unpack_forward_comm(int, int, double *); int pack_reverse_comm(int, int, double *); + int pack_reverse_comm_size(int, int); void unpack_reverse_comm(int, int *, double *); double memory_usage(); @@ -54,54 +56,72 @@ class FixHyperLocal : public FixHyper { private: int me; + + // inputs and derived quantities + double cutbond,qfactor,vmax,tequil,dcut; double alpha_user; // timescale to apply boostostat (time units) double alpha; // unitless dt/alpha_user double boost_target; // target value of boost - int checkbias,checkbias_every,checkbias_flag,checkbias_count; + int checkghost,checkbias; // flags for optional stats + + double cutbondsq,dcutsq; + double beta,invqfactorsq; + + // flags int setupflag; // 1 during setup, 0 during run int firstflag; // set for first time bond_build takes place - int nostrainyet; // 1 until maxstrain is first computed + int nostrainyet; // 1 until maxstrain is first compute + bigint starttime; // timestep when this fix was invoked + int commflag; // flag for communication mode + + // stats - int nbias_running,nobias_running; - int nbondbuild; - double time_bondbuild; - bigint starttime; - double sumbiascoeff; // sum of aveboost at every timestep - bigint allbonds; // sum of bond count on this step - double allbias; // sum of biascoeff on all bonds on this step + int nbondbuild; // # of rebuilds of bond list + double time_bondbuild; // CPU time for bond builds - int nnewbond; // running tally of number of new bonds created + bigint allbonds; // current total # of bonds + int nnewbond; // running tally of # of new bonds created int maxbondperatom; // max # of bonds any atom ever has - int commflag; // flag for communication mode int nevent; // # of events that trigger bond rebuild int nevent_atom; // # of atoms that experienced an event - double cutbondsq,dcutsq; - double beta,invqfactorsq; - double mybias; + + int nbias_running; // running count of biased bonds + int nobias_running; // ditto for bonds with bias = 0, b/c too long + int negstrain_running; // ditto for bonds with negative strain + + double mybias; // sum of bias potentials for biased bonds double maxbondlen; // cummulative max length of any bond - double maxdriftsq; // max distance any atom drifts from original pos - double maxbiascoeff; // cummulative max bias coeff for any bond + double maxdriftsq; // max distance any bond atom drifts from quenched x + + double sumbiascoeff; // sum of all bond bias coeffs at each timestep + double avebiascoeff; // cummulative sumbiascoeff/allbonds across steps double minbiascoeff; // cummulative min bias coeff for any bond + double maxbiascoeff; // cummulative max bias coeff for any bond + double rmaxever,rmaxeverbig; - int ghost_toofar; + int ghost_toofar; // # of ghost atoms not found in Dcut neigh list + + int checkbias_every,checkbias_flag,checkbias_count; + + // 2 neighbor lists class NeighList *listfull; // full neigh list up to Dcut distance class NeighList *listhalf; // half neigh list up to pair distance // both created only when bonds are rebuilt - // list of my owned bonds + // list of my owned bonds and bias coeffs // persists on a proc from one event until the next struct OneBond { // single IJ bond, atom I is owner int i,j; // current local indices of 2 bond atoms int iold,jold; // local indices when bonds were formed double r0; // relaxed bond length - double biascoeff; // biasing coefficient = prefactor Cij }; - struct OneBond *blist; // list of owned bonds + OneBond *blist; // list of owned bonds + double *biascoeff; // biasing coefficient Cij for each bond int nblocal; // # of owned bonds int maxbond; // allocated size of blist @@ -137,24 +157,24 @@ class FixHyperLocal : public FixHyper { tagint *biasflag; // atoms in biased bonds marked with bond partner // for owned and ghost atoms - // data struct used to persist biascoeffs when bond list is re-created - - struct OneCoeff { - double biascoeff; - tagint jtag; - }; - - struct OneCoeff **clist; // list of bond coeffs for each atom's bonds - int *numcoeff; // # of coeffs per atom - int maxcoeff; // allocate size of clist - int maxcoeffperatom; // allocated # of columns in clist - // list of biased bonds this proc owns int maxbias; // allocated size of bias list int nbias; // # of biased bonds I own int *bias; // index of biased bonds in my bond list + // data structs for persisting bias coeffs when bond list is reformed + + struct OneCoeff { + double biascoeff; + tagint tag; + }; + + MyPage *cpage; // pages of OneCoeff datums for clist + OneCoeff **clist; // ptrs to vectors of bias coeffs for each atom + int *numcoeff; // # of bias coeffs per atom (one per bond) + int maxcoeff; // allocate sized of clist and numcoeff + // extra timers //double timefirst,timesecond,timethird,timefourth; @@ -163,7 +183,6 @@ class FixHyperLocal : public FixHyper { // private methods void grow_bond(); - void grow_coeff(); }; } diff --git a/src/REPLICA/hyper.cpp b/src/REPLICA/hyper.cpp index 22940de221..0d8de6d060 100644 --- a/src/REPLICA/hyper.cpp +++ b/src/REPLICA/hyper.cpp @@ -40,9 +40,7 @@ enum{NOHYPER,GLOBAL,LOCAL}; /* ---------------------------------------------------------------------- */ -Hyper::Hyper(LAMMPS *lmp) : - Pointers(lmp), dumplist(NULL) -{} +Hyper::Hyper(LAMMPS *lmp) : Pointers(lmp), dumplist(NULL) {} /* ---------------------------------------------------------------------- perform hyperdynamics simulation @@ -260,11 +258,12 @@ void Hyper::command(int narg, char **arg) double maxdrift = 0.0; double maxbondlen = 0.0; double fraczero = 1.0; + double fracneg = 1.0; - double nnewbond,avenboost,aveboostcoeff,maxboostcoeff,minboostcoeff; - double maxbondperatom,neighbondperbond,aveboostnow; + double nnewbond,avenbias,avebiascoeff,minbiascoeff,maxbiascoeff; + double maxbondperatom,neighbondperbond,avebiasnow; double tbondbuild,rmaxever,rmaxeverbig,allghost_toofar; - double lostbond,lostbondcoeff,biasoverlap,nonmatchbiascoeff; + double lostbond,lostbondcoeff,biasoverlap; if (hyperenable) { t_hyper = fix_hyper->query(1); @@ -274,115 +273,70 @@ void Hyper::command(int narg, char **arg) maxdrift = fix_hyper->query(5); maxbondlen = fix_hyper->query(6); fraczero = fix_hyper->query(7); + fracneg = fix_hyper->query(8); if (hyperstyle == LOCAL) { - nnewbond = fix_hyper->query(8); - maxbondperatom = fix_hyper->query(9); - avenboost = fix_hyper->query(10); - aveboostcoeff = fix_hyper->query(11); - maxboostcoeff = fix_hyper->query(12); - minboostcoeff = fix_hyper->query(13); - neighbondperbond = fix_hyper->query(14); - aveboostnow = fix_hyper->query(15); - tbondbuild = fix_hyper->query(16); - rmaxever = fix_hyper->query(17); - rmaxeverbig = fix_hyper->query(18); - allghost_toofar = fix_hyper->query(19); - lostbond = fix_hyper->query(20); - lostbondcoeff = fix_hyper->query(21); - biasoverlap = fix_hyper->query(22); - nonmatchbiascoeff = fix_hyper->query(23); + nnewbond = fix_hyper->query(9); + maxbondperatom = fix_hyper->query(10); + avenbias = fix_hyper->query(11); + avebiascoeff = fix_hyper->query(12); + minbiascoeff = fix_hyper->query(13); + maxbiascoeff = fix_hyper->query(14); + neighbondperbond = fix_hyper->query(15); + avebiasnow = fix_hyper->query(16); + tbondbuild = fix_hyper->query(17); + rmaxever = fix_hyper->query(18); + rmaxeverbig = fix_hyper->query(19); + allghost_toofar = fix_hyper->query(20); + biasoverlap = fix_hyper->query(21); } } if (me == 0) { - if (screen) { - fprintf(screen,"Cummulative quantities for fix hyper:\n"); - fprintf(screen," hyper time = %g\n",t_hyper); - fprintf(screen," time boost factor = %g\n",t_hyper/(nsteps*update->dt)); - fprintf(screen," event timesteps = %d\n",nevent_running); - fprintf(screen," # of atoms in events = %d\n",nevent_atoms_running); - fprintf(screen,"Quantities for this hyper run:\n"); - fprintf(screen," event timesteps = %d\n",nevent); - fprintf(screen," # of atoms in events = %d\n",nevent_atoms); - fprintf(screen," max length of any bond = %g\n",maxbondlen); - fprintf(screen," max drift distance of any atom = %g\n",maxdrift); - fprintf(screen," fraction of steps & bonds with zero bias = %g\n", - fraczero); - fprintf(screen,"Current quantities:\n"); - fprintf(screen," ave bonds/atom = %g\n",avebonds); + FILE *out; + for (int iout = 0; iout < 2; iout++) { + if (iout == 0) out = screen; + if (iout == 1) out = logfile; + if (!out) continue; + fprintf(out,"Cummulative quantities for fix hyper:\n"); + fprintf(out," hyper time = %g\n",t_hyper); + fprintf(out," time boost factor = %g\n",t_hyper/(nsteps*update->dt)); + fprintf(out," event timesteps = %d\n",nevent_running); + fprintf(out," # of atoms in events = %d\n",nevent_atoms_running); + fprintf(out,"Quantities for this hyper run:\n"); + fprintf(out," event timesteps = %d\n",nevent); + fprintf(out," # of atoms in events = %d\n",nevent_atoms); + fprintf(out," max length of any bond = %g\n",maxbondlen); + fprintf(out," max drift distance of any atom = %g\n",maxdrift); + fprintf(out," fraction of biased bonds with zero bias = %g\n",fraczero); + fprintf(out," fraction of biased bonds with negative strain = %g\n", + fracneg); + fprintf(out,"Current quantities:\n"); + fprintf(out," ave bonds/atom = %g\n",avebonds); if (hyperstyle == LOCAL) { - fprintf(screen,"Cummulative quantities specific to fix hyper/local:\n"); - fprintf(screen," # of new bonds formed = %g\n",nnewbond); - fprintf(screen," max bonds/atom = %g\n",maxbondperatom); - fprintf(screen,"Quantities for this hyper run specific to " + fprintf(out,"Cummulative quantities specific to fix hyper/local:\n"); + fprintf(out," # of new bonds formed = %g\n",nnewbond); + fprintf(out," max bonds/atom = %g\n",maxbondperatom); + fprintf(out,"Quantities for this hyper run specific to " "fix hyper/local:\n"); - fprintf(screen," ave boosted bonds/step = %g\n",avenboost); - fprintf(screen," ave boost coeff of all bonds = %g\n",aveboostcoeff); - fprintf(screen," max boost coeff of any bond = %g\n",maxboostcoeff); - fprintf(screen," min boost coeff of any bond = %g\n",minboostcoeff); - fprintf(screen," max dist from my box of any " + fprintf(out," ave biased bonds/step = %g\n",avenbias); + fprintf(out," ave bias coeff of all bonds = %g\n",avebiascoeff); + fprintf(out," min bias coeff of any bond = %g\n",minbiascoeff); + fprintf(out," max bias coeff of any bond = %g\n",maxbiascoeff); + fprintf(out," max dist from my subbox of any " "non-maxstrain bond ghost atom = %g\n",rmaxever); - fprintf(screen," max dist from my box of any bond ghost atom = %g\n", + fprintf(out," max dist from my box of any bond ghost atom = %g\n", rmaxeverbig); - fprintf(screen," count of bond ghost neighbors " + fprintf(out," count of bond ghost neighbors " "not found on reneighbor steps = %g\n",allghost_toofar); - fprintf(screen," lost bond partners = %g\n",lostbond); - fprintf(screen," ave bias coeff for lost bond partners = %g\n", - lostbondcoeff); - fprintf(screen," bias overlaps = %g\n",biasoverlap); - fprintf(screen," non-matching bias coeffs = %g\n",nonmatchbiascoeff); - fprintf(screen," CPU time for bond builds = %g\n",tbondbuild); - fprintf(screen,"Current quantities specific to fix hyper/local:\n"); - fprintf(screen," neighbor bonds/bond = %g\n",neighbondperbond); - fprintf(screen," ave boost coeff for all bonds = %g\n",aveboostnow); + fprintf(out," bias overlaps = %g\n",biasoverlap); + fprintf(out," CPU time for bond builds = %g\n",tbondbuild); + fprintf(out,"Current quantities specific to fix hyper/local:\n"); + fprintf(out," neighbor bonds/bond = %g\n",neighbondperbond); + fprintf(out," ave boost coeff for all bonds = %g\n",avebiasnow); } - fprintf(screen,"\n"); - } - - if (logfile) { - fprintf(logfile,"Cummulative quantities for fix hyper:\n"); - fprintf(logfile," hyper time = %g\n",t_hyper); - fprintf(logfile," event timesteps = %d\n",nevent_running); - fprintf(logfile," # of atoms in events = %d\n",nevent_atoms_running); - fprintf(logfile,"Quantities for this hyper run:\n"); - fprintf(logfile," event timesteps = %d\n",nevent); - fprintf(logfile," # of atoms in events = %d\n",nevent_atoms); - fprintf(logfile," max length of any bond = %g\n",maxbondlen); - fprintf(logfile," max drift distance of any atom = %g\n",maxdrift); - fprintf(logfile," fraction of steps & bonds with zero bias = %g\n", - fraczero); - fprintf(logfile,"Current quantities:\n"); - fprintf(logfile," ave bonds/atom = %g\n",avebonds); - - if (hyperstyle == LOCAL) { - fprintf(logfile,"Cummulative quantities specific tofix hyper/local:\n"); - fprintf(logfile," # of new bonds formed = %g\n",nnewbond); - fprintf(logfile," max bonds/atom = %g\n",maxbondperatom); - fprintf(logfile,"Quantities for this hyper run specific to " - "fix hyper/local:\n"); - fprintf(logfile," ave boosted bonds/step = %g\n",avenboost); - fprintf(logfile," ave boost coeff of all bonds = %g\n",aveboostcoeff); - fprintf(logfile," max boost coeff of any bond = %g\n",maxboostcoeff); - fprintf(logfile," min boost coeff of any bond = %g\n",minboostcoeff); - fprintf(logfile," max dist from my box of any " - "non-maxstrain bond ghost atom = %g\n",rmaxever); - fprintf(logfile," max dist from my box of any bond ghost atom = %g\n", - rmaxeverbig); - fprintf(logfile," count of ghost bond neighbors " - "not found on reneighbor steps = %g\n",allghost_toofar); - fprintf(logfile," lost bond partners = %g\n",lostbond); - fprintf(logfile," ave bias coeff for lost bond partners = %g\n", - lostbondcoeff); - fprintf(logfile," bias overlaps = %g\n",biasoverlap); - fprintf(logfile," non-matching bias coeffs = %g\n",nonmatchbiascoeff); - fprintf(logfile," CPU time for bond builds = %g\n",tbondbuild); - fprintf(logfile,"Current quantities specific to fix hyper/local:\n"); - fprintf(logfile," neighbor bonds/bond = %g\n",neighbondperbond); - fprintf(logfile," ave boost coeff for all bonds = %g\n",aveboostnow); - } - fprintf(logfile,"\n"); + fprintf(out,"\n"); } } diff --git a/src/fix_ave_histo.cpp b/src/fix_ave_histo.cpp index a5bf8db557..d60fe7af14 100644 --- a/src/fix_ave_histo.cpp +++ b/src/fix_ave_histo.cpp @@ -32,7 +32,7 @@ using namespace FixConst; enum{X,V,F,COMPUTE,FIX,VARIABLE}; enum{ONE,RUNNING}; enum{SCALAR,VECTOR,WINDOW}; -enum{GLOBAL,PERATOM,LOCAL}; +enum{DEFAULT,GLOBAL,PERATOM,LOCAL}; enum{IGNORE,END,EXTRA}; #define INVOKED_SCALAR 1 @@ -46,8 +46,10 @@ enum{IGNORE,END,EXTRA}; FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), - nvalues(0), which(NULL), argindex(NULL), value2index(NULL), ids(NULL), fp(NULL), stats_list(NULL), - bin(NULL), bin_total(NULL), bin_all(NULL), bin_list(NULL), coord(NULL), vector(NULL) + nvalues(0), which(NULL), argindex(NULL), value2index(NULL), + ids(NULL), fp(NULL), stats_list(NULL), + bin(NULL), bin_total(NULL), bin_all(NULL), bin_list(NULL), + coord(NULL), vector(NULL) { if (narg < 10) error->all(FLERR,"Illegal fix ave/histo command"); @@ -188,9 +190,8 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : memory->sfree(earg); } - // setup and error check - // kind = inputs are all global, or all per-atom, or all local - // for fix inputs, check that fix frequency is acceptable + // check input args for kind consistency + // all inputs must all be global, per-atom, or local if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0) error->all(FLERR,"Illegal fix ave/histo command"); @@ -201,40 +202,65 @@ FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) : if (ave != RUNNING && overwrite) error->all(FLERR,"Illegal fix ave/histo command"); - int kindflag; + int kindglobal,kindperatom,kindlocal; + for (int i = 0; i < nvalues; i++) { - if (which[i] == X || which[i] == V || which[i] == F) kindflag = PERATOM; - else if (which[i] == COMPUTE) { + kindglobal = kindperatom = kindlocal = 0; + + if (which[i] == X || which[i] == V || which[i] == F) { + kindperatom = 1; + + } else if (which[i] == COMPUTE) { int c_id = modify->find_compute(ids[i]); if (c_id < 0) error->all(FLERR,"Fix ave/histo input is invalid compute"); Compute *compute = modify->compute[c_id]; + // computes can produce multiple kinds of output if (compute->scalar_flag || compute->vector_flag || compute->array_flag) - kindflag = GLOBAL; - else if (compute->peratom_flag) kindflag = PERATOM; - else if (compute->local_flag) kindflag = LOCAL; - else error->all(FLERR,"Fix ave/histo input is invalid compute"); + kindglobal = 1; + if (compute->peratom_flag) kindperatom = 1; + if (compute->local_flag) kindlocal = 1; + } else if (which[i] == FIX) { int f_id = modify->find_fix(ids[i]); if (f_id < 0) error->all(FLERR,"Fix ave/histo input is invalid fix"); Fix *fix = modify->fix[f_id]; + // fixes can produce multiple kinds of output 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(FLERR,"Fix ave/histo input is invalid fix"); + kindglobal = 1; + if (fix->peratom_flag) kindperatom = 1; + if (fix->local_flag) kindlocal = 1; + } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); - if (ivariable < 0) error->all(FLERR,"Fix ave/histo input is invalid variable"); - if (input->variable->equalstyle(ivariable)) kindflag = GLOBAL; - else if (input->variable->atomstyle(ivariable)) kindflag = PERATOM; - else error->all(FLERR,"Fix ave/histo input is invalid variable"); + if (ivariable < 0) + error->all(FLERR,"Fix ave/histo input is invalid variable"); + // variables only produce one kind of output + if (input->variable->equalstyle(ivariable)) kindglobal = 1; + else if (input->variable->atomstyle(ivariable)) kindperatom = 1; + else error->all(FLERR,"Fix ave/histo input is invalid kind of variable"); + } + + if (kind == DEFAULT) { + if (kindglobal + kindperatom + kindlocal > 1) + error->all(FLERR,"Fix ave/histo input kind is ambiguous"); + if (kindglobal) kind = GLOBAL; + if (kindperatom) kind = PERATOM; + if (kindlocal) kind = LOCAL; + } else if (kind == GLOBAL) { + if (!kindglobal) + error->all(FLERR,"Fix ave/histo input kind is invalid"); + } else if (kind == PERATOM) { + if (!kindperatom) + error->all(FLERR,"Fix ave/histo input kind is invalid"); + } else if (kind == LOCAL) { + if (!kindlocal) + error->all(FLERR,"Fix ave/histo input kind is invalid"); } - if (i == 0) kind = kindflag; - else if (kindflag != kind) - error->all(FLERR, - "Fix ave/histo inputs are not all global, peratom, or local"); } + // more error checks + // for fix inputs, check that fix frequency is acceptable + if (kind == PERATOM && mode == SCALAR) error->all(FLERR, "Fix ave/histo cannot input per-atom values in scalar mode"); @@ -919,6 +945,7 @@ void FixAveHisto::options(int iarg, int narg, char **arg) // option defaults fp = NULL; + kind = DEFAULT; ave = ONE; startstep = 0; mode = SCALAR; @@ -942,6 +969,13 @@ void FixAveHisto::options(int iarg, int narg, char **arg) } } iarg += 2; + } else if (strcmp(arg[iarg],"kind") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); + if (strcmp(arg[iarg+1],"global") == 0) kind = GLOBAL; + else if (strcmp(arg[iarg+1],"peratom") == 0) kind = PERATOM; + else if (strcmp(arg[iarg+1],"local") == 0) kind = LOCAL; + else error->all(FLERR,"Illegal fix ave/histo command"); + iarg += 2; } else if (strcmp(arg[iarg],"ave") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix ave/histo command"); if (strcmp(arg[iarg+1],"one") == 0) ave = ONE; diff --git a/src/thermo.cpp b/src/thermo.cpp index ddbbd0f496..3e777edf82 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -380,9 +380,8 @@ void Thermo::compute(int flag) loc += sprintf(&line[loc],format[ifield],dvalue); else if (vtype[ifield] == INT) loc += sprintf(&line[loc],format[ifield],ivalue); - else if (vtype[ifield] == BIGINT) { + else if (vtype[ifield] == BIGINT) loc += sprintf(&line[loc],format[ifield],bivalue); - } } // print line to screen and logfile -- GitLab From edd4b0cf2548c6ddc5b3ad08a7141c4f5a016606 Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 4 Mar 2019 07:35:02 -0700 Subject: [PATCH 0189/1243] Commit JT 030419 - added minspin - modifs before co --- examples/SPIN/gneb_bfo/in.neb.spin_iron | 11 +- examples/SPIN/gneb_bfo/in.neb.spin_iron_min | 42 ++ examples/SPIN/gneb_bfo/in.spin.dyna_iron | 53 +++ src/REPLICA/fix_neb_spin.cpp | 285 ++++++------- src/REPLICA/fix_neb_spin.h | 4 +- src/REPLICA/neb_spin.cpp | 45 +- src/SPIN/min_spinmin.cpp | 428 ++++++++++++++++++++ src/SPIN/min_spinmin.h | 56 +++ 8 files changed, 772 insertions(+), 152 deletions(-) create mode 100644 examples/SPIN/gneb_bfo/in.neb.spin_iron_min create mode 100644 examples/SPIN/gneb_bfo/in.spin.dyna_iron create mode 100644 src/SPIN/min_spinmin.cpp create mode 100644 src/SPIN/min_spinmin.h diff --git a/examples/SPIN/gneb_bfo/in.neb.spin_iron b/examples/SPIN/gneb_bfo/in.neb.spin_iron index 2cf3a8653e..860db24a61 100644 --- a/examples/SPIN/gneb_bfo/in.neb.spin_iron +++ b/examples/SPIN/gneb_bfo/in.neb.spin_iron @@ -29,12 +29,15 @@ neighbor 0.1 bin neigh_modify every 10 check yes delay 20 fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 -#fix 2 all langevin/spin 0.0 0.0 21 -fix 2 all neb/spin 1.0 +fix 2 all langevin/spin 0.1 0.0 21 +fix 3 all neb/spin 1.0 +#fix 4 all nve/spin lattice no #parallel ideal timestep 0.0001 +thermo 100 -#min_style quickmin -neb/spin 0.0 0.1 1 1 1 final ../examples/SPIN/gneb_bfo/final.iron_spin + +min_style spinmin +neb/spin 0.0 0.1 100 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin #neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.neb.spin_iron_min b/examples/SPIN/gneb_bfo/in.neb.spin_iron_min new file mode 100644 index 0000000000..a38a8fbde5 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.neb.spin_iron_min @@ -0,0 +1,42 @@ +# bcc iron in a 3d periodic box + +units metal +dimension 3 +boundary p p f + +atom_style spin + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice bcc 2.8665 +region box block 0.0 4.0 0.0 4.0 0.0 1.0 +#create_box 1 box +#create_atoms 1 box + +read_data ../examples/SPIN/gneb_bfo/initial.iron_spin + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 55.845 +#set group all spin 2.2 -1.0 0.0 0.0 + +pair_style spin/exchange 3.5 +pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 +fix 2 all langevin/spin 0.1 0.0 21 +fix 3 all neb/spin 1.0 +fix 4 all nve/spin lattice no +#parallel ideal + +timestep 0.0001 +thermo 100 + + +min_style spinmin +neb/spin 0.0 0.1 10 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin +#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spin.dyna_iron b/examples/SPIN/gneb_bfo/in.spin.dyna_iron new file mode 100644 index 0000000000..918819c816 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.spin.dyna_iron @@ -0,0 +1,53 @@ +# bcc iron in a 3d periodic box + +clear +units metal +atom_style spin + +dimension 3 +boundary f f f + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice bcc 2.8665 +region box block 0.0 4.0 0.0 4.0 0.0 1.0 +create_box 1 box +create_atoms 1 box + +#read_data ../examples/SPIN/gneb_bfo/initial.iron_spin + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 55.845 +set group all spin 2.2 -1.0 0.0 0.0 + +pair_style spin/exchange 3.5 +pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 +fix 2 all langevin/spin 300.0 0.01 21 +#fix 3 all neb/spin 1.0 +fix 3 all nve/spin lattice no +timestep 0.0001 + +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magx equal c_out_mag[1] +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo_style custom step time v_magx v_magnorm v_tmag temp v_emag ke pe etotal +thermo 100 + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] +run 10000 diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index 150c37a03e..42450c2f0f 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -334,6 +334,9 @@ void FixNEB_spin::min_post_force(int /*vflag*/) MPI_Bcast(&vnext,1,MPI_DOUBLE,0,world); } + //printf("test veng: %g / %g / %g \n",veng,vprev,vnext); + //error->universe_all(FLERR,"End test"); + if (FreeEndFinal && ireplica == nreplica-1 && (update->ntimestep == 0)) EFinalIni = veng; if (ireplica == 0) vIni=veng; @@ -391,7 +394,6 @@ void FixNEB_spin::min_post_force(int /*vflag*/) dotgrad = gradlen = dotpath = dottangrad = 0.0; - // computation of the tangent vector // final replica @@ -401,11 +403,13 @@ void FixNEB_spin::min_post_force(int /*vflag*/) if (mask[i] & groupbit) { // tangent vector + delspxp = sp[i][0] - spprev[i][0]; delspyp = sp[i][1] - spprev[i][1]; delspzp = sp[i][2] - spprev[i][2]; // project delp vector on tangent space + delpdots = delspxp*sp[i][0]+delspyp*sp[i][1]+delspzp*sp[i][2]; delspxp -= delpdots*sp[i][0]; delspyp -= delpdots*sp[i][1]; @@ -415,6 +419,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) //domain->minimum_image(delspxp,delspyp,delspzp); // calc. geodesic length + spi[0]=sp[i][0]; spi[1]=sp[i][1]; spi[2]=sp[i][2]; @@ -470,11 +475,13 @@ void FixNEB_spin::min_post_force(int /*vflag*/) if (mask[i] & groupbit) { // tangent vector + delspxn = spnext[i][0]- sp[i][0]; delspyn = spnext[i][1]- sp[i][1]; delspzn = spnext[i][2]- sp[i][2]; // project deln vector on tangent space + delndots = delspxn*sp[i][0]+delspyn*sp[i][1]+delspzn*sp[i][2]; delspxn -= delndots*sp[i][0]; delspyn -= delndots*sp[i][1]; @@ -484,6 +491,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) //domain->minimum_image(delspxn,delspyn,delspzn); // calc. geodesic length + spi[0]=sp[i][0]; spi[1]=sp[i][1]; spi[2]=sp[i][2]; @@ -492,7 +500,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) spj[2]=spnext[i][2]; templen = geodesic_distance(spi, spj); nlen += templen*templen; - dottangrad += delspxn*fm[i][0] + delspyn*fm[i][1] + delspzp*fm[i][2]; + dottangrad += delspxn*fm[i][0] + delspyn*fm[i][1] + delspzn*fm[i][2]; gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; if (FreeEndIni) { error->all(FLERR,"Free End option not yet active"); @@ -817,18 +825,19 @@ double FixNEB_spin::geodesic_distance(double spi[3], double spj[3]) double dist; double crossx,crossy,crossz; double dotx,doty,dotz; - double crosslen,dots; + double normcross,dots; crossx = spi[1]*spj[2]-spi[2]*spj[1]; crossy = spi[2]*spj[0]-spi[0]*spj[2]; crossz = spi[0]*spj[1]-spi[1]*spj[0]; - crosslen = sqrt(crossx*crossx + crossy*crossy + crossz*crossz); + normcross = sqrt(crossx*crossx + crossy*crossy + crossz*crossz); + dotx = spi[0]*spj[0]; doty = spi[1]*spj[1]; dotz = spi[2]*spj[2]; dots = dotx+doty+dotz; - dist = atan2(crosslen,dots); + dist = atan2(normcross,dots); return dist; } @@ -837,144 +846,144 @@ double FixNEB_spin::geodesic_distance(double spi[3], double spj[3]) geometric damped advance os spins ---------------------------------------------------------------------- */ -void FixNEB_spin::advance_spins(double dts) -{ - //int j=0; - //int *sametag = atom->sametag; - int nlocal = atom->nlocal; - int *mask = atom->mask; - double **sp = atom->sp; - double **fm = atom->fm; - double tdampx,tdampy,tdampz; - double msq,scale,fm2,energy,dts2; - double alpha; - double spi[3],fmi[3]; - double cp[3],g[3]; - - //cp[0] = cp[1] = cp[2] = 0.0; - //g[0] = g[1] = g[2] = 0.0; - dts2 = dts*dts; - - // fictitious Gilbert damping of 1 - alpha = 1.0; - - // loop on all spins on proc. - - if (ireplica != nreplica-1 && ireplica != 0) - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - - spi[0] = sp[i][0]; - spi[1] = sp[i][1]; - spi[2] = sp[i][2]; - - fmi[0] = fm[i][0]; - fmi[1] = fm[i][1]; - fmi[2] = fm[i][2]; - - // calc. damping torque - - tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); - tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); - tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); - - // apply advance algorithm (geometric, norm preserving) - - fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); - energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); - - cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; - cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; - cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; - - g[0] = sp[i][0]+cp[0]*dts; - g[1] = sp[i][1]+cp[1]*dts; - g[2] = sp[i][2]+cp[2]*dts; - - g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; - g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; - g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; - - g[0] /= (1+0.25*fm2*dts2); - g[1] /= (1+0.25*fm2*dts2); - g[2] /= (1+0.25*fm2*dts2); - - sp[i][0] = g[0]; - sp[i][1] = g[1]; - sp[i][2] = g[2]; - - // renormalization (check if necessary) - - msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; - scale = 1.0/sqrt(msq); - sp[i][0] *= scale; - sp[i][1] *= scale; - sp[i][2] *= scale; - - // comm. sp[i] to atoms with same tag (for serial algo) - - // no need for simplecticity - //if (sector_flag == 0) { - // if (sametag[i] >= 0) { - // j = sametag[i]; - // while (j >= 0) { - // sp[j][0] = sp[i][0]; - // sp[j][1] = sp[i][1]; - // sp[j][2] = sp[i][2]; - // j = sametag[j]; - // } - // } - //} - // - - } -} +//void FixNEB_spin::advance_spins(double dts) +//{ +// //int j=0; +// //int *sametag = atom->sametag; +// int nlocal = atom->nlocal; +// int *mask = atom->mask; +// double **sp = atom->sp; +// double **fm = atom->fm; +// double tdampx,tdampy,tdampz; +// double msq,scale,fm2,energy,dts2; +// double alpha; +// double spi[3],fmi[3]; +// double cp[3],g[3]; +// +// //cp[0] = cp[1] = cp[2] = 0.0; +// //g[0] = g[1] = g[2] = 0.0; +// dts2 = dts*dts; +// +// // fictitious Gilbert damping of 1 +// alpha = 1.0; +// +// // loop on all spins on proc. +// +// if (ireplica != nreplica-1 && ireplica != 0) +// for (int i = 0; i < nlocal; i++) +// if (mask[i] & groupbit) { +// +// spi[0] = sp[i][0]; +// spi[1] = sp[i][1]; +// spi[2] = sp[i][2]; +// +// fmi[0] = fm[i][0]; +// fmi[1] = fm[i][1]; +// fmi[2] = fm[i][2]; +// +// // calc. damping torque +// +// tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); +// tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); +// tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); +// +// // apply advance algorithm (geometric, norm preserving) +// +// fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); +// energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); +// +// cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; +// cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; +// cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; +// +// g[0] = sp[i][0]+cp[0]*dts; +// g[1] = sp[i][1]+cp[1]*dts; +// g[2] = sp[i][2]+cp[2]*dts; +// +// g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; +// g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; +// g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; +// +// g[0] /= (1+0.25*fm2*dts2); +// g[1] /= (1+0.25*fm2*dts2); +// g[2] /= (1+0.25*fm2*dts2); +// +// sp[i][0] = g[0]; +// sp[i][1] = g[1]; +// sp[i][2] = g[2]; +// +// // renormalization (check if necessary) +// +// msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; +// scale = 1.0/sqrt(msq); +// sp[i][0] *= scale; +// sp[i][1] *= scale; +// sp[i][2] *= scale; +// +// // comm. sp[i] to atoms with same tag (for serial algo) +// +// // no need for simplecticity +// //if (sector_flag == 0) { +// // if (sametag[i] >= 0) { +// // j = sametag[i]; +// // while (j >= 0) { +// // sp[j][0] = sp[i][0]; +// // sp[j][1] = sp[i][1]; +// // sp[j][2] = sp[i][2]; +// // j = sametag[j]; +// // } +// // } +// //} +// // +// +// } +//} /* ---------------------------------------------------------------------- evaluate max timestep ---------------------------------------------------------------------- */ -double FixNEB_spin::evaluate_dt() -{ - double dtmax; - double fmsq; - double fmaxsqone,fmaxsqloc,fmaxsqall; - int nlocal = atom->nlocal; - int *mask = atom->mask; - double **fm = atom->fm; - - // finding max fm on this proc. - - fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { - fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; - fmaxsqone = MAX(fmaxsqone,fmsq); - } - - // finding max fm on this replica - - fmaxsqloc = fmaxsqone; - MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); - - // finding max fm over all replicas, if necessary - // this communicator would be invalid for multiprocess replicas - - if (update->multireplica == 1) { - fmaxsqall = fmaxsqloc; - MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); - } - - if (fmaxsqall < fmaxsqloc) - error->all(FLERR,"Incorrect fmaxall calc."); - - // define max timestep - // dividing by 10 the inverse of max frequency - - dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); - - return dtmax; -} +//double FixNEB_spin::evaluate_dt() +//{ +// double dtmax; +// double fmsq; +// double fmaxsqone,fmaxsqloc,fmaxsqall; +// int nlocal = atom->nlocal; +// int *mask = atom->mask; +// double **fm = atom->fm; +// +// // finding max fm on this proc. +// +// fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; +// for (int i = 0; i < nlocal; i++) +// if (mask[i] & groupbit) { +// fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; +// fmaxsqone = MAX(fmaxsqone,fmsq); +// } +// +// // finding max fm on this replica +// +// fmaxsqloc = fmaxsqone; +// MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); +// +// // finding max fm over all replicas, if necessary +// // this communicator would be invalid for multiprocess replicas +// +// if (update->multireplica == 1) { +// fmaxsqall = fmaxsqloc; +// MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); +// } +// +// if (fmaxsqall < fmaxsqloc) +// error->all(FLERR,"Incorrect fmaxall calc."); +// +// // define max timestep +// // dividing by 10 the inverse of max frequency +// +// dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); +// +// return dtmax; +//} /* ---------------------------------------------------------------------- send/recv NEB atoms to/from adjacent replicas diff --git a/src/REPLICA/fix_neb_spin.h b/src/REPLICA/fix_neb_spin.h index 291341860e..c70f35ae2d 100644 --- a/src/REPLICA/fix_neb_spin.h +++ b/src/REPLICA/fix_neb_spin.h @@ -36,8 +36,8 @@ class FixNEB_spin : public Fix { void init(); void min_setup(int); void min_post_force(int); - void advance_spins(double); - double evaluate_dt(); + //void advance_spins(double); + //double evaluate_dt(); private: int me,nprocs,nprocs_universe; diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index 8780cb9a0a..6249797e95 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -24,6 +24,7 @@ // test spin #include "neb_spin.h" #include "compute.h" +#include "force.h" #include "universe.h" #include "atom.h" @@ -262,6 +263,8 @@ void NEB_spin::run() // setup regular NEB_spin minimization FILE *uscreen = universe->uscreen; FILE *ulogfile = universe->ulogfile; + + //printf("test before run 1 \n"); if (me_universe == 0 && uscreen) fprintf(uscreen,"Setting up regular NEB_spin ...\n"); @@ -272,8 +275,12 @@ void NEB_spin::run() update->max_eval = n1steps; if (update->laststep < 0) error->all(FLERR,"Too many timesteps for NEB_spin"); + + //printf("test before run 2 \n"); update->minimize->setup(); + + //printf("test before run 3 \n"); if (me_universe == 0) { if (uscreen) { @@ -304,7 +311,9 @@ void NEB_spin::run() } } } + //printf("test before run 4 \n"); print_status(); + //printf("test before run 5 \n"); // perform regular NEB_spin for n1steps or until replicas converge // retrieve PE values from fix NEB_spin and print every nevery iterations @@ -314,13 +323,23 @@ void NEB_spin::run() timer->init(); timer->barrier_start(); + // test import fix_nve scheme + + //printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //error->all(FLERR,"end neb_spin test"); double dts; while (update->minimize->niter < n1steps) { //dts = evaluate_dt(); //advance_spins(dts); - dts = fneb->evaluate_dt(); - fneb->advance_spins(dts); + //fneb-> + //dts = fneb->evaluate_dt(); + //fneb->advance_spins(dts); + + // no minimizer for spins + update->minimize->run(nevery); + + // no minimizer for spins //update->minimize->run(nevery); // @@ -331,6 +350,9 @@ void NEB_spin::run() if (update->minimize->stop_condition) break; } + // test neb end + //error->all(FLERR,"end neb_spin test"); + timer->barrier_stop(); update->minimize->cleanup(); @@ -371,8 +393,11 @@ void NEB_spin::run() update->minimize->init(); fneb->rclimber = top; + printf("test print 6.2 \n"); update->minimize->setup(); + printf("test print 6.3 \n"); + if (me_universe == 0) { if (uscreen) { if (verbose) { @@ -418,9 +443,9 @@ void NEB_spin::run() while (update->minimize->niter < n2steps) { //dts = evaluate_dt(); //advance_spins(dts); - dts = fneb->evaluate_dt(); - fneb->advance_spins(dts); - //update->minimize->run(nevery); + //dts = fneb->evaluate_dt(); + //fneb->advance_spins(dts); + update->minimize->run(nevery); print_status(); if (update->minimize->stop_condition) break; } @@ -995,9 +1020,13 @@ void NEB_spin::print_status() double fmaxreplica; MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); - double fnorminf = update->minimize->fnorm_inf(); - double fmaxatom; - MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots); + + // no minimize->fnorm_inf for spins + //double fnorminf = update->minimize->fnorm_inf(); + //double fmaxatom; + //MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots); + double fnorminf = 0.0; + double fmaxatom = 0.0; if (verbose) { freplica = new double[nreplica]; diff --git a/src/SPIN/min_spinmin.cpp b/src/SPIN/min_spinmin.cpp new file mode 100644 index 0000000000..08f91abae7 --- /dev/null +++ b/src/SPIN/min_spinmin.cpp @@ -0,0 +1,428 @@ +/* ---------------------------------------------------------------------- + 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 +#include +#include "min_spinmin.h" +#include "universe.h" +#include "atom.h" +#include "force.h" +#include "update.h" +#include "output.h" +#include "timer.h" +#include "error.h" + +#include +#include +#include "modify.h" +#include "math_special.h" +#include "math_const.h" +#include "fix_neb_spin.h" + +using namespace LAMMPS_NS; +using namespace MathConst; + +// EPS_ENERGY = minimum normalization for energy tolerance + +#define EPS_ENERGY 1.0e-8 + +#define DELAYSTEP 5 + +/* ---------------------------------------------------------------------- */ + +MinSpinMin::MinSpinMin(LAMMPS *lmp) : Min(lmp) {} + +/* ---------------------------------------------------------------------- */ + +void MinSpinMin::init() +{ + Min::init(); + + dt = update->dt; + last_negative = update->ntimestep; + + // test dts + dts = dt; + +} + +/* ---------------------------------------------------------------------- */ + +void MinSpinMin::setup_style() +{ + double **v = atom->v; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) + v[i][0] = v[i][1] = v[i][2] = 0.0; +} + +/* ---------------------------------------------------------------------- + set current vector lengths and pointers + called after atoms have migrated +------------------------------------------------------------------------- */ + +void MinSpinMin::reset_vectors() +{ + // atomic dof + + // not really good size => sp is 4N vector + nvec = 4 * atom->nlocal; + if (nvec) spvec = atom->sp[0]; + + nvec = 3 * atom->nlocal; + if (nvec) fmvec = atom->fm[0]; + + if (nvec) xvec = atom->x[0]; + if (nvec) fvec = atom->f[0]; +} + +/* ---------------------------------------------------------------------- + minimization via QuickMin damped dynamics +------------------------------------------------------------------------- */ + +int MinSpinMin::iterate(int maxiter) +{ + bigint ntimestep; + //double vmax,vdotf,vdotfall,fdotf,fdotfall,scale; + //double dtvone,dtv,dtf,dtfm; + //int flag,flagall; + + //alpha_final = 0.0; + + // search for and allocate neb_spin fix + + //int ineb; + //for (ineb = 0; ineb < modify->nfix; ineb++) + // if (strcmp(modify->fix[ineb]->style,"neb/spin") == 0) break; + //if (ineb == modify->nfix) error->all(FLERR,"spinmin requires use of fix neb/spin"); + //fneb = (FixNEB_spin *) modify->fix[ineb]; + + for (int iter = 0; iter < maxiter; iter++) { + + if (timer->check_timeout(niter)) + return TIMEOUT; + + ntimestep = ++update->ntimestep; + niter++; + + // optimize timestep accross processes / replicas + + //dts = fneb->evaluate_dt(); + dts = evaluate_dt(); + + // apply damped precessional dynamics to the spins + + //fneb->advance_spins(dts); + advance_spins(dts); + + + //// zero velocity if anti-parallel to force + //// else project velocity in direction of force + + //double **v = atom->v; + //double **f = atom->f; + //int nlocal = atom->nlocal; + + //vdotf = 0.0; + //for (int i = 0; i < nlocal; i++) + // vdotf += v[i][0]*f[i][0] + v[i][1]*f[i][1] + v[i][2]*f[i][2]; + //MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,world); + + // sum vdotf over replicas, if necessary + // this communicator would be invalid for multiprocess replicas + + //if (update->multireplica == 1) { + // vdotf = vdotfall; + // MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld); + //} + + //if (vdotfall < 0.0) { + // last_negative = ntimestep; + // for (int i = 0; i < nlocal; i++) + // v[i][0] = v[i][1] = v[i][2] = 0.0; + + //} else { + // fdotf = 0.0; + // for (int i = 0; i < nlocal; i++) + // fdotf += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; + // MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,world); + + // // sum fdotf over replicas, if necessary + // // this communicator would be invalid for multiprocess replicas + + // if (update->multireplica == 1) { + // fdotf = fdotfall; + // MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld); + // } + + // if (fdotfall == 0.0) scale = 0.0; + // else scale = vdotfall/fdotfall; + // for (int i = 0; i < nlocal; i++) { + // v[i][0] = scale * f[i][0]; + // v[i][1] = scale * f[i][1]; + // v[i][2] = scale * f[i][2]; + // } + //} + + //// limit timestep so no particle moves further than dmax + + //double *rmass = atom->rmass; + //double *mass = atom->mass; + //int *type = atom->type; + + //dtvone = dt; + + //for (int i = 0; i < nlocal; i++) { + // vmax = MAX(fabs(v[i][0]),fabs(v[i][1])); + // vmax = MAX(vmax,fabs(v[i][2])); + // if (dtvone*vmax > dmax) dtvone = dmax/vmax; + //} + //MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,world); + + //// min dtv over replicas, if necessary + //// this communicator would be invalid for multiprocess replicas + + //if (update->multireplica == 1) { + // dtvone = dtv; + // MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,universe->uworld); + //} + + //dtf = dtv * force->ftm2v; + + //// Euler integration step + + //double **x = atom->x; + + //if (rmass) { + // for (int i = 0; i < nlocal; i++) { + // dtfm = dtf / rmass[i]; + // x[i][0] += dtv * v[i][0]; + // x[i][1] += dtv * v[i][1]; + // x[i][2] += dtv * v[i][2]; + // v[i][0] += dtfm * f[i][0]; + // v[i][1] += dtfm * f[i][1]; + // v[i][2] += dtfm * f[i][2]; + // } + //} else { + // for (int i = 0; i < nlocal; i++) { + // dtfm = dtf / mass[type[i]]; + // x[i][0] += dtv * v[i][0]; + // x[i][1] += dtv * v[i][1]; + // x[i][2] += dtv * v[i][2]; + // v[i][0] += dtfm * f[i][0]; + // v[i][1] += dtfm * f[i][1]; + // v[i][2] += dtfm * f[i][2]; + // } + //} + + //eprevious = ecurrent; + //ecurrent = energy_force(0); + //neval++; + + //// energy tolerance criterion + //// only check after DELAYSTEP elapsed since velocties reset to 0 + //// sync across replicas if running multi-replica minimization + + //if (update->etol > 0.0 && ntimestep-last_negative > DELAYSTEP) { + // if (update->multireplica == 0) { + // if (fabs(ecurrent-eprevious) < + // update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + // return ETOL; + // } else { + // if (fabs(ecurrent-eprevious) < + // update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + // flag = 0; + // else flag = 1; + // MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + // if (flagall == 0) return ETOL; + // } + //} + + //// force tolerance criterion + //// sync across replicas if running multi-replica minimization + + //if (update->ftol > 0.0) { + // fdotf = fnorm_sqr(); + // if (update->multireplica == 0) { + // if (fdotf < update->ftol*update->ftol) return FTOL; + // } else { + // if (fdotf < update->ftol*update->ftol) flag = 0; + // else flag = 1; + // MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + // if (flagall == 0) return FTOL; + // } + //} + + //// output for thermo, dump, restart files + + //if (output->next == ntimestep) { + // timer->stamp(); + // output->write(ntimestep); + // timer->stamp(Timer::OUTPUT); + //} + } + + return MAXITER; +} + +/* ---------------------------------------------------------------------- + evaluate max timestep +---------------------------------------------------------------------- */ + +double MinSpinMin::evaluate_dt() +{ + double dtmax; + double fmsq; + double fmaxsqone,fmaxsqloc,fmaxsqall; + int nlocal = atom->nlocal; + int *mask = atom->mask; + double **fm = atom->fm; + + // finding max fm on this proc. + + fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; + for (int i = 0; i < nlocal; i++) { + fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; + fmaxsqone = MAX(fmaxsqone,fmsq); + } + //for (int i = 0; i < nlocal; i++) + // if (mask[i] & groupbit) { + // fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; + // fmaxsqone = MAX(fmaxsqone,fmsq); + // } + + // finding max fm on this replica + + fmaxsqloc = fmaxsqone; + MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); + + // finding max fm over all replicas, if necessary + // this communicator would be invalid for multiprocess replicas + + if (update->multireplica == 1) { + fmaxsqall = fmaxsqloc; + MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); + } + + if (fmaxsqall < fmaxsqloc) + error->all(FLERR,"Incorrect fmaxall calc."); + + // define max timestep + // dividing by 10 the inverse of max frequency + + dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); + + return dtmax; +} + +/* ---------------------------------------------------------------------- + geometric damped advance of spins +---------------------------------------------------------------------- */ + +void MinSpinMin::advance_spins(double dts) +{ + //int j=0; + //int *sametag = atom->sametag; + int nlocal = atom->nlocal; + int *mask = atom->mask; + double **sp = atom->sp; + double **fm = atom->fm; + double tdampx,tdampy,tdampz; + double msq,scale,fm2,energy,dts2; + double alpha; + double spi[3],fmi[3]; + double cp[3],g[3]; + + //cp[0] = cp[1] = cp[2] = 0.0; + //g[0] = g[1] = g[2] = 0.0; + dts2 = dts*dts; + + // fictitious Gilbert damping of 1 + alpha = 1.0; + + // loop on all spins on proc. + + //if (ireplica != nreplica-1 && ireplica != 0) + // for (int i = 0; i < nlocal; i++) + // if (mask[i] & groupbit) { + for (int i = 0; i < nlocal; i++) { + + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + + fmi[0] = fm[i][0]; + fmi[1] = fm[i][1]; + fmi[2] = fm[i][2]; + + // calc. damping torque + + tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); + tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); + tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); + + // apply advance algorithm (geometric, norm preserving) + + fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); + energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); + + cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; + cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; + cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; + + g[0] = sp[i][0]+cp[0]*dts; + g[1] = sp[i][1]+cp[1]*dts; + g[2] = sp[i][2]+cp[2]*dts; + + g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; + g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; + g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; + + g[0] /= (1+0.25*fm2*dts2); + g[1] /= (1+0.25*fm2*dts2); + g[2] /= (1+0.25*fm2*dts2); + + sp[i][0] = g[0]; + sp[i][1] = g[1]; + sp[i][2] = g[2]; + + // renormalization (check if necessary) + + msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; + scale = 1.0/sqrt(msq); + sp[i][0] *= scale; + sp[i][1] *= scale; + sp[i][2] *= scale; + + // comm. sp[i] to atoms with same tag (for serial algo) + + // no need for simplecticity + //if (sector_flag == 0) { + // if (sametag[i] >= 0) { + // j = sametag[i]; + // while (j >= 0) { + // sp[j][0] = sp[i][0]; + // sp[j][1] = sp[i][1]; + // sp[j][2] = sp[i][2]; + // j = sametag[j]; + // } + // } + //} + // + } + + printf("test inside spinmin, dts = %g \n",dts); + printf("test inside spinmin, fmi i=%d, %g %g %g \n",1,fm[1][0],fm[1][1],fm[1][2]); + printf("test inside spinmin, spi i=%d, %g %g %g \n",1,sp[1][0],sp[1][1],sp[1][2]); +} diff --git a/src/SPIN/min_spinmin.h b/src/SPIN/min_spinmin.h new file mode 100644 index 0000000000..fe2cf7c51d --- /dev/null +++ b/src/SPIN/min_spinmin.h @@ -0,0 +1,56 @@ +/* -*- 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 MINIMIZE_CLASS + +MinimizeStyle(spinmin,MinSpinMin) + +#else + +#ifndef LMP_MIN_SPINMIN_H +#define LMP_MIN_SPINMIN_H + +#include "min.h" + +namespace LAMMPS_NS { + +class MinSpinMin : public Min { + public: + MinSpinMin(class LAMMPS *); + ~MinSpinMin() {} + void init(); + void setup_style(); + void reset_vectors(); + int iterate(int); + double evaluate_dt(); + void advance_spins(double); + + class FixNEB_spin *fneb; + + private: + + // spin timestep + double dts; + + double *spvec; // variables for atomic dof, as 1d vector + double *fmvec; // variables for atomic dof, as 1d vector + + + double dt; + bigint last_negative; +}; + +} + +#endif +#endif -- GitLab From ab0c35be9357d36f3d0600206679753fb14a86ae Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 4 Mar 2019 08:04:11 -0700 Subject: [PATCH 0190/1243] Commit JT 030419 - correction of pair_spin calculations - corrects an error between i and ii lists in single/pair calc. --- src/SPIN/pair_spin_dmi.cpp | 88 +++++++++++++++++++----------- src/SPIN/pair_spin_exchange.cpp | 78 +++++++++++++++++---------- src/SPIN/pair_spin_magelec.cpp | 58 +++++++++++++------- src/SPIN/pair_spin_neel.cpp | 94 +++++++++++++++++++++------------ 4 files changed, 206 insertions(+), 112 deletions(-) diff --git a/src/SPIN/pair_spin_dmi.cpp b/src/SPIN/pair_spin_dmi.cpp index 18682fdb9f..8496e40f99 100644 --- a/src/SPIN/pair_spin_dmi.cpp +++ b/src/SPIN/pair_spin_dmi.cpp @@ -329,7 +329,9 @@ void PairSpinDmi::compute(int eflag, int vflag) } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + update the pair interactions fmi acting on the spin ii +------------------------------------------------------------------------- */ void PairSpinDmi::compute_single_pair(int ii, double fmi[3]) { @@ -341,52 +343,76 @@ void PairSpinDmi::compute_single_pair(int ii, double fmi[3]) double delx,dely,delz; double spj[3]; - int i,j,jnum,itype,jtype; - int *ilist,*jlist,*numneigh,**firstneigh; + int i,j,jnum,itype,jtype,ntypes; + int k,locflag; + int *jlist,*numneigh,**firstneigh; double rsq, inorm; - ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; + + // check if interaction applies to type of ii + + itype = type[ii]; + ntypes = atom->ntypes; + locflag = 0; + k = 1; + while (k <= ntypes) { + if (k <= itype) { + if (setflag[k][itype] == 1) { + locflag =1; + break; + } + k++; + } else if (k > itype) { + if (setflag[itype][k] == 1) { + locflag =1; + break; + } + k++; + } else error->all(FLERR,"Wrong type number"); + } - i = ilist[ii]; - itype = type[i]; + // if interaction applies to type ii, + // locflag = 1 and compute pair interaction - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xi[2] = x[i][2]; + //i = ilist[ii]; + if (locflag == 1) { - jlist = firstneigh[i]; - jnum = numneigh[i]; + xi[0] = x[ii][0]; + xi[1] = x[ii][1]; + xi[2] = x[ii][2]; - for (int jj = 0; jj < jnum; jj++) { + jlist = firstneigh[ii]; + jnum = numneigh[ii]; - j = jlist[jj]; - j &= NEIGHMASK; - jtype = type[j]; + for (int jj = 0; jj < jnum; jj++) { - spj[0] = sp[j][0]; - spj[1] = sp[j][1]; - spj[2] = sp[j][2]; + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; - delx = xi[0] - x[j][0]; - dely = xi[1] - x[j][1]; - delz = xi[2] - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - inorm = 1.0/sqrt(rsq); - eij[0] = -inorm*delx; - eij[1] = -inorm*dely; - eij[2] = -inorm*delz; + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; - local_cut2 = cut_spin_dmi[itype][jtype]*cut_spin_dmi[itype][jtype]; + delx = xi[0] - x[j][0]; + dely = xi[1] - x[j][1]; + delz = xi[2] - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + inorm = 1.0/sqrt(rsq); + eij[0] = -inorm*delx; + eij[1] = -inorm*dely; + eij[2] = -inorm*delz; - if (rsq <= local_cut2) { - compute_dmi(i,j,eij,fmi,spj); - } + local_cut2 = cut_spin_dmi[itype][jtype]*cut_spin_dmi[itype][jtype]; + if (rsq <= local_cut2) { + compute_dmi(ii,j,eij,fmi,spj); + } + } } - } /* ---------------------------------------------------------------------- diff --git a/src/SPIN/pair_spin_exchange.cpp b/src/SPIN/pair_spin_exchange.cpp index 67229c2423..b2955aafb2 100644 --- a/src/SPIN/pair_spin_exchange.cpp +++ b/src/SPIN/pair_spin_exchange.cpp @@ -318,7 +318,6 @@ void PairSpinExchange::compute(int eflag, int vflag) void PairSpinExchange::compute_single_pair(int ii, double fmi[3]) { - int *type = atom->type; double **x = atom->x; double **sp = atom->sp; @@ -327,46 +326,70 @@ void PairSpinExchange::compute_single_pair(int ii, double fmi[3]) double delx,dely,delz; double spj[3]; - int i,j,jnum,itype,jtype; - int *ilist,*jlist,*numneigh,**firstneigh; + int i,j,jnum,itype,jtype,ntypes; + int k,locflag; + int *jlist,*numneigh,**firstneigh; double rsq; - ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; - i = ilist[ii]; - itype = type[i]; + // check if interaction applies to type of ii + + itype = type[ii]; + ntypes = atom->ntypes; + locflag = 0; + k = 1; + while (k <= ntypes) { + if (k <= itype) { + if (setflag[k][itype] == 1) { + locflag =1; + break; + } + k++; + } else if (k > itype) { + if (setflag[itype][k] == 1) { + locflag =1; + break; + } + k++; + } else error->all(FLERR,"Wrong type number"); + } + + // if interaction applies to type ii, + // locflag = 1 and compute pair interaction - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xi[2] = x[i][2]; + if (locflag == 1) { + + xi[0] = x[ii][0]; + xi[1] = x[ii][1]; + xi[2] = x[ii][2]; - jlist = firstneigh[i]; - jnum = numneigh[i]; + jlist = firstneigh[ii]; + jnum = numneigh[ii]; - for (int jj = 0; jj < jnum; jj++) { + for (int jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - j &= NEIGHMASK; - jtype = type[j]; - local_cut2 = cut_spin_exchange[itype][jtype]*cut_spin_exchange[itype][jtype]; + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; + local_cut2 = cut_spin_exchange[itype][jtype]*cut_spin_exchange[itype][jtype]; - spj[0] = sp[j][0]; - spj[1] = sp[j][1]; - spj[2] = sp[j][2]; + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; - delx = xi[0] - x[j][0]; - dely = xi[1] - x[j][1]; - delz = xi[2] - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + delx = xi[0] - x[j][0]; + dely = xi[1] - x[j][1]; + delz = xi[2] - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= local_cut2) { - compute_exchange(i,j,rsq,fmi,spj); + if (rsq <= local_cut2) { + compute_exchange(ii,j,rsq,fmi,spj); + } } - } - + } } /* ---------------------------------------------------------------------- @@ -528,3 +551,4 @@ void PairSpinExchange::read_restart_settings(FILE *fp) MPI_Bcast(&mix_flag,1,MPI_INT,0,world); } + diff --git a/src/SPIN/pair_spin_magelec.cpp b/src/SPIN/pair_spin_magelec.cpp index f85d69e222..a7357f61e3 100644 --- a/src/SPIN/pair_spin_magelec.cpp +++ b/src/SPIN/pair_spin_magelec.cpp @@ -319,7 +319,9 @@ void PairSpinMagelec::compute(int eflag, int vflag) } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + update the pair interactions fmi acting on the spin ii +------------------------------------------------------------------------- */ void PairSpinMagelec::compute_single_pair(int ii, double fmi[3]) { @@ -331,30 +333,48 @@ void PairSpinMagelec::compute_single_pair(int ii, double fmi[3]) double delx,dely,delz; double spj[3]; - int i,j,inum,jnum,itype,jtype; - int *ilist,*jlist,*numneigh,**firstneigh; + int i,j,jnum,itype,jtype,ntypes; + int k,locflag; + int *jlist,*numneigh,**firstneigh; double rsq, inorm; - inum = list->inum; - ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; + + // check if interaction applies to type of ii + + itype = type[ii]; + ntypes = atom->ntypes; + locflag = 0; + k = 1; + while (k <= ntypes) { + if (k <= itype) { + if (setflag[k][itype] == 1) { + locflag =1; + break; + } + k++; + } else if (k > itype) { + if (setflag[itype][k] == 1) { + locflag =1; + break; + } + k++; + } else error->all(FLERR,"Wrong type number"); + } - // compute pair if - - if (ii < inum) { + // if interaction applies to type ii, + // locflag = 1 and compute pair interaction - i = ilist[ii]; - itype = type[i]; + if (locflag == 1) { - xi[0] = xi[1] = xi[2] = 0.0; - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xi[2] = x[i][2]; + xi[0] = x[ii][0]; + xi[1] = x[ii][1]; + xi[2] = x[ii][2]; - jlist = firstneigh[i]; - jnum = numneigh[i]; + jlist = firstneigh[ii]; + jnum = numneigh[ii]; for (int jj = 0; jj < jnum; jj++) { @@ -377,12 +397,10 @@ void PairSpinMagelec::compute_single_pair(int ii, double fmi[3]) eij[2] = -inorm*delz; if (rsq <= local_cut2) { - compute_magelec(i,j,eij,fmi,spj); + compute_magelec(ii,j,eij,fmi,spj); } } - - } - + } } /* ---------------------------------------------------------------------- */ diff --git a/src/SPIN/pair_spin_neel.cpp b/src/SPIN/pair_spin_neel.cpp index 55f537cf4f..bd12832a8d 100644 --- a/src/SPIN/pair_spin_neel.cpp +++ b/src/SPIN/pair_spin_neel.cpp @@ -330,7 +330,9 @@ void PairSpinNeel::compute(int eflag, int vflag) } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + update the pair interactions fmi acting on the spin ii +------------------------------------------------------------------------- */ void PairSpinNeel::compute_single_pair(int ii, double fmi[3]) { @@ -342,57 +344,81 @@ void PairSpinNeel::compute_single_pair(int ii, double fmi[3]) double xi[3], rij[3], eij[3]; double spi[3], spj[3]; - int i,j,jnum,itype,jtype; - int *ilist,*jlist,*numneigh,**firstneigh; + int i,j,jnum,itype,jtype,ntypes; + int k,locflag; + int *jlist,*numneigh,**firstneigh; double rsq, inorm; - ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; + + // check if interaction applies to type of ii + + itype = type[ii]; + ntypes = atom->ntypes; + locflag = 0; + k = 1; + while (k <= ntypes) { + if (k <= itype) { + if (setflag[k][itype] == 1) { + locflag =1; + break; + } + k++; + } else if (k > itype) { + if (setflag[itype][k] == 1) { + locflag =1; + break; + } + k++; + } else error->all(FLERR,"Wrong type number"); + } - i = ilist[ii]; - itype = type[i]; + // if interaction applies to type ii, + // locflag = 1 and compute pair interaction - spi[0] = sp[i][0]; - spi[1] = sp[i][1]; - spi[2] = sp[i][2]; + if (locflag == 1) { - xi[0] = x[i][0]; - xi[1] = x[i][1]; - xi[2] = x[i][2]; + spi[0] = sp[ii][0]; + spi[1] = sp[ii][1]; + spi[2] = sp[ii][2]; - eij[0] = eij[1] = eij[2] = 0.0; + xi[0] = x[ii][0]; + xi[1] = x[ii][1]; + xi[2] = x[ii][2]; - jlist = firstneigh[i]; - jnum = numneigh[i]; + eij[0] = eij[1] = eij[2] = 0.0; - for (int jj = 0; jj < jnum; jj++) { + jlist = firstneigh[ii]; + jnum = numneigh[ii]; - j = jlist[jj]; - j &= NEIGHMASK; - jtype = type[j]; + for (int jj = 0; jj < jnum; jj++) { - local_cut2 = cut_spin_neel[itype][jtype]*cut_spin_neel[itype][jtype]; + j = jlist[jj]; + j &= NEIGHMASK; + jtype = type[j]; - spj[0] = sp[j][0]; - spj[1] = sp[j][1]; - spj[2] = sp[j][2]; + local_cut2 = cut_spin_neel[itype][jtype]*cut_spin_neel[itype][jtype]; - rij[0] = x[j][0] - xi[0]; - rij[1] = x[j][1] - xi[1]; - rij[2] = x[j][2] - xi[2]; - rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; - inorm = 1.0/sqrt(rsq); - eij[0] = inorm*rij[0]; - eij[1] = inorm*rij[1]; - eij[2] = inorm*rij[2]; + spj[0] = sp[j][0]; + spj[1] = sp[j][1]; + spj[2] = sp[j][2]; + + rij[0] = x[j][0] - xi[0]; + rij[1] = x[j][1] - xi[1]; + rij[2] = x[j][2] - xi[2]; + rsq = rij[0]*rij[0] + rij[1]*rij[1] + rij[2]*rij[2]; + inorm = 1.0/sqrt(rsq); + eij[0] = inorm*rij[0]; + eij[1] = inorm*rij[1]; + eij[2] = inorm*rij[2]; - if (rsq <= local_cut2) { - compute_neel(i,j,rsq,eij,fmi,spi,spj); + if (rsq <= local_cut2) { + compute_neel(ii,j,rsq,eij,fmi,spi,spj); + } } } - } /* ---------------------------------------------------------------------- */ -- GitLab From 0d1524526a807b618617b1af5a0930f1bebd6a7b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 4 Mar 2019 17:26:55 -0500 Subject: [PATCH 0191/1243] work around the remaining variable length array cases. fix an off-by-one error, too. --- src/USER-SMTBQ/pair_smtbq.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/USER-SMTBQ/pair_smtbq.cpp b/src/USER-SMTBQ/pair_smtbq.cpp index 1931754427..f3b85e9a9b 100644 --- a/src/USER-SMTBQ/pair_smtbq.cpp +++ b/src/USER-SMTBQ/pair_smtbq.cpp @@ -2895,11 +2895,12 @@ void PairSMTBQ::groupSurface_QEq() void PairSMTBQ::groupQEqAllParallel_QEq() { int ii,i,jj,j,kk,k,itype,jtype,ktype,jnum,m,gp,zz,z,kgp; - int iproc,team_elt[10][nproc],team_QEq[10][nproc][5]; + int iproc; // ,team_elt[10][nproc],team_QEq[10][nproc][5]; + int **team_elt,***team_QEq; int *ilist,*jlist,*numneigh,**firstneigh,ngp,igp; double delr[3],xtmp,ytmp,ztmp,rsq; int **flag_gp, *nelt, **tab_gp; - int QEq,QEqall[nproc]; + int QEq,*QEqall; double **x = atom->x; int *type = atom->type; @@ -2927,6 +2928,9 @@ void PairSMTBQ::groupQEqAllParallel_QEq() memory->create(nelt,nall,"pair:nelt"); memory->create(tab_gp,10,nall,"pair:flag_gp"); + memory->create(team_elt,10,nproc,"pair:team_elt"); + memory->create(team_QEq,10,nproc,5,"pair:team_QEq"); + memory->create(QEqall,nproc,"pair:QEqall"); for (i = 0; i < nall ; i++) { flag_QEq[i] = 0; } for (i = 0; i < 10*nproc; i++) { @@ -3002,6 +3006,9 @@ void PairSMTBQ::groupQEqAllParallel_QEq() memory->destroy(tab_gp); memory->destroy(nelt); + memory->destroy(team_elt); + memory->destroy(team_QEq); + memory->destroy(QEqall); return; } // ::::::::::::::::::::::::::::::::::::::::::::::::::::::: @@ -3339,6 +3346,9 @@ void PairSMTBQ::groupQEqAllParallel_QEq() memory->destroy(tab_gp); memory->destroy(nelt); + memory->destroy(team_elt); + memory->destroy(team_QEq); + memory->destroy(QEqall); } /* ---------------------------------------------------------------------- */ @@ -3346,7 +3356,8 @@ void PairSMTBQ::groupQEqAllParallel_QEq() void PairSMTBQ::Init_charge(int * /*nQEq*/, int * /*nQEqa*/, int * /*nQEqc*/) { int ii,i,gp,itype; - int *ilist,test[nteam],init[nteam]; + int *ilist; + std::vector test(cluster),init(cluster); double bound,tot,totll; int inum = list->inum; @@ -3376,7 +3387,8 @@ void PairSMTBQ::Init_charge(int * /*nQEq*/, int * /*nQEqa*/, int * /*nQEqc*/) } } - MPI_Allreduce(test,init,nteam+1,MPI_INT,MPI_SUM,world); + // TODO + MPI_Allreduce(test.data(),init.data(),cluster,MPI_INT,MPI_SUM,world); // On fait que sur les atomes hybrides!!! // ---------------------------------------- -- GitLab From 6ed8fbbd515ddae8543b6342433f73728f8ef3b5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 4 Mar 2019 18:01:55 -0500 Subject: [PATCH 0192/1243] handle uninitialized data access issues and out-of-bounds access for single element calculations --- src/USER-SMTBQ/pair_smtbq.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/USER-SMTBQ/pair_smtbq.cpp b/src/USER-SMTBQ/pair_smtbq.cpp index f3b85e9a9b..91ba612986 100644 --- a/src/USER-SMTBQ/pair_smtbq.cpp +++ b/src/USER-SMTBQ/pair_smtbq.cpp @@ -405,7 +405,13 @@ void PairSMTBQ::read_file(char *file) verbose = 1; verbose = 0; - // open file on all processors + coordOxBB = 0.0; + coordOxBulk = 0.0; + coordOxSurf = 0.0; + ROxBB = 0.0; + ROxSurf = 0.0; + + // open file on all processors FILE *fp; fp = force->open_potential(file); if ( fp == NULL ) { @@ -455,14 +461,12 @@ void PairSMTBQ::read_file(char *file) // load up parameter settings and error check their values - if (nparams == maxparam) { - maxparam += DELTA; - params = (Param *) memory->srealloc(params,maxparam*sizeof(Param), + nparams = maxparam = num_atom_types; + params = (Param *) memory->create(params,maxparam*sizeof(Param), "pair:params"); - maxintparam += m; - intparams = (Intparam *) memory->srealloc(intparams,(maxintparam+1)*sizeof(Intparam), + maxintparam = m; + intparams = (Intparam *) memory->create(intparams,(maxintparam+1)*sizeof(Intparam), "pair:intparams"); - } for (i=0; i < num_atom_types; i++) params[i].nom = (char*) malloc(sizeof(char)*3); @@ -839,7 +843,8 @@ void PairSMTBQ::read_file(char *file) } //A adapter au STO - ncov = min((params[0].sto)*(params[0].n0),(params[1].sto)*(params[1].n0)); + for (i=1,ncov=params[0].sto*params[0].n0; i < nparams; ++i) + ncov = min(ncov,(params[1].sto)*(params[1].n0)); if (verbose) printf (" Parametre ncov = %f\n",ncov); if (verbose) printf (" ********************************************* \n"); -- GitLab From fa7b5ecfa3c284c3724d3cf3dcd05126be134c47 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 5 Mar 2019 00:45:40 -0500 Subject: [PATCH 0193/1243] disable chimet array in pair style smtbq, which was never set anywhere --- src/USER-SMTBQ/pair_smtbq.cpp | 10 ++-------- src/USER-SMTBQ/pair_smtbq.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/USER-SMTBQ/pair_smtbq.cpp b/src/USER-SMTBQ/pair_smtbq.cpp index 91ba612986..5c3189fc31 100644 --- a/src/USER-SMTBQ/pair_smtbq.cpp +++ b/src/USER-SMTBQ/pair_smtbq.cpp @@ -123,7 +123,6 @@ PairSMTBQ::PairSMTBQ(LAMMPS *lmp) : Pair(lmp) sbcov = NULL; coord = NULL; sbmet = NULL; - chimet = NULL; ecov = NULL; potmad = NULL; @@ -210,7 +209,6 @@ PairSMTBQ::~PairSMTBQ() memory->destroy(potmad); memory->destroy(potself); memory->destroy(potcov); - memory->destroy(chimet); memory->destroy(nvsm); memory->destroy(vsm);; @@ -875,7 +873,6 @@ void PairSMTBQ::compute(int eflag, int vflag) memory->destroy(sbcov); memory->destroy(coord); memory->destroy(sbmet); - memory->destroy(chimet); memory->destroy(flag_QEq); memory->destroy(qf); memory->destroy(q1); @@ -891,7 +888,6 @@ void PairSMTBQ::compute(int eflag, int vflag) memory->create(sbcov,nmax,"pair:sbcov"); memory->create(coord,nmax,"pair:coord"); memory->create(sbmet,nmax,"pair:sbmet"); - memory->create(chimet,nmax,"pair:chimet"); memory->create(flag_QEq,nmax,"pair:flag_QEq"); memory->create(qf,nmax,"pair:qf"); memory->create(q1,nmax,"pair:q1"); @@ -1328,10 +1324,7 @@ void PairSMTBQ::tabqeq() memory->create(sbcov,nmax,"pair:sbcov"); memory->create(coord,nmax,"pair:coord"); memory->create(sbmet,nmax,"pair:sbmet"); - memory->create(chimet,nmax,"pair:chimet"); - // memory->create(nvsm,nmax,"pair:nvsm"); - // memory->create(vsm,nmax,nmax,"pair:vsm"); memory->create(flag_QEq,nmax,"pair:flag_QEq"); memory->create(qf,nmax,"pair:qf"); @@ -2681,7 +2674,8 @@ void PairSMTBQ::Charge() gp = flag_QEq[i]; qf[i] = 0.0; - qf[i] = potself[i]+potmad[i]+potcov[i]+chimet[i] ; + // AK: chimet is not set anywhere + qf[i] = potself[i]+potmad[i]+potcov[i]; // +chimet[i]; Transf[gp] += qf[i]; } diff --git a/src/USER-SMTBQ/pair_smtbq.h b/src/USER-SMTBQ/pair_smtbq.h index ac8ed70ac0..05e4b67242 100644 --- a/src/USER-SMTBQ/pair_smtbq.h +++ b/src/USER-SMTBQ/pair_smtbq.h @@ -90,7 +90,7 @@ protected: double coordOxBulk,coordOxSurf,ROxSurf,coordOxBB,ROxBB; // Covalent interaction - double *ecov, *potmad, *potself, *potcov, *chimet; + double *ecov, *potmad, *potself, *potcov; //, *chimet; double **tabsmb,**dtabsmb, **tabsmr, **dtabsmr, *sbcov, *sbmet; double ncov; -- GitLab From 1e573bd557e6b79b0d94fc7bed1b048f76b2c2ac Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 5 Mar 2019 08:35:53 -0500 Subject: [PATCH 0194/1243] when compiling LAMMPS in a git checkout, embed and print git branch and revision info into the executable --- cmake/CMakeLists.txt | 28 +++++++++++++++++++++++++++- src/Makefile | 21 +++++++++++++++++++-- src/Purge.list | 1 + src/info.cpp | 10 +++++++--- src/lammps.cpp | 5 +++++ src/lammps.h | 1 + 6 files changed, 60 insertions(+), 6 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index d9c87bdf5b..f54cf9d887 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -11,6 +11,8 @@ get_filename_component(LAMMPS_LIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib get_filename_component(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib ABSOLUTE) get_filename_component(LAMMPS_DOC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../doc ABSOLUTE) +find_package(Git) + # by default, install into $HOME/.local (not /usr/local), so that no root access (and sudo!!) is needed if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/.local" CACHE PATH "default install path" FORCE ) @@ -85,7 +87,7 @@ string(TOUPPER "${CMAKE_BUILD_TYPE}" BTYPE) # this is fast, so check for it all the time message(STATUS "Running check for auto-generated files from make-based build system") file(GLOB SRC_AUTOGEN_FILES ${LAMMPS_SOURCE_DIR}/style_*.h) -list(APPEND SRC_AUTOGEN_FILES ${LAMMPS_SOURCE_DIR}/lmpinstalledpkgs.h) +list(APPEND SRC_AUTOGEN_FILES ${LAMMPS_SOURCE_DIR}/lmpinstalledpkgs.h ${LAMMPS_SOURCE_DIR}/lmpgitversion.h) foreach(_SRC ${SRC_AUTOGEN_FILES}) get_filename_component(FILENAME "${_SRC}" NAME) if(EXISTS ${LAMMPS_SOURCE_DIR}/${FILENAME}) @@ -1326,6 +1328,30 @@ message(STATUS "Generating lmpinstalledpkgs.h...") file(WRITE "${LAMMPS_STYLE_HEADERS_DIR}/lmpinstalledpkgs.h.tmp" "${temp}" ) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HEADERS_DIR}/lmpinstalledpkgs.h.tmp" "${LAMMPS_STYLE_HEADERS_DIR}/lmpinstalledpkgs.h") +###################################### +# Generate lmpgitversion.h +###################################### +set(temp "#ifndef LMP_GIT_VERSION_H\n#define LMP_GIT_VERSION_H\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_version[] =") +if(GIT_FOUND) + execute_process(COMMAND ${GIT_EXECUTABLE} describe HEAD + OUTPUT_VARIABLE temp_git_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE temp_git_branch + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(temp_git "${temp_git_branch} / ${temp_git_version}") +else() + set(temp_git "") +endif() + +set(temp "${temp} \"${temp_git}\";\n#endif\n\n") +message(STATUS "Generating lmpgitversion.h...") +file(WRITE "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${temp}" ) +execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h") + ########################################### # Actually add executable and lib to build ############################################ diff --git a/src/Makefile b/src/Makefile index f954d84e5d..058a415238 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,7 +19,7 @@ OBJDIR = Obj_$@ OBJSHDIR = Obj_shared_$@ SRC = $(wildcard *.cpp) -INC = $(filter-out lmpinstalledpkgs.h,$(wildcard *.h)) +INC = $(filter-out lmpinstalledpkgs.h lmpgitversion.h,$(wildcard *.h)) OBJ = $(SRC:.cpp=.o) SRCLIB = $(filter-out main.cpp,$(SRC)) @@ -167,6 +167,23 @@ lmpinstalledpkgs.h: $(SRC) $(INC) mv ${TMPNAME}.lmpinstalled lmpinstalledpkgs.h || rm ${TMPNAME}.lmpinstalled ; \ else mv ${TMPNAME}.lmpinstalled lmpinstalledpkgs.h ; fi +gitversion: + @echo 'Gathering git version information' + @echo '#ifndef LMP_GIT_VERSION_H' > ${TMPNAME}.lmpgitversion + @echo '#define LMP_GIT_VERSION_H' >> ${TMPNAME}.lmpgitversion + @echo 'const char LAMMPS_NS::LAMMPS::git_version[] = ' >> ${TMPNAME}.lmpgitversion + @if (type git && git describe HEAD ) >> /dev/null 2>> /dev/null ; then \ + export v1=$$(git rev-parse --abbrev-ref HEAD); export v2=$$(git describe HEAD); \ + echo "\"$${v1} / $${v2}\";" >> ${TMPNAME}.lmpgitversion ; \ + else \ + echo '"";' >> ${TMPNAME}.lmpgitversion ; \ + fi + @echo '#endif' >> ${TMPNAME}.lmpgitversion + @if [ -f lmpgitversion.h ]; \ + then test "`diff --brief ${TMPNAME}.lmpgitversion lmpgitversion.h`" != "" && \ + mv ${TMPNAME}.lmpgitversion lmpgitversion.h || rm ${TMPNAME}.lmpgitversion ; \ + else mv ${TMPNAME}.lmpgitversion lmpgitversion.h ; fi + # Build LAMMPS in one of 4 modes # exe = exe with static compile in Obj_machine (default) # shexe = exe with shared compile in Obj_shared_machine @@ -180,7 +197,7 @@ lmpinstalledpkgs.h: $(SRC) $(INC) -f MAKE/MACHINES/Makefile.$@ -o -f MAKE/MINE/Makefile.$@ @if [ ! -d $(objdir) ]; then mkdir $(objdir); fi @$(SHELL) Make.sh style - @$(MAKE) $(MFLAGS) lmpinstalledpkgs.h + @$(MAKE) $(MFLAGS) lmpinstalledpkgs.h gitversion @echo 'Compiling LAMMPS for machine $@' @if [ -f MAKE/MACHINES/Makefile.$@ ]; \ then cp MAKE/MACHINES/Makefile.$@ $(objdir)/Makefile; fi diff --git a/src/Purge.list b/src/Purge.list index 32b42f5ef1..59c35efca5 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -24,6 +24,7 @@ style_nstencil.h style_ntopo.h # other auto-generated files lmpinstalledpkgs.h +lmpgitversion.h # renamed on 7 January 2019 pair_lebedeva.cpp pair_lebedeva.h diff --git a/src/info.cpp b/src/info.cpp index 983a1e9e92..f17a00b8d2 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -260,9 +260,13 @@ void Info::command(int narg, char **arg) fprintf(out,"Printed on %s\n",ctime(&now)); if (flags & CONFIG) { - fprintf(out,"\nLAMMPS version: %s / %s\n\n", - universe->version, universe->num_ver); - + if (strlen(lmp->git_version) > 0) { + fprintf(out,"\nLAMMPS version: %s / %s\nGit revision: %s\n\n", + universe->version, universe->num_ver,lmp->git_version); + } else { + fprintf(out,"\nLAMMPS version: %s / %s\n\n", + universe->version, universe->num_ver); + } const char *infobuf = get_os_info(); fprintf(out,"OS information: %s\n\n",infobuf); delete[] infobuf; diff --git a/src/lammps.cpp b/src/lammps.cpp index 8a23a4297b..80ea1d8c9d 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -52,6 +52,7 @@ #include "error.h" #include "lmpinstalledpkgs.h" +#include "lmpgitversion.h" using namespace LAMMPS_NS; @@ -418,6 +419,10 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if ((universe->me == 0) && !helpflag) { if (screen) fprintf(screen,"LAMMPS (%s)\n",universe->version); if (logfile) fprintf(logfile,"LAMMPS (%s)\n",universe->version); + if (strlen(git_version) > 0) { + if (screen) fprintf(screen,"Git revision (%s)\n",git_version); + if (logfile) fprintf(logfile,"Git revision (%s)\n",git_version); + } } // universe is one or more worlds, as setup by partition switch diff --git a/src/lammps.h b/src/lammps.h index 151b4fc49b..7ae7ab7ecb 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -64,6 +64,7 @@ class LAMMPS { class CiteMe *citeme; // citation info static const char * installed_packages[]; + static const char git_version[]; LAMMPS(int, char **, MPI_Comm); ~LAMMPS(); -- GitLab From 1c7d1919882e76a688ab2e37962a51c999bbbdbf Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 5 Mar 2019 09:03:12 -0500 Subject: [PATCH 0195/1243] also print git version (if available) in multi-partition runs and in help message --- src/lammps.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lammps.cpp b/src/lammps.cpp index 80ea1d8c9d..126a88b3e1 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -497,11 +497,15 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if ((universe->me == 0) && (!helpflag)) { if (universe->uscreen) { fprintf(universe->uscreen,"LAMMPS (%s)\n",universe->version); + if (strlen(git_version) > 0) + fprintf(universe->uscreen,"Git revision (%s)\n",git_version); fprintf(universe->uscreen,"Running on %d partitions of processors\n", universe->nworlds); } if (universe->ulogfile) { fprintf(universe->ulogfile,"LAMMPS (%s)\n",universe->version); + if (strlen(git_version) > 0) + fprintf(universe->ulogfile,"Git revision (%s)\n",git_version); fprintf(universe->ulogfile,"Running on %d partitions of processors\n", universe->nworlds); } @@ -510,10 +514,14 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if ((me == 0) && (!helpflag)) { if (screen) { fprintf(screen,"LAMMPS (%s)\n",universe->version); + if (strlen(git_version) > 0) + fprintf(screen,"Git revision (%s)\n",git_version); fprintf(screen,"Processor partition = %d\n",universe->iworld); } if (logfile) { fprintf(logfile,"LAMMPS (%s)\n",universe->version); + if (strlen(git_version) > 0) + fprintf(logfile,"Git revision (%s)\n",git_version); fprintf(logfile,"Processor partition = %d\n",universe->iworld); } } @@ -903,9 +911,16 @@ void LAMMPS::help() // general help message about command line and flags + if (strlen(git_version) > 0) { + fprintf(fp, + "\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " + LAMMPS_VERSION "\nGit revision (%s)\n\n",git_version); + } else { + fprintf(fp, + "\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " + LAMMPS_VERSION "\n\n"); + } fprintf(fp, - "\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " - LAMMPS_VERSION "\n\n" "Usage example: %s -var t 300 -echo screen -in in.alloy\n\n" "List of command line options supported by this LAMMPS executable:\n\n" "-echo none/screen/log/both : echoing of input script (-e)\n" -- GitLab From 146e2f283a7d717cff840f0b3696fc27c8826931 Mon Sep 17 00:00:00 2001 From: mkanski Date: Tue, 5 Mar 2019 19:11:33 +0100 Subject: [PATCH 0196/1243] Better error handling in reaxc_forces --- src/USER-REAXC/pair_reaxc.cpp | 11 ++++++----- src/USER-REAXC/reaxc_allocate.cpp | 12 ++++++++---- src/USER-REAXC/reaxc_allocate.h | 7 ++++++- src/USER-REAXC/reaxc_forces.cpp | 18 +++++++++++------- src/USER-REAXC/reaxc_forces.h | 2 +- src/USER-REAXC/reaxc_init_md.cpp | 12 +++++++----- src/USER-REAXC/reaxc_init_md.h | 5 ++++- src/USER-REAXC/reaxc_reset_tools.cpp | 12 +++++++----- src/USER-REAXC/reaxc_reset_tools.h | 8 ++++++-- 9 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index b68e0d0779..0f4b3a5b3d 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -394,7 +394,8 @@ void PairReaxC::init_style( ) "increased neighbor list skin."); for( int i = 0; i < LIST_N; ++i ) - lists[i].allocated = 0; + if (lists[i].allacated != 1) + lists[i].allocated = 0; if (fix_reax == NULL) { char **fixarg = new char*[3]; @@ -445,7 +446,7 @@ void PairReaxC::setup( ) error->all(FLERR,"Pair reax/c problem in far neighbor list"); write_reax_lists(); - Initialize( system, control, data, workspace, &lists, out_control, + Initialize( lmp, system, control, data, workspace, &lists, out_control, mpi_data, world ); for( int k = 0; k < system->N; ++k ) { num_bonds[k] = system->my_atoms[k].num_bonds; @@ -465,7 +466,7 @@ void PairReaxC::setup( ) // check if I need to shrink/extend my data-structs - ReAllocate( system, control, data, workspace, &lists, mpi_data ); + ReAllocate( lmp, system, control, data, workspace, &lists, mpi_data ); } bigint local_ngroup = list->inum; @@ -517,7 +518,7 @@ void PairReaxC::compute(int eflag, int vflag) setup(); - Reset( system, control, data, workspace, &lists, world ); + Reset( lmp, system, control, data, workspace, &lists, world ); workspace->realloc.num_far = write_reax_lists(); // timing for filling in the reax lists if (comm->me == 0) { @@ -527,7 +528,7 @@ void PairReaxC::compute(int eflag, int vflag) // forces - Compute_Forces(system,control,data,workspace,&lists,out_control,mpi_data); + Compute_Forces(lmp, system,control,data,workspace,&lists,out_control,mpi_data); read_reax_forces(vflag); for(int k = 0; k < system->N; ++k) { diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp index 700e68514c..ebf0684389 100644 --- a/src/USER-REAXC/reaxc_allocate.cpp +++ b/src/USER-REAXC/reaxc_allocate.cpp @@ -35,6 +35,10 @@ #include #endif +#include "lammps.h" +#include "error.h" +using namespace LAMMPS_NS; + /* allocate space for my_atoms important: we cannot know the exact number of atoms that will fall into a process's box throughout the whole simulation. therefore @@ -353,7 +357,7 @@ static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, } -static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, +static int Reallocate_Bonds_List( LAMMPS *lmp, reax_system *system, reax_list *bonds, int *total_bonds, int *est_3body, MPI_Comm comm ) { @@ -379,7 +383,7 @@ static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, Delete_List( bonds, comm ); if(!Make_List(system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) { fprintf( stderr, "not enough space for bonds list. terminating!\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR, "Can't allocate space for hbonds."); } #ifdef LMP_USER_OMP @@ -399,7 +403,7 @@ static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, } -void ReAllocate( reax_system *system, control_params *control, +void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, mpi_datatypes *mpi_data ) { @@ -490,7 +494,7 @@ void ReAllocate( reax_system *system, control_params *control, /* bonds list */ num_bonds = est_3body = -1; if (Nflag || realloc->bonds) { - Reallocate_Bonds_List( system, (*lists)+BONDS, &num_bonds, + Reallocate_Bonds_List( lmp, system, (*lists)+BONDS, &num_bonds, &est_3body, comm ); realloc->bonds = 0; realloc->num_3body = MAX( realloc->num_3body, est_3body ) * 2; diff --git a/src/USER-REAXC/reaxc_allocate.h b/src/USER-REAXC/reaxc_allocate.h index f8814859af..786ee6ee8b 100644 --- a/src/USER-REAXC/reaxc_allocate.h +++ b/src/USER-REAXC/reaxc_allocate.h @@ -28,6 +28,11 @@ #define __ALLOCATE_H_ #include "reaxc_types.h" + +#include "lammps.h" +#include "error.h" +using namespace LAMMPS_NS; + int PreAllocate_Space( reax_system*, control_params*, storage*, MPI_Comm ); int Allocate_System( reax_system*, int, int, char* ); @@ -37,6 +42,6 @@ int Allocate_Workspace( reax_system*, control_params*, storage*, int, int, MPI_Comm, char* ); void DeAllocate_Workspace( control_params*, storage* ); -void ReAllocate( reax_system*, control_params*, simulation_data*, storage*, +void ReAllocate( LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, reax_list**, mpi_datatypes* ); #endif diff --git a/src/USER-REAXC/reaxc_forces.cpp b/src/USER-REAXC/reaxc_forces.cpp index 19b3cc4975..848c03f5a1 100644 --- a/src/USER-REAXC/reaxc_forces.cpp +++ b/src/USER-REAXC/reaxc_forces.cpp @@ -39,7 +39,11 @@ #include "reaxc_valence_angles.h" #include "reaxc_vector.h" +#include "lammps.h" +#include "error.h" + interaction_function Interaction_Functions[NUM_INTRS]; +using namespace LAMMPS_NS; void Dummy_Interaction( reax_system * /*system*/, control_params * /*control*/, simulation_data * /*data*/, storage * /*workspace*/, @@ -114,7 +118,7 @@ void Compute_Total_Force( reax_system *system, control_params *control, } -void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **lists, +void Validate_Lists( LAMMPS *lmp, reax_system *system, storage * /*workspace*/, reax_list **lists, int step, int /*n*/, int N, int numH, MPI_Comm comm ) { int i, comp, Hindex; @@ -136,7 +140,7 @@ void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **l if (End_Index(i, bonds) > comp) { fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, i, End_Index(i,bonds), comp ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR,"Failure in bond list."); } } } @@ -163,7 +167,7 @@ void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **l if (End_Index(Hindex, hbonds) > comp) { fprintf(stderr,"step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", step, Hindex, End_Index(Hindex,hbonds), comp ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR, "Failure in hydrogen bonds."); } } } @@ -171,7 +175,7 @@ void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **l } -void Init_Forces_noQEq( reax_system *system, control_params *control, +void Init_Forces_noQEq( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls * /*out_control*/, MPI_Comm comm ) { @@ -307,7 +311,7 @@ void Init_Forces_noQEq( reax_system *system, control_params *control, workspace->realloc.num_bonds = num_bonds; workspace->realloc.num_hbonds = num_hbonds; - Validate_Lists( system, workspace, lists, data->step, + Validate_Lists( lmp, system, workspace, lists, data->step, system->n, system->N, system->numH, comm ); } @@ -431,14 +435,14 @@ void Estimate_Storages( reax_system *system, control_params *control, } -void Compute_Forces( reax_system *system, control_params *control, +void Compute_Forces( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { MPI_Comm comm = mpi_data->world; - Init_Forces_noQEq( system, control, data, workspace, + Init_Forces_noQEq( lmp, system, control, data, workspace, lists, out_control, comm ); /********* bonded interactions ************/ diff --git a/src/USER-REAXC/reaxc_forces.h b/src/USER-REAXC/reaxc_forces.h index 6c839a7023..31cfc03a6b 100644 --- a/src/USER-REAXC/reaxc_forces.h +++ b/src/USER-REAXC/reaxc_forces.h @@ -33,7 +33,7 @@ extern interaction_function Interaction_Functions[NUM_INTRS]; void Init_Force_Functions( control_params* ); -void Compute_Forces( reax_system*, control_params*, simulation_data*, +void Compute_Forces( LAMMPS_NS::LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes* ); void Estimate_Storages( reax_system*, control_params*, reax_list**, int*, int*, int*, int*, MPI_Comm ); diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index 5901b76326..4565fd067d 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -36,6 +36,8 @@ #include "reaxc_tool_box.h" #include "reaxc_vector.h" +using namespace LAMMPS_NS; + int Init_System( reax_system *system, control_params *control, char * /*msg*/ ) { int i; @@ -150,7 +152,7 @@ int Init_MPI_Datatypes( reax_system *system, storage * /*workspace*/, return SUCCESS; } -int Init_Lists( reax_system *system, control_params *control, +int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data * /*data*/, storage * /*workspace*/, reax_list **lists, mpi_datatypes *mpi_data, char * /*msg*/ ) { @@ -180,7 +182,7 @@ int Init_Lists( reax_system *system, control_params *control, if( !Make_List( system->Hcap, total_hbonds, TYP_HBOND, *lists+HBONDS, comm ) ) { fprintf( stderr, "not enough space for hbonds list. terminating!\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR, "Can't allocate space for hbonds."); } } @@ -194,7 +196,7 @@ int Init_Lists( reax_system *system, control_params *control, if( !Make_List( system->total_cap, bond_cap, TYP_BOND, *lists+BONDS, comm ) ) { fprintf( stderr, "not enough space for bonds list. terminating!\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR, "Can't allocate space for hbonds."); } /* 3bodies list */ @@ -211,7 +213,7 @@ int Init_Lists( reax_system *system, control_params *control, return SUCCESS; } -void Initialize( reax_system *system, control_params *control, +void Initialize( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data, MPI_Comm comm ) @@ -250,7 +252,7 @@ void Initialize( reax_system *system, control_params *control, MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); } - if (Init_Lists( system, control, data, workspace, lists, mpi_data, msg ) == + if (Init_Lists( lmp, system, control, data, workspace, lists, mpi_data, msg ) == FAILURE) { fprintf( stderr, "p%d: %s\n", system->my_rank, msg ); fprintf( stderr, "p%d: system could not be initialized! terminating.\n", diff --git a/src/USER-REAXC/reaxc_init_md.h b/src/USER-REAXC/reaxc_init_md.h index 25333c744f..2baa70245b 100644 --- a/src/USER-REAXC/reaxc_init_md.h +++ b/src/USER-REAXC/reaxc_init_md.h @@ -29,6 +29,9 @@ #include "reaxc_types.h" -void Initialize( reax_system*, control_params*, simulation_data*, storage*, +#include "lammps.h" +#include "error.h" + +void Initialize( LAMMPS_NS::LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes*, MPI_Comm ); #endif diff --git a/src/USER-REAXC/reaxc_reset_tools.cpp b/src/USER-REAXC/reaxc_reset_tools.cpp index 80faed1e9f..d9cb5f22fe 100644 --- a/src/USER-REAXC/reaxc_reset_tools.cpp +++ b/src/USER-REAXC/reaxc_reset_tools.cpp @@ -30,6 +30,8 @@ #include "reaxc_tool_box.h" #include "reaxc_vector.h" +using namespace LAMMPS_NS; + void Reset_Atoms( reax_system* system, control_params *control ) { int i; @@ -119,7 +121,7 @@ void Reset_Workspace( reax_system *system, storage *workspace ) } -void Reset_Neighbor_Lists( reax_system *system, control_params *control, +void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system *system, control_params *control, storage *workspace, reax_list **lists, MPI_Comm comm ) { @@ -145,7 +147,7 @@ void Reset_Neighbor_Lists( reax_system *system, control_params *control, fprintf(stderr, "p%d: not enough space for bonds! total=%d allocated=%d\n", system->my_rank, total_bonds, bonds->num_intrs ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR, "Can't allocate space for hbonds."); } } } @@ -171,14 +173,14 @@ void Reset_Neighbor_Lists( reax_system *system, control_params *control, fprintf(stderr, "p%d: not enough space for hbonds! total=%d allocated=%d\n", system->my_rank, total_hbonds, hbonds->num_intrs ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->all(FLERR, "Can't allocate space for hbonds."); } } } } -void Reset( reax_system *system, control_params *control, simulation_data *data, +void Reset( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, MPI_Comm comm ) { Reset_Atoms( system, control ); @@ -187,6 +189,6 @@ void Reset( reax_system *system, control_params *control, simulation_data *data, Reset_Workspace( system, workspace ); - Reset_Neighbor_Lists( system, control, workspace, lists, comm ); + Reset_Neighbor_Lists( lmp, system, control, workspace, lists, comm ); } diff --git a/src/USER-REAXC/reaxc_reset_tools.h b/src/USER-REAXC/reaxc_reset_tools.h index c2a90072d5..9e2b9de980 100644 --- a/src/USER-REAXC/reaxc_reset_tools.h +++ b/src/USER-REAXC/reaxc_reset_tools.h @@ -29,12 +29,16 @@ #include "reaxc_types.h" +#include "lammps.h" +#include "error.h" +using namespace LAMMPS_NS; + void Reset_Pressures( simulation_data* ); void Reset_Simulation_Data( simulation_data*, int ); void Reset_Timing( reax_timing* ); void Reset_Workspace( reax_system*, storage* ); -void Reset_Neighbor_Lists( reax_system*, control_params*, storage*, +void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system*, control_params*, storage*, reax_list**, MPI_Comm ); -void Reset( reax_system*, control_params*, simulation_data*, storage*, +void Reset( LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, reax_list**, MPI_Comm ); #endif -- GitLab From bfa950a7e906b0f09233b72f177a978887fdeaa7 Mon Sep 17 00:00:00 2001 From: mkanski Date: Tue, 5 Mar 2019 22:40:10 +0100 Subject: [PATCH 0197/1243] Added initialization for grown arrays --- src/USER-REAXC/fix_reaxc.cpp | 12 ++++++++---- src/USER-REAXC/fix_reaxc.h | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/USER-REAXC/fix_reaxc.cpp b/src/USER-REAXC/fix_reaxc.cpp index 1323ff4da7..361733f3ca 100644 --- a/src/USER-REAXC/fix_reaxc.cpp +++ b/src/USER-REAXC/fix_reaxc.cpp @@ -41,16 +41,15 @@ FixReaxC::FixReaxC(LAMMPS *lmp,int narg, char **arg) : { // perform initial allocation of atom-based arrays // register with atom class - + + oldnmax = 0; num_bonds = NULL; num_hbonds = NULL; grow_arrays(atom->nmax); atom->add_callback(0); // initialize arrays to MIN so atom migration is OK the 1st time - - for (int i = 0; i < atom->nmax; i++) - num_bonds[i] = num_hbonds[i] = MIN_REAX_BONDS; + // it is done in grow_arrays() now // set comm sizes needed by this fix @@ -98,6 +97,11 @@ void FixReaxC::grow_arrays(int nmax) { memory->grow(num_bonds,nmax,"reaxc:num_bonds"); memory->grow(num_hbonds,nmax,"reaxc:num_hbonds"); + for (int i = oldnmax; i < nmax; i++) { + num_hbonds[i] = MIN_REAX_HBONDS; + num_bonds[i] = MIN_REAX_BONDS; + } + oldnmax = nmax; } /* ---------------------------------------------------------------------- diff --git a/src/USER-REAXC/fix_reaxc.h b/src/USER-REAXC/fix_reaxc.h index 0e173f5ece..6a37002847 100644 --- a/src/USER-REAXC/fix_reaxc.h +++ b/src/USER-REAXC/fix_reaxc.h @@ -56,6 +56,7 @@ class FixReaxC : public Fix { int maxhbonds; // max # of Hbonds for any atom int *num_bonds; // # of bonds for each atom int *num_hbonds; // # of Hbonds for each atom + int oldnmax; // arrays' size before growing }; } -- GitLab From c5a3b034ce54ad213fe1c30f4636dc922f5607cf Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 5 Mar 2019 17:29:34 -0500 Subject: [PATCH 0198/1243] implement various suggestions to improve the use of git information gathered --- cmake/CMakeLists.txt | 36 ++++++++++++++++++++++++++---------- src/Makefile | 18 +++++++++++++----- src/info.cpp | 7 ++++--- src/lammps.cpp | 22 ++++------------------ src/lammps.h | 6 +++++- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f54cf9d887..ec32049445 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1332,22 +1332,38 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HE # Generate lmpgitversion.h ###################################### set(temp "#ifndef LMP_GIT_VERSION_H\n#define LMP_GIT_VERSION_H\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_version[] =") +set(temp_git_commit "(unknown)") +set(temp_git_branch "(unknown)") +set(temp_git_describe "(unknown)") +set(temp_git_info "false") if(GIT_FOUND) execute_process(COMMAND ${GIT_EXECUTABLE} describe HEAD - OUTPUT_VARIABLE temp_git_version + RESULT_VARIABLE temp_in_git_checkout ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD - OUTPUT_VARIABLE temp_git_branch - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - set(temp_git "${temp_git_branch} / ${temp_git_version}") -else() - set(temp_git "") + if(temp_in_git_checkout EQUAL 0) + set(temp_git_info "true") + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + OUTPUT_VARIABLE temp_git_commit + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE temp_git_branch + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} describe --dirty=-modified + OUTPUT_VARIABLE temp_git_describe + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() endif() -set(temp "${temp} \"${temp_git}\";\n#endif\n\n") +set(temp "${temp}const bool LAMMPS_NS::LAMMPS::has_git_info = ${temp_git_info};\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_commit[] = \"${temp_git_commit}\";\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_branch[] = \"${temp_git_branch}\";\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_descriptor[] = \"${temp_git_describe}\";\n") +set(temp "${temp}#endif\n\n") + message(STATUS "Generating lmpgitversion.h...") file(WRITE "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${temp}" ) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h") diff --git a/src/Makefile b/src/Makefile index 058a415238..f720abe6ec 100644 --- a/src/Makefile +++ b/src/Makefile @@ -171,13 +171,21 @@ gitversion: @echo 'Gathering git version information' @echo '#ifndef LMP_GIT_VERSION_H' > ${TMPNAME}.lmpgitversion @echo '#define LMP_GIT_VERSION_H' >> ${TMPNAME}.lmpgitversion - @echo 'const char LAMMPS_NS::LAMMPS::git_version[] = ' >> ${TMPNAME}.lmpgitversion @if (type git && git describe HEAD ) >> /dev/null 2>> /dev/null ; then \ - export v1=$$(git rev-parse --abbrev-ref HEAD); export v2=$$(git describe HEAD); \ - echo "\"$${v1} / $${v2}\";" >> ${TMPNAME}.lmpgitversion ; \ + git='true'; \ + commit=$$(git rev-parse HEAD); \ + branch=$$(git rev-parse --abbrev-ref HEAD); \ + describe=$$(git describe --dirty=-modified); \ else \ - echo '"";' >> ${TMPNAME}.lmpgitversion ; \ - fi + git='false' ; \ + commit='(unknown)' ; \ + branch='(unknown)' ; \ + describe='(unknown)' ; \ + fi ; \ + echo "const bool LAMMPS_NS::LAMMPS::has_git_info = $${git};" >> ${TMPNAME}.lmpgitversion ; \ + echo "const char LAMMPS_NS::LAMMPS::git_commit[] = \"$${commit}\";" >> ${TMPNAME}.lmpgitversion ; \ + echo "const char LAMMPS_NS::LAMMPS::git_branch[] = \"$${branch}\";" >> ${TMPNAME}.lmpgitversion ; \ + echo "const char LAMMPS_NS::LAMMPS::git_descriptor[] = \"$${describe}\";" >> ${TMPNAME}.lmpgitversion @echo '#endif' >> ${TMPNAME}.lmpgitversion @if [ -f lmpgitversion.h ]; \ then test "`diff --brief ${TMPNAME}.lmpgitversion lmpgitversion.h`" != "" && \ diff --git a/src/info.cpp b/src/info.cpp index f17a00b8d2..3d8a8d7b9e 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -260,9 +260,10 @@ void Info::command(int narg, char **arg) fprintf(out,"Printed on %s\n",ctime(&now)); if (flags & CONFIG) { - if (strlen(lmp->git_version) > 0) { - fprintf(out,"\nLAMMPS version: %s / %s\nGit revision: %s\n\n", - universe->version, universe->num_ver,lmp->git_version); + if (lmp->has_git_info) { + fprintf(out,"\nLAMMPS version: %s / %s\nGit info: %s / %s / %s\n\n", + universe->version, universe->num_ver,lmp->git_branch, + lmp->git_descriptor,lmp->git_commit); } else { fprintf(out,"\nLAMMPS version: %s / %s\n\n", universe->version, universe->num_ver); diff --git a/src/lammps.cpp b/src/lammps.cpp index 126a88b3e1..2b3f001b09 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -419,10 +419,6 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if ((universe->me == 0) && !helpflag) { if (screen) fprintf(screen,"LAMMPS (%s)\n",universe->version); if (logfile) fprintf(logfile,"LAMMPS (%s)\n",universe->version); - if (strlen(git_version) > 0) { - if (screen) fprintf(screen,"Git revision (%s)\n",git_version); - if (logfile) fprintf(logfile,"Git revision (%s)\n",git_version); - } } // universe is one or more worlds, as setup by partition switch @@ -497,15 +493,11 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if ((universe->me == 0) && (!helpflag)) { if (universe->uscreen) { fprintf(universe->uscreen,"LAMMPS (%s)\n",universe->version); - if (strlen(git_version) > 0) - fprintf(universe->uscreen,"Git revision (%s)\n",git_version); fprintf(universe->uscreen,"Running on %d partitions of processors\n", universe->nworlds); } if (universe->ulogfile) { fprintf(universe->ulogfile,"LAMMPS (%s)\n",universe->version); - if (strlen(git_version) > 0) - fprintf(universe->ulogfile,"Git revision (%s)\n",git_version); fprintf(universe->ulogfile,"Running on %d partitions of processors\n", universe->nworlds); } @@ -514,14 +506,10 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if ((me == 0) && (!helpflag)) { if (screen) { fprintf(screen,"LAMMPS (%s)\n",universe->version); - if (strlen(git_version) > 0) - fprintf(screen,"Git revision (%s)\n",git_version); fprintf(screen,"Processor partition = %d\n",universe->iworld); } if (logfile) { fprintf(logfile,"LAMMPS (%s)\n",universe->version); - if (strlen(git_version) > 0) - fprintf(logfile,"Git revision (%s)\n",git_version); fprintf(logfile,"Processor partition = %d\n",universe->iworld); } } @@ -911,13 +899,11 @@ void LAMMPS::help() // general help message about command line and flags - if (strlen(git_version) > 0) { - fprintf(fp, - "\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " - LAMMPS_VERSION "\nGit revision (%s)\n\n",git_version); + if (has_git_info) { + fprintf(fp,"\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " + LAMMPS_VERSION "\nGit info (%s / %s)\n\n",git_branch, git_descriptor); } else { - fprintf(fp, - "\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " + fprintf(fp,"\nLarge-scale Atomic/Molecular Massively Parallel Simulator - " LAMMPS_VERSION "\n\n"); } fprintf(fp, diff --git a/src/lammps.h b/src/lammps.h index 7ae7ab7ecb..2e052e5ed2 100644 --- a/src/lammps.h +++ b/src/lammps.h @@ -64,7 +64,11 @@ class LAMMPS { class CiteMe *citeme; // citation info static const char * installed_packages[]; - static const char git_version[]; + + static const bool has_git_info; + static const char git_commit[]; + static const char git_branch[]; + static const char git_descriptor[]; LAMMPS(int, char **, MPI_Comm); ~LAMMPS(); -- GitLab From b628e3b1b612a9ffbfd18d2a45439f339634631c Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Wed, 6 Mar 2019 10:26:03 -0600 Subject: [PATCH 0199/1243] Update openkim.org urls in various places --- doc/src/Build_extras.txt | 8 ++------ doc/src/pair_kim.txt | 8 ++------ lib/kim/Install.py | 4 ++-- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/doc/src/Build_extras.txt b/doc/src/Build_extras.txt index 8691f64a09..cbbd9db2f3 100644 --- a/doc/src/Build_extras.txt +++ b/doc/src/Build_extras.txt @@ -181,14 +181,10 @@ library with all its models, may take around 30 min to build. Of course you only need to do that once. See the list of KIM model drivers here: -https://openkim.org/kim-items/model-drivers/alphabetical +https://openkim.org/browse/model-drivers/alphabetical See the list of all KIM models here: -https://openkim.org/kim-items/models/by-model-drivers - -See the list of example KIM models included by default here: -https://openkim.org/kim-api on the "What is in the KIM API source -package?" page. +https://openkim.org/browse/models/by-model-drivers [CMake build]: diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index 67ab0b6c07..c5d42403e3 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -31,14 +31,10 @@ element or alloy and set of parameters, e.g. EAM for Cu with a specific EAM potential file. See the current list of "KIM model -drivers"_https://openkim.org/kim-items/model-drivers/alphabetical. +drivers"_https://openkim.org/browse/model-drivers/alphabetical. See the current list of all "KIM -models"_https://openkim.org/kim-items/models/by-model-drivers - -See the list of "example KIM models"_https://openkim.org/kim-api which -are included in the KIM library by default, in the "What is in the KIM -API source package?" section. +models"_https://openkim.org/browse/models/by-model-drivers To use this pair style, you must first download and install the KIM API library from the "OpenKIM website"_https://openkim.org. The KIM diff --git a/lib/kim/Install.py b/lib/kim/Install.py index 7a3d9c148d..dfb6bc53dc 100644 --- a/lib/kim/Install.py +++ b/lib/kim/Install.py @@ -40,10 +40,10 @@ make lib-kim args="-b -a everything" # install KIM API lib with all models make lib-kim args="-n -a EAM_Dynamo_Ackland_2003_W__MO_141627196590_005" # only add one model or model driver See the list of KIM model drivers here: -https://openkim.org/kim-items/model-drivers/alphabetical +https://openkim.org/browse/model-drivers/alphabetical See the list of all KIM models here: -https://openkim.org/kim-items/models/by-model-drivers +https://openkim.org/browse/models/by-model-drivers """ pgroup = parser.add_mutually_exclusive_group() -- GitLab From 9a6dc2ff11dd846f4e2cf7b4cada63af21dcb110 Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Wed, 6 Mar 2019 13:54:32 -0700 Subject: [PATCH 0200/1243] Removed several files that should not have been included --- src/GRANULAR/pair_gran_dmt_rolling.cpp | 721 -------- src/GRANULAR/pair_gran_dmt_rolling.h | 55 - src/GRANULAR/pair_gran_dmt_rolling2.cpp | 719 -------- .../pair_gran_hooke_history_multi.cpp | 915 ---------- src/GRANULAR/pair_gran_hooke_history_multi.h | 109 -- src/GRANULAR/pair_gran_jkr_rolling.cpp | 763 -------- src/GRANULAR/pair_gran_jkr_rolling.h | 56 - src/GRANULAR/pair_gran_jkr_rolling_multi.cpp | 1181 ------------ src/GRANULAR/pair_gran_jkr_rolling_multi.h | 87 - src/GRANULAR/pair_granular_multi.cpp | 1624 ----------------- src/GRANULAR/pair_granular_multi.h | 107 -- 11 files changed, 6337 deletions(-) delete mode 100644 src/GRANULAR/pair_gran_dmt_rolling.cpp delete mode 100644 src/GRANULAR/pair_gran_dmt_rolling.h delete mode 100644 src/GRANULAR/pair_gran_dmt_rolling2.cpp delete mode 100644 src/GRANULAR/pair_gran_hooke_history_multi.cpp delete mode 100644 src/GRANULAR/pair_gran_hooke_history_multi.h delete mode 100644 src/GRANULAR/pair_gran_jkr_rolling.cpp delete mode 100644 src/GRANULAR/pair_gran_jkr_rolling.h delete mode 100644 src/GRANULAR/pair_gran_jkr_rolling_multi.cpp delete mode 100644 src/GRANULAR/pair_gran_jkr_rolling_multi.h delete mode 100644 src/GRANULAR/pair_granular_multi.cpp delete mode 100644 src/GRANULAR/pair_granular_multi.h diff --git a/src/GRANULAR/pair_gran_dmt_rolling.cpp b/src/GRANULAR/pair_gran_dmt_rolling.cpp deleted file mode 100644 index f293998e92..0000000000 --- a/src/GRANULAR/pair_gran_dmt_rolling.cpp +++ /dev/null @@ -1,721 +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: Leo Silbert (SNL), Gary Grest (SNL) - ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "pair_gran_dmt_rolling.h" -#include "atom.h" -#include "update.h" -#include "force.h" -#include "fix.h" -#include "fix_neigh_history.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "comm.h" -#include "memory.h" -#include "error.h" -#include "math_const.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -#define TWOTHIRDS 0.6666666666666666 -#define EPSILON 1e-10 - -enum {TSUJI, BRILLIANTOV}; -enum {INDEP, BRILLROLL}; - -/* ---------------------------------------------------------------------- */ - -PairGranDMTRolling::PairGranDMTRolling(LAMMPS *lmp) : - PairGranHookeHistory(lmp, 7), - E_one(0), G_one(0), pois(0), muS_one(0), cor(0), alpha_one(0), - Ecoh_one(0), kR_one(0), muR_one(0), etaR_one(0) -{ - int ntypes = atom->ntypes; - memory->create(E,ntypes+1,ntypes+1,"pair:E"); - memory->create(G,ntypes+1,ntypes+1,"pair:G"); - memory->create(alpha,ntypes+1,ntypes+1,"pair:alpha"); - memory->create(gamman,ntypes+1,ntypes+1,"pair:gamman"); - memory->create(muS,ntypes+1,ntypes+1,"pair:muS"); - memory->create(Ecoh,ntypes+1,ntypes+1,"pair:Ecoh"); - memory->create(kR,ntypes+1,ntypes+1,"pair:kR"); - memory->create(muR,ntypes+1,ntypes+1,"pair:muR"); - memory->create(etaR,ntypes+1,ntypes+1,"pair:etaR"); -} - -/* ---------------------------------------------------------------------- */ -PairGranDMTRolling::~PairGranDMTRolling() -{ - delete [] E_one; - delete [] G_one; - delete [] pois; - delete [] muS_one; - delete [] cor; - delete [] alpha_one; - delete [] Ecoh_one; - delete [] kR_one; - delete [] muR_one; - delete [] etaR_one; - //TODO: Make all this work with standard pair coeff type commands. - //Also these should not be in the destructor. - memory->destroy(E); - memory->destroy(G); - memory->destroy(alpha); - memory->destroy(gamman); - memory->destroy(muS); - memory->destroy(Ecoh); - memory->destroy(kR); - memory->destroy(muR); - memory->destroy(etaR); -} -/* ---------------------------------------------------------------------- */ - -void PairGranDMTRolling::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum; - int itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; - double Fhz, Fdamp, Fdmt, Fne, Fntot, Fscrit, Frcrit; - double overlap; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - double signtwist, magtwist, magtortwist, Mtcrit; - double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; - double tortwist1, tortwist2, tortwist3; - double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *shear,*allshear,**firstshear; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int shearupdate = 1; - if (update->setupflag) shearupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - 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 *type = atom->type; - int *mask = atom->mask; - int nlocal = atom->nlocal; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firstshear = fix_history->firstvalue; - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - 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]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - jtype = type[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]; - radsum = radi + radj; - - if (rsq >= radsum*radsum){ - // unset non-touching neighbors - touch[jj] = 0; - shear = &allshear[size_history*jj]; - for (int k = 0; k < size_history; k++) - shear[k] = 0.0; - } else { - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/(radi+radj); - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - //**************************************** - //Normal force = Hertzian contact + DMT + damping - //**************************************** - overlap = radsum - r; - a = sqrt(R*overlap); - kn = 4.0/3.0*E[itype][jtype]*a; - Fhz = kn*overlap; - - //Damping (based on Tsuji et al) - if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - //DMT - Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; - - Fne = Fhz + Fdmt; - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including shear history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting - //delta/2, i.e. instead of radi, use distance to center of contact point? - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - touch[jj] = 1; - shear = &allshear[size_history*jj]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // Rotate and update shear displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (shearupdate) { - rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - shear[0] -= rsht*nx; - shear[1] -= rsht*ny; - shear[2] -= rsht*nz; - //Also rescale to preserve magnitude - shear[0] *= scalefac; - shear[1] *= scalefac; - shear[2] *= scalefac; - } - //Update shear history - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; - } - - // tangential forces = shear + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = muS[itype][jtype] * fabs(Fne); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - //**************************************** - // Rolling force, including shear history effects - //**************************************** - - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - - if (shearupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - shear[3] -= rolldotn*nx; - shear[4] -= rolldotn*ny; - shear[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - shear[3] *= scalefac; - shear[4] *= scalefac; - shear[5] *= scalefac; - } - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; - } - - k_R = kR[itype][jtype]; - if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; - else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); - fr1 = -k_R*shear[3] - eta_R*vrl1; - fr2 = -k_R*shear[4] - eta_R*vrl2; - fr3 = -k_R*shear[5] - eta_R*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR[itype][jtype] * fabs(Fne); - - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - - - //**************************************** - // Twisting torque, including shear history effects - //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - shear[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit){ - shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - - if (force->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; - - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } -} - -/* ---------------------------------------------------------------------- - global settings - ------------------------------------------------------------------------- */ - -void PairGranDMTRolling::settings(int narg, char **arg) -{ - if (narg < 6) error->all(FLERR,"Illegal pair_style command"); - - int ntypes = atom->ntypes; - - if (narg < 8*ntypes) error->all(FLERR,"Illegal pair_style command"); - - E_one = new double[ntypes+1]; - G_one = new double[ntypes+1]; - pois = new double[ntypes+1]; - muS_one = new double[ntypes+1]; - cor = new double[ntypes+1]; - alpha_one = new double[ntypes+1]; - Ecoh_one = new double[ntypes+1]; - kR_one = new double[ntypes+1]; - muR_one = new double[ntypes+1]; - etaR_one = new double[ntypes+1]; - - for (int i=0; i < ntypes;i++){ - E_one[i+1] = force->numeric(FLERR, arg[i]); - G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); - muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); - cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); - Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); - kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); - muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); - etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); - } - - //Defaults - normaldamp = TSUJI; - rollingdamp = INDEP; - - int iarg = 8*ntypes; - while (iarg < narg){ - if (strcmp(arg[iarg],"normaldamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else if (strcmp(arg[iarg],"rollingdamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else{ - iarg +=1; - } - } - - //Derived from inputs - for (int i=1; i <= ntypes; i++){ - pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; - alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; - for (int j=i; j <= ntypes; j++){ - E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); - G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); - if (normaldamp == TSUJI){ - alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); - } - else if (normaldamp == BRILLIANTOV){ - gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); - } - muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); - Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); - kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); - etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); - muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); - } - } -} - -/* ---------------------------------------------------------------------- */ - -double PairGranDMTRolling::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - double &fforce) -{ - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double overlap, a; - double mi,mj,meff,damp,kn,kt; - double Fhz,Fdamp,Fdmt,Fne,Fntot,Fscrit; - double eta_N,eta_T; - double vtr1,vtr2,vtr3,vrel; - double fs1,fs2,fs3,fs; - double shrmag; - - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - - if (rsq >= radsum*radsum) { - fforce = 0.0; - svector[0] = svector[1] = svector[2] = svector[3] = 0.0; - return 0.0; - } - - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/radsum; - - // relative translational velocity - - double **v = atom->v; - vr1 = v[i][0] - v[j][0]; - vr2 = v[i][1] - v[j][1]; - vr3 = v[i][2] - v[j][2]; - - // normal component - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - - vnnr = vr1*nx + vr2*ny + vr3*nz; - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // tangential component - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - double **omega = atom->omega; - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - double *rmass = atom->rmass; - int *type = atom->type; - int *mask = atom->mask; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - - // normal force = Hertzian contact + normal velocity damping - overlap = radsum - r; - a = sqrt(R*overlap); - kn = 4.0/3.0*E[itype][jtype]*a; - Fhz = kn*overlap; - - //Damping (based on Tsuji et al) - - eta_N=alpha[itype][jtype]*sqrt(meff*kn); - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - //DMT - Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; - - Fne = Fhz + Fdmt; - Fntot = Fne + Fdamp; - - // relative velocities - - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - // neighprev = index of found neigh on previous call - // search entire jnum list of neighbors of I for neighbor J - // start from neighprev, since will typically be next neighbor - // reset neighprev to 0 as necessary - - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allshear = fix_history->firstvalue[i]; - - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - - double *shear = &allshear[size_history*neighprev]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // tangential forces = shear + tangential velocity damping - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; - fs1 = -kt*shear[0] - eta_T*vtr1; - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - Fscrit= muS[itype][jtype] * fabs(Fne); - - if (fs > Fscrit) { - if (shrmag != 0.0) { - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - fs *= Fscrit/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; - } - - // set all forces and return no energy - - fforce = Fntot; - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = vn1; - svector[5] = vn2; - svector[6] = vn3; - svector[7] = vt1; - svector[8] = vt2; - svector[9] = vt3; - return 0.0; -} diff --git a/src/GRANULAR/pair_gran_dmt_rolling.h b/src/GRANULAR/pair_gran_dmt_rolling.h deleted file mode 100644 index 8f4ae2005e..0000000000 --- a/src/GRANULAR/pair_gran_dmt_rolling.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- 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(gran/dmt/rolling,PairGranDMTRolling) - -#else - -#ifndef LMP_PAIR_GRAN_DMT_ROLLING_H -#define LMP_PAIR_GRAN_DMT_ROLLING_H - -#include "pair_gran_hooke_history.h" - -namespace LAMMPS_NS { - -class PairGranDMTRolling : public PairGranHookeHistory { -public: - PairGranDMTRolling(class LAMMPS *); - virtual ~PairGranDMTRolling(); - virtual void compute(int, int); - void settings(int, char **); //Eventually set this through coeff method so that user can specify a particular i-j set of coefficients - double single(int, int, int, int, double, double, double, double &); - double *E_one, *G_one, *pois, *muS_one, *cor, *alpha_one, *Ecoh_one, *kR_one, *muR_one, *etaR_one; //Public so as to be accessible to fix/wall/gran -private: - double **E, **G, **alpha, **muS, **Ecoh, **kR, **muR, **etaR, **gamman; - int normaldamp, rollingdamp; - - -}; - -} - -#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. - - */ diff --git a/src/GRANULAR/pair_gran_dmt_rolling2.cpp b/src/GRANULAR/pair_gran_dmt_rolling2.cpp deleted file mode 100644 index 5c1211cbc5..0000000000 --- a/src/GRANULAR/pair_gran_dmt_rolling2.cpp +++ /dev/null @@ -1,719 +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: Leo Silbert (SNL), Gary Grest (SNL) - ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "pair_gran_dmt_rolling.h" -#include "atom.h" -#include "update.h" -#include "force.h" -#include "fix.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "comm.h" -#include "memory.h" -#include "error.h" -#include "math_const.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -#define TWOTHIRDS 0.6666666666666666 -#define EPSILON 1e-10 - -enum {TSUJI, BRILLIANTOV}; -enum {INDEP, BRILLROLL}; - -/* ---------------------------------------------------------------------- */ - -PairGranDMTRolling::PairGranDMTRolling(LAMMPS *lmp) : - PairGranHookeHistory(lmp, 7), - E_one(0), G_one(0), pois(0), muS_one(0), cor(0), alpha_one(0), - Ecoh_one(0), kR_one(0), muR_one(0), etaR_one(0) -{ - int ntypes = atom->ntypes; - memory->create(E,ntypes+1,ntypes+1,"pair:E"); - memory->create(G,ntypes+1,ntypes+1,"pair:G"); - memory->create(alpha,ntypes+1,ntypes+1,"pair:alpha"); - memory->create(gamman,ntypes+1,ntypes+1,"pair:gamman"); - memory->create(muS,ntypes+1,ntypes+1,"pair:muS"); - memory->create(Ecoh,ntypes+1,ntypes+1,"pair:Ecoh"); - memory->create(kR,ntypes+1,ntypes+1,"pair:kR"); - memory->create(muR,ntypes+1,ntypes+1,"pair:muR"); - memory->create(etaR,ntypes+1,ntypes+1,"pair:etaR"); -} - -/* ---------------------------------------------------------------------- */ -PairGranDMTRolling::~PairGranDMTRolling() -{ - delete [] E_one; - delete [] G_one; - delete [] pois; - delete [] muS_one; - delete [] cor; - delete [] alpha_one; - delete [] Ecoh_one; - delete [] kR_one; - delete [] muR_one; - delete [] etaR_one; - //TODO: Make all this work with standard pair coeff type commands. - //Also these should not be in the destructor. - memory->destroy(E); - memory->destroy(G); - memory->destroy(alpha); - memory->destroy(gamman); - memory->destroy(muS); - memory->destroy(Ecoh); - memory->destroy(kR); - memory->destroy(muR); - memory->destroy(etaR); -} -/* ---------------------------------------------------------------------- */ - -void PairGranDMTRolling::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum; - int itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; - double Fhz, Fdamp, Fdmt, Fne, Fntot, Fscrit, Frcrit; - double overlap; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - double signtwist, magtwist, magtortwist, Mtcrit; - double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; - double tortwist1, tortwist2, tortwist3; - double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *shear,*allshear,**firstshear; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int shearupdate = 1; - if (update->setupflag) shearupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - 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 *type = atom->type; - int *mask = atom->mask; - int nlocal = atom->nlocal; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = list->listhistory->firstneigh; - firstshear = list->listhistory->firstdouble; - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - 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]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - jtype = type[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]; - radsum = radi + radj; - - if (rsq >= radsum*radsum){ - // unset non-touching neighbors - touch[jj] = 0; - shear = &allshear[nsheardim*jj]; - for (int k = 0; k < nsheardim; k++) - shear[k] = 0.0; - } else { - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/(radi+radj); - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - //**************************************** - //Normal force = Hertzian contact + DMT + damping - //**************************************** - overlap = radsum - r; - a = sqrt(R*overlap); - kn = 4.0/3.0*E[itype][jtype]*a; - Fhz = kn*overlap; - - //Damping (based on Tsuji et al) - if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - //DMT - Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; - - Fne = Fhz + Fdmt; - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including shear history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting - //delta/2, i.e. instead of radi, use distance to center of contact point? - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - touch[jj] = 1; - shear = &allshear[nsheardim*jj]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // Rotate and update shear displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (shearupdate) { - rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - shear[0] -= rsht*nx; - shear[1] -= rsht*ny; - shear[2] -= rsht*nz; - //Also rescale to preserve magnitude - shear[0] *= scalefac; - shear[1] *= scalefac; - shear[2] *= scalefac; - } - //Update shear history - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; - } - - // tangential forces = shear + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = muS[itype][jtype] * fabs(Fne); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - //**************************************** - // Rolling force, including shear history effects - //**************************************** - - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - - if (shearupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - shear[3] -= rolldotn*nx; - shear[4] -= rolldotn*ny; - shear[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - shear[3] *= scalefac; - shear[4] *= scalefac; - shear[5] *= scalefac; - } - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; - } - - k_R = kR[itype][jtype]; - if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; - else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); - fr1 = -k_R*shear[3] - eta_R*vrl1; - fr2 = -k_R*shear[4] - eta_R*vrl2; - fr3 = -k_R*shear[5] - eta_R*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR[itype][jtype] * fabs(Fne); - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - - - //**************************************** - // Twisting torque, including shear history effects - //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - shear[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit){ - shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - - if (force->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; - - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } -} - -/* ---------------------------------------------------------------------- - global settings - ------------------------------------------------------------------------- */ - -void PairGranDMTRolling::settings(int narg, char **arg) -{ - if (narg < 6) error->all(FLERR,"Illegal pair_style command"); - - int ntypes = atom->ntypes; - - if (narg < 8*ntypes) error->all(FLERR,"Illegal pair_style command"); - - E_one = new double[ntypes+1]; - G_one = new double[ntypes+1]; - pois = new double[ntypes+1]; - muS_one = new double[ntypes+1]; - cor = new double[ntypes+1]; - alpha_one = new double[ntypes+1]; - Ecoh_one = new double[ntypes+1]; - kR_one = new double[ntypes+1]; - muR_one = new double[ntypes+1]; - etaR_one = new double[ntypes+1]; - - for (int i=0; i < ntypes;i++){ - E_one[i+1] = force->numeric(FLERR, arg[i]); - G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); - muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); - cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); - Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); - kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); - muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); - etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); - } - - //Defaults - normaldamp = TSUJI; - rollingdamp = INDEP; - - int iarg = 8*ntypes; - while (iarg < narg){ - if (strcmp(arg[iarg],"normaldamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else if (strcmp(arg[iarg],"rollingdamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else{ - iarg +=1; - } - } - - //Derived from inputs - for (int i=1; i <= ntypes; i++){ - pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; - alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; - for (int j=i; j <= ntypes; j++){ - E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); - G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); - if (normaldamp == TSUJI){ - alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); - } - else if (normaldamp == BRILLIANTOV){ - gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); - } - muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); - Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); - kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); - etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); - muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); - } - } -} - -/* ---------------------------------------------------------------------- */ - -double PairGranDMTRolling::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - double &fforce) -{ - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double overlap, a; - double mi,mj,meff,damp,kn,kt; - double Fhz,Fdamp,Fdmt,Fne,Fntot,Fscrit; - double eta_N,eta_T; - double vtr1,vtr2,vtr3,vrel; - double fs1,fs2,fs3,fs; - double shrmag; - - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - - if (rsq >= radsum*radsum) { - fforce = 0.0; - svector[0] = svector[1] = svector[2] = svector[3] = 0.0; - return 0.0; - } - - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/radsum; - - // relative translational velocity - - double **v = atom->v; - vr1 = v[i][0] - v[j][0]; - vr2 = v[i][1] - v[j][1]; - vr3 = v[i][2] - v[j][2]; - - // normal component - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - - vnnr = vr1*nx + vr2*ny + vr3*nz; - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // tangential component - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - double **omega = atom->omega; - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - double *rmass = atom->rmass; - int *type = atom->type; - int *mask = atom->mask; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - - // normal force = Hertzian contact + normal velocity damping - overlap = radsum - r; - a = sqrt(R*overlap); - kn = 4.0/3.0*E[itype][jtype]*a; - Fhz = kn*overlap; - - //Damping (based on Tsuji et al) - - eta_N=alpha[itype][jtype]*sqrt(meff*kn); - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - //DMT - Fdmt = -4*MY_PI*Ecoh[itype][jtype]*R; - - Fne = Fhz + Fdmt; - Fntot = Fne + Fdamp; - - // relative velocities - - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - // neighprev = index of found neigh on previous call - // search entire jnum list of neighbors of I for neighbor J - // start from neighprev, since will typically be next neighbor - // reset neighprev to 0 as necessary - - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allshear = list->listhistory->firstdouble[i]; - - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - - double *shear = &allshear[nsheardim*neighprev]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // tangential forces = shear + tangential velocity damping - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; - fs1 = -kt*shear[0] - eta_T*vtr1; - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - Fscrit= muS[itype][jtype] * fabs(Fne); - - if (fs > Fscrit) { - if (shrmag != 0.0) { - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - fs *= Fscrit/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; - } - - // set all forces and return no energy - - fforce = Fntot; - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = vn1; - svector[5] = vn2; - svector[6] = vn3; - svector[7] = vt1; - svector[8] = vt2; - svector[9] = vt3; - return 0.0; -} diff --git a/src/GRANULAR/pair_gran_hooke_history_multi.cpp b/src/GRANULAR/pair_gran_hooke_history_multi.cpp deleted file mode 100644 index 48e793bbb3..0000000000 --- a/src/GRANULAR/pair_gran_hooke_history_multi.cpp +++ /dev/null @@ -1,915 +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: Leo Silbert (SNL), Gary Grest (SNL) -------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "pair_gran_hooke_history_multi.h" -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "modify.h" -#include "fix.h" -#include "fix_neigh_history.h" -#include "comm.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -#define BIG 1.0e20 - -/* ---------------------------------------------------------------------- */ - -PairGranHookeHistoryMulti::PairGranHookeHistoryMulti(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 1; - no_virial_fdotr_compute = 1; - history = 1; - fix_history = NULL; - - single_extra = 10; - svector = new double[10]; - - neighprev = 0; - - nmax = 0; - mass_rigid = NULL; - - // set comm size needed by this Pair if used with fix rigid - - comm_forward = 1; -} - -/* ---------------------------------------------------------------------- */ - -PairGranHookeHistoryMulti::~PairGranHookeHistoryMulti() -{ - delete [] svector; - if (fix_history) modify->delete_fix("NEIGH_HISTORY"); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut); - memory->destroy(kn); - memory->destroy(kt); - memory->destroy(gamman); - memory->destroy(gammat); - memory->destroy(xmu); - memory->destroy(dampflag); - - delete [] onerad_dynamic; - delete [] onerad_frozen; - delete [] maxrad_dynamic; - delete [] maxrad_frozen; - } - memory->destroy(mass_rigid); -} - -/* ---------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,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 mi,mj,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; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int shearupdate = 1; - if (update->setupflag) shearupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0) { - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - double **x = atom->x; - double **v = atom->v; - double **f = atom->f; - int *type = atom->type; - 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 newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firstshear = fix_history->firstvalue; - - // 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]; - radi = radius[i]; - touch = firsttouch[i]; - allshear = firstshear[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]; - 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; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - // normal forces = Hookian contact + normal velocity damping - - damp = meff*gamman[itype][jtype]*vnnr*rsqinv; - ccel = kn[itype][jtype]*(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[itype][jtype]*shear[0] + meff*gammat[itype][jtype]*vtr1); - fs2 = - (kt[itype][jtype]*shear[1] + meff*gammat[itype][jtype]*vtr2); - fs3 = - (kt[itype][jtype]*shear[2] + meff*gammat[itype][jtype]*vtr3); - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - fn = xmu[itype][jtype] * fabs(ccel*r); - - if (fs > fn) { - if (shrmag != 0.0) { - shear[0] = (fn/fs) * (shear[0] + - meff*gammat[itype][jtype]*vtr1/kt[itype][jtype]) - - meff*gammat[itype][jtype]*vtr1/kt[itype][jtype]; - shear[1] = (fn/fs) * (shear[1] + - meff*gammat[itype][jtype]*vtr2/kt[itype][jtype]) - - meff*gammat[itype][jtype]*vtr2/kt[itype][jtype]; - shear[2] = (fn/fs) * (shear[2] + - meff*gammat[itype][jtype]*vtr3/kt[itype][jtype]) - - meff*gammat[itype][jtype]*vtr3/kt[itype][jtype]; - fs1 *= fn/fs; - fs2 *= fn/fs; - fs3 *= fn/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - // forces & torques - - fx = delx*ccel + fs1; - fy = dely*ccel + fs2; - fz = delz*ccel + fs3; - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = rinv * (dely*fs3 - delz*fs2); - tor2 = rinv * (delz*fs1 - delx*fs3); - tor3 = rinv * (delx*fs2 - dely*fs1); - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= 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(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 PairGranHookeHistoryMulti::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(kn,n+1,n+1,"pair:kn"); - memory->create(kt,n+1,n+1,"pair:kt"); - memory->create(gamman,n+1,n+1,"pair:gamman"); - memory->create(gammat,n+1,n+1,"pair:gammat"); - memory->create(xmu,n+1,n+1,"pair:xmu"); - memory->create(dampflag,n+1,n+1,"pair:dampflag"); - - onerad_dynamic = new double[n+1]; - onerad_frozen = new double[n+1]; - maxrad_dynamic = new double[n+1]; - maxrad_frozen = new double[n+1]; -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::settings(int narg, char **arg) -{ - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); - - if (strcmp(arg[0],"NULL") == 0 ) cut_global = -1.0; - else cut_global = force->numeric(FLERR,arg[0]); - - // reset cutoffs that have been explicitly set - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::coeff(int narg, char **arg) -{ - if (narg < 8 || narg > 9) - error->all(FLERR,"Incorrect args for pair coefficients"); - - if (!allocated) allocate(); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - double kn_one = force->numeric(FLERR,arg[2]); - double kt_one; - if (strcmp(arg[3],"NULL") == 0) kt_one = kn_one * 2.0/7.0; - else kt_one = force->numeric(FLERR,arg[3]); - - double gamman_one = force->numeric(FLERR,arg[4]); - double gammat_one; - if (strcmp(arg[5],"NULL") == 0) gammat_one = 0.5 * gamman_one; - else gammat_one = force->numeric(FLERR,arg[5]); - - double xmu_one = force->numeric(FLERR,arg[6]); - int dampflag_one = force->inumeric(FLERR,arg[7]); - if (dampflag_one == 0) gammat_one = 0.0; - - if (kn_one < 0.0 || kt_one < 0.0 || gamman_one < 0.0 || gammat_one < 0.0 || - xmu_one < 0.0 || xmu_one > 10000.0 || dampflag_one < 0 || dampflag_one > 1) - error->all(FLERR,"Illegal pair_style command"); - - // convert Kn and Kt from pressure units to force/distance^2 - kn_one /= force->nktv2p; - kt_one /= force->nktv2p; - - double cut_one = cut_global; - if (narg==9) { - if (strcmp(arg[8],"NULL") == 0) cut_one = -1.0; - else cut_one = force->numeric(FLERR,arg[8]); - } - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - kn[i][j] = kn_one; - kt[i][j] = kt_one; - gamman[i][j] = gamman_one; - gammat[i][j] = gammat_one; - xmu[i][j] = xmu_one; - dampflag[i][j] = dampflag_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 PairGranHookeHistoryMulti::init_style() -{ - int i; - - // error and warning checks - - if (!atom->radius_flag || !atom->rmass_flag) - error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); - if (comm->ghost_velocity == 0) - error->all(FLERR,"Pair granular requires ghost atoms store velocity"); - - // need a granular neigh list - - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->size = 1; - if (history) neighbor->requests[irequest]->history = 1; - - dt = update->dt; - - // if shear history is stored: - // if first init, create Fix needed for storing shear history - - if (history && fix_history == NULL) { - char dnumstr[16]; - sprintf(dnumstr,"%d",3); - char **fixarg = new char*[4]; - fixarg[0] = (char *) "NEIGH_HISTORY"; - fixarg[1] = (char *) "all"; - fixarg[2] = (char *) "NEIGH_HISTORY"; - fixarg[3] = dnumstr; - modify->add_fix(4,fixarg,1); - delete [] fixarg; - fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; - fix_history->pair = this; - } - - // check for FixFreeze and set freeze_group_bit - - for (i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"freeze") == 0) break; - if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; - else freeze_group_bit = 0; - - // check for FixRigid so can extract rigid body masses - - fix_rigid = NULL; - for (i = 0; i < modify->nfix; i++) - if (modify->fix[i]->rigid_flag) break; - if (i < modify->nfix) fix_rigid = modify->fix[i]; - - // check for FixPour and FixDeposit so can extract particle radii - - int ipour; - for (ipour = 0; ipour < modify->nfix; ipour++) - if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; - if (ipour == modify->nfix) ipour = -1; - - int idep; - for (idep = 0; idep < modify->nfix; idep++) - if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; - if (idep == modify->nfix) idep = -1; - - // set maxrad_dynamic and maxrad_frozen for each type - // include future FixPour and FixDeposit particles as dynamic - - int itype; - for (i = 1; i <= atom->ntypes; i++) { - onerad_dynamic[i] = onerad_frozen[i] = 0.0; - if (ipour >= 0) { - itype = i; - onerad_dynamic[i] = - *((double *) modify->fix[ipour]->extract("radius",itype)); - } - if (idep >= 0) { - itype = i; - onerad_dynamic[i] = - *((double *) modify->fix[idep]->extract("radius",itype)); - } - } - - double *radius = atom->radius; - int *mask = atom->mask; - int *type = atom->type; - int nlocal = atom->nlocal; - - for (i = 0; i < nlocal; i++) - if (mask[i] & freeze_group_bit) - onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]); - else - onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]); - - MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - - // set fix which stores history info - - if (history) { - int ifix = modify->find_fix("NEIGH_HISTORY"); - if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); - fix_history = (FixNeighHistory *) modify->fix[ifix]; - } -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairGranHookeHistoryMulti::init_one(int i, int j) -{ - if (setflag[i][j] == 0) { - kn[i][j] = mix_stiffness(kn[i][i],kn[j][j]); - kt[i][j] = mix_stiffness(kt[i][i],kt[j][j]); - gamman[i][j] = mix_damping(gamman[i][i],gamman[j][j]); - gammat[i][j] = mix_damping(gammat[i][i],gammat[j][j]); - xmu[i][j] = mix_friction(xmu[i][i],xmu[j][j]); - - dampflag[i][j] = 0; - if (dampflag[i][i] || dampflag[j][j]) dampflag[i][j] = 1; - - } - - kn[j][i] = kn[i][j]; - kt[j][i] = kt[i][j]; - gamman[j][i] = gamman[i][j]; - gammat[j][i] = gammat[i][j]; - xmu[j][i] = xmu[i][j]; - dampflag[j][i] = dampflag[i][j]; - - double cutoff = cut[i][j]; - - // It is likely that cut[i][j] at this point is still 0.0. This can happen when - // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates - // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size - // To avoid this issue,for cases involving cut[i][j] = 0.0 (possible only - // if there is no current information about radius/cutoff of type i and j). - // we assign cutoff = min(cut[i][j]) for i,j such that cut[i][j] > 0.0. - - if (cut[i][j] < 0.0) { - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); - } - cutoff = cutmax; - } - } - return cutoff; -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::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(&kn[i][j],sizeof(double),1,fp); - fwrite(&kt[i][j],sizeof(double),1,fp); - fwrite(&gamman[i][j],sizeof(double),1,fp); - fwrite(&gammat[i][j],sizeof(double),1,fp); - fwrite(&xmu[i][j],sizeof(double),1,fp); - fwrite(&dampflag[i][j],sizeof(int),1,fp); - fwrite(&cut[i][j],sizeof(double),1,fp); - } - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::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(&kn[i][j],sizeof(double),1,fp); - fread(&kt[i][j],sizeof(double),1,fp); - fread(&gamman[i][j],sizeof(double),1,fp); - fread(&gammat[i][j],sizeof(double),1,fp); - fread(&xmu[i][j],sizeof(double),1,fp); - fread(&dampflag[i][j],sizeof(int),1,fp); - fread(&cut[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&kn[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&kt[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&gamman[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&gammat[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&xmu[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&dampflag[i][j],1,MPI_INT,0,world); - } - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file -------------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::write_restart_settings(FILE *fp) -{ - fwrite(&cut_global,sizeof(double),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts -------------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_global,sizeof(double),1,fp); - } - MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); -} - -/* ---------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::reset_dt() -{ - dt = update->dt; -} - -/* ---------------------------------------------------------------------- */ - -double PairGranHookeHistoryMulti::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - double &fforce) -{ - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double mi,mj,meff,damp,ccel; - double vtr1,vtr2,vtr3,vrel,shrmag,rsht; - double fs1,fs2,fs3,fs,fn; - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - - if (rsq >= radsum*radsum) { - fforce = 0.0; - for (int m = 0; m < single_extra; m++) svector[m] = 0.0; - return 0.0; - } - - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - - // relative translational velocity - - double **v = atom->v; - vr1 = v[i][0] - v[j][0]; - vr2 = v[i][1] - v[j][1]; - vr3 = v[i][2] - v[j][2]; - - // normal component - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - - 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 - - double **omega = atom->omega; - 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; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - double *rmass = atom->rmass; - int *mask = atom->mask; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: insure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - // normal forces = Hookian contact + normal velocity damping - - damp = meff*gamman[itype][jtype]*vnnr*rsqinv; - ccel = kn[itype][jtype]*(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 - // neighprev = index of found neigh on previous call - // search entire jnum list of neighbors of I for neighbor J - // start from neighprev, since will typically be next neighbor - // reset neighprev to 0 as necessary - - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allshear = fix_history->firstvalue[i]; - - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - - double *shear = &allshear[3*neighprev]; - 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; - - // tangential forces = shear + tangential velocity damping - - fs1 = - (kt[itype][jtype]*shear[0] + meff*gammat[itype][jtype]*vtr1); - fs2 = - (kt[itype][jtype]*shear[1] + meff*gammat[itype][jtype]*vtr2); - fs3 = - (kt[itype][jtype]*shear[2] + meff*gammat[itype][jtype]*vtr3); - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - fn = xmu[itype][jtype] * fabs(ccel*r); - - if (fs > fn) { - if (shrmag != 0.0) { - fs1 *= fn/fs; - fs2 *= fn/fs; - fs3 *= fn/fs; - fs *= fn/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; - } - - // set force and return no energy - - fforce = ccel; - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = vn1; - svector[5] = vn2; - svector[6] = vn3; - svector[7] = vt1; - svector[8] = vt2; - svector[9] = vt3; - - return 0.0; -} - -/* ---------------------------------------------------------------------- */ - -int PairGranHookeHistoryMulti::pack_forward_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++] = mass_rigid[j]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void PairGranHookeHistoryMulti::unpack_forward_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) - mass_rigid[i] = buf[m++]; -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays -------------------------------------------------------------------------- */ - -double PairGranHookeHistoryMulti::memory_usage() -{ - double bytes = nmax * sizeof(double); - return bytes; -} - -/* ---------------------------------------------------------------------- - mixing of stiffness -------------------------------------------------------------------------- */ - -double PairGranHookeHistoryMulti::mix_stiffness(double kii, double kjj) -{ - return kii*kjj/(kii + kjj); -} - -/* ---------------------------------------------------------------------- - mixing of damping -------------------------------------------------------------------------- */ - -double PairGranHookeHistoryMulti::mix_damping(double gammaii, double gammajj) -{ - return sqrt(gammaii*gammajj); -} - -/* ---------------------------------------------------------------------- - mixing of friction -------------------------------------------------------------------------- */ - -double PairGranHookeHistoryMulti::mix_friction(double xmuii, double xmujj) -{ - return MAX(xmuii,xmujj); -} - diff --git a/src/GRANULAR/pair_gran_hooke_history_multi.h b/src/GRANULAR/pair_gran_hooke_history_multi.h deleted file mode 100644 index f302ede96c..0000000000 --- a/src/GRANULAR/pair_gran_hooke_history_multi.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- 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(gran/hooke/history/multi,PairGranHookeHistoryMulti) - -#else - -#ifndef LMP_PAIR_GRAN_HOOKE_HISTORY_MULTI_H -#define LMP_PAIR_GRAN_HOOKE_HISTORY_MULTI_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairGranHookeHistoryMulti : public Pair { - public: - PairGranHookeHistoryMulti(class LAMMPS *); - virtual ~PairGranHookeHistoryMulti(); - virtual void compute(int, int); - virtual void settings(int, char **); - virtual void coeff(int, char **); // Made Virtual by IS Oct 7 2017 - void init_style(); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); - void reset_dt(); - virtual double single(int, int, int, int, double, double, double, double &); - int pack_forward_comm(int, int *, double *, int, int *); - void unpack_forward_comm(int, int, double *); - double memory_usage(); - - protected: - double cut_global; - double **kn,**kt,**gamman,**gammat,**xmu,**cut; - int **dampflag; - double dt; - int freeze_group_bit; - int history; - - int neighprev; - double *onerad_dynamic,*onerad_frozen; - double *maxrad_dynamic,*maxrad_frozen; - - class FixNeighHistory *fix_history; - - // storage of rigid body masses for use in granular interactions - - class Fix *fix_rigid; // ptr to rigid body fix, NULL if none - double *mass_rigid; // rigid mass for owned+ghost atoms - int nmax; // allocated size of mass_rigid - - virtual void allocate(); // Made Virtual by IS Oct 7 2017 - -private: - double mix_stiffness(double kii, double kjj); - double mix_damping(double gammaii, double gammajj); - double mix_friction(double xmuii, double xmujj); -}; - -} - -#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. - -E: Incorrect args for pair coefficients - -Self-explanatory. Check the input script or data file. - -E: Pair granular requires atom attributes radius, rmass - -The atom style defined does not have these attributes. - -E: Pair granular requires ghost atoms store velocity - -Use the comm_modify vel yes command to enable this. - -E: Pair granular with shear history requires newton pair off - -This is a current restriction of the implementation of pair -granular styles with history. - -E: Could not find pair fix ID - -A fix is created internally by the pair style to store shear -history information. You cannot delete it. - -*/ diff --git a/src/GRANULAR/pair_gran_jkr_rolling.cpp b/src/GRANULAR/pair_gran_jkr_rolling.cpp deleted file mode 100644 index ce109cccbc..0000000000 --- a/src/GRANULAR/pair_gran_jkr_rolling.cpp +++ /dev/null @@ -1,763 +0,0 @@ -/* ---------------------------------------------------------------------- - 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: Leo Silbert (SNL), Gary Grest (SNL) - ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "pair_gran_jkr_rolling.h" -#include "atom.h" -#include "update.h" -#include "force.h" -#include "fix.h" -#include "fix_neigh_history.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "comm.h" -#include "memory.h" -#include "error.h" -#include "math_const.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -#define ONETHIRD 0.33333333333333333 -#define TWOTHIRDS 0.66666666666666666 -#define POW6ONE 0.550321208149104 //6^(-1/3) -#define POW6TWO 0.30285343213869 //6^(-2/3) - -#define EPSILON 1e-10 - -enum {TSUJI, BRILLIANTOV}; -enum {INDEP, BRILLROLL}; - -/* ---------------------------------------------------------------------- */ - -PairGranJKRRolling::PairGranJKRRolling(LAMMPS *lmp) : - PairGranHookeHistory(lmp, 7) -{ - E_one = NULL; - G_one = NULL; - pois = NULL; - muS_one = NULL; - cor = NULL; - alpha_one = NULL; - Ecoh_one = NULL; - kR_one = NULL; - muR_one = NULL; - etaR_one = NULL; - int ntypes = atom->ntypes; - memory->create(E,ntypes+1,ntypes+1,"pair:E"); - memory->create(G,ntypes+1,ntypes+1,"pair:G"); - memory->create(alpha,ntypes+1,ntypes+1,"pair:alpha"); - memory->create(gamman,ntypes+1,ntypes+1,"pair:gamman"); - memory->create(muS,ntypes+1,ntypes+1,"pair:muS"); - memory->create(Ecoh,ntypes+1,ntypes+1,"pair:Ecoh"); - memory->create(kR,ntypes+1,ntypes+1,"pair:kR"); - memory->create(muR,ntypes+1,ntypes+1,"pair:muR"); - memory->create(etaR,ntypes+1,ntypes+1,"pair:etaR"); -} - -/* ---------------------------------------------------------------------- */ -PairGranJKRRolling::~PairGranJKRRolling() -{ - delete [] E_one; - delete [] G_one; - delete [] pois; - delete [] muS_one; - delete [] cor; - delete [] alpha_one; - delete [] Ecoh_one; - delete [] kR_one; - delete [] muR_one; - delete [] etaR_one; - //TODO: Make all this work with standard pair coeff type commands. - //Also these should not be in the destructor. - memory->destroy(E); - memory->destroy(G); - memory->destroy(alpha); - memory->destroy(gamman); - memory->destroy(muS); - memory->destroy(Ecoh); - memory->destroy(kR); - memory->destroy(muR); - memory->destroy(etaR); -} -/* ---------------------------------------------------------------------- */ - -void PairGranJKRRolling::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum; - int itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; - double Fne, Fdamp, Fntot, Fscrit, Frcrit, F_C, delta_C, delta_Cinv; - double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; - double keyterm, keyterm2, keyterm3, aovera0, foverFc; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - double signtwist, magtwist, magtortwist, Mtcrit; - double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; - double tortwist1, tortwist2, tortwist3; - double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *shear,*allshear,**firstshear; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int shearupdate = 1; - if (update->setupflag) shearupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - 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 *type = atom->type; - int *mask = atom->mask; - int nlocal = atom->nlocal; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firstshear = fix_history->firstvalue; - - // loop over neighbors of my atoms - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - 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]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - jtype = type[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]; - radsum = radi + radj; - R = radi*radj/(radi+radj); - a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); - delta_C = 0.5*a0*a0*POW6ONE/R; - - if ((rsq >= radsum*radsum && touch[jj] == 0) || - (rsq >= (radsum+delta_C)*(radsum+delta_C))){ - // unset non-touching neighbors - touch[jj] = 0; - shear = &allshear[size_history*jj]; - for (int k = 0; k < size_history; k++) - shear[k] = 0.0; - } else { - F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - //**************************************** - //Normal force = JKR-adjusted Hertzian contact + damping - //**************************************** - if (Ecoh[itype][jtype] != 0.0) delta_Cinv = 1.0/delta_C; - else delta_Cinv = 1.0; - overlap = (radsum - r)*delta_Cinv; - olapsq = overlap*overlap; - olapcubed = olapsq*overlap; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,ONETHIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = POW6TWO * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 - a = aovera0*a0; - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) - - Fne = F_C*foverFc; - - //Damping - kn = 4.0/3.0*E[itype][jtype]*a; - if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including shear history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - //Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting - //delta/2, i.e. instead of radi, use distance to center of contact point? - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - touch[jj] = 1; - shear = &allshear[size_history*jj]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // Rotate and update shear displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (shearupdate) { - rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - shear[0] -= rsht*nx; - shear[1] -= rsht*ny; - shear[2] -= rsht*nz; - //Also rescale to preserve magnitude - shear[0] *= scalefac; - shear[1] *= scalefac; - shear[2] *= scalefac; - } - //Update shear history - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; - } - - // tangential forces = shear + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = muS[itype][jtype] * fabs(Fne + 2*F_C); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - //**************************************** - // Rolling force, including shear history effects - //**************************************** - - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - - if (shearupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - shear[3] -= rolldotn*nx; - shear[4] -= rolldotn*ny; - shear[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - shear[3] *= scalefac; - shear[4] *= scalefac; - shear[5] *= scalefac; - } - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; - } - - k_R = kR[itype][jtype]*4.0*F_C*pow(aovera0,1.5); - if (rollingdamp == INDEP) eta_R = etaR[itype][jtype]; - else if (rollingdamp == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); - fr1 = -k_R*shear[3] - eta_R*vrl1; - fr2 = -k_R*shear[4] - eta_R*vrl2; - fr3 = -k_R*shear[5] - eta_R*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR[itype][jtype] * fabs(Fne + 2*F_C); - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - - - //**************************************** - // Twisting torque, including shear history effects - //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - shear[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - //shear[6] = Mtcrit/k_Q*magtwist/fabs(magtwist); - shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - - if (force->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; - - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } -} - -/* ---------------------------------------------------------------------- - global settings - ------------------------------------------------------------------------- */ - -void PairGranJKRRolling::settings(int narg, char **arg) -{ - if (narg < 6) error->all(FLERR,"Illegal pair_style command"); - - int ntypes = atom->ntypes; - - if (narg < 8*ntypes) error->all(FLERR,"Illegal pair_style command"); - - E_one = new double[ntypes+1]; - G_one = new double[ntypes+1]; - pois = new double[ntypes+1]; - muS_one = new double[ntypes+1]; - cor = new double[ntypes+1]; - alpha_one = new double[ntypes+1]; - Ecoh_one = new double[ntypes+1]; - kR_one = new double[ntypes+1]; - muR_one = new double[ntypes+1]; - etaR_one = new double[ntypes+1]; - - //Defaults - normaldamp = TSUJI; - rollingdamp = INDEP; - - int iarg = 8*ntypes; - while (iarg < narg){ - if (strcmp(arg[iarg],"normaldamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp = TSUJI; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else if (strcmp(arg[iarg],"rollingdamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); - iarg +=2; - } - else iarg += 1; - } - - for (int i=0; i < ntypes;i++){ - - E_one[i+1] = force->numeric(FLERR, arg[i]); - G_one[i+1] = force->numeric(FLERR, arg[ntypes+i]); - muS_one[i+1] = force->numeric(FLERR, arg[2*ntypes+i]); - cor[i+1] = force->numeric(FLERR, arg[3*ntypes+i]); - Ecoh_one[i+1] = force->numeric(FLERR, arg[4*ntypes+i]); - kR_one[i+1] = force->numeric(FLERR, arg[5*ntypes+i]); - muR_one[i+1] = force->numeric(FLERR, arg[6*ntypes+i]); - etaR_one[i+1] = force->numeric(FLERR, arg[7*ntypes+i]); - } - - //Optional keywords: - // normaldamp tsuji, or normaldamp brilliantov - // rollingdamp brilliantov - - //Derived from inputs - for (int i=1; i <= ntypes; i++){ - pois[i] = E_one[i]/(2.0*G_one[i]) - 1.0; - alpha_one[i] = 1.2728-4.2783*cor[i]+11.087*cor[i]*cor[i]-22.348*cor[i]*cor[i]*cor[i]+27.467*cor[i]*cor[i]*cor[i]*cor[i]-18.022*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]+4.8218*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]*cor[i]; - for (int j=i; j <= ntypes; j++){ - E[i][j] = E[j][i] = 1/((1-pois[i]*pois[i])/E_one[i]+(1-pois[j]*pois[j])/E_one[j]); - G[i][j] = G[j][i] = 1/((2-pois[i])/G_one[i]+(2-pois[j])/G_one[j]); - if (normaldamp == TSUJI){ - alpha[i][j] = alpha[j][i] = sqrt(alpha_one[i]*alpha_one[j]); - } - else if (normaldamp == BRILLIANTOV){ - gamman[i][j] = gamman[j][i] = sqrt(cor[i]*cor[j]); - } - muS[i][j] = muS[j][i] = sqrt(muS_one[i]*muS_one[j]); - Ecoh[i][j] = Ecoh[j][i] = sqrt(Ecoh_one[i]*Ecoh_one[j]); - kR[i][j] = kR[j][i] = sqrt(kR_one[i]*kR_one[j]); - etaR[i][j] = etaR[j][i] = sqrt(etaR_one[i]*etaR_one[j]); - muR[i][j] = muR[j][i] = sqrt(muR_one[i]*muR_one[j]); - } - } -} - -/* ---------------------------------------------------------------------- */ - -double PairGranJKRRolling::single(int i, int j, int itype, int jtype, - double rsq, - double factor_coul, double factor_lj, - double &fforce) -{//TODO: update PairGranJKRRolling::single for JKR - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double overlap, a; - double mi,mj,meff,damp,kn,kt; - double Fdamp,Fne,Fntot,Fscrit; - double eta_N,eta_T; - double vtr1,vtr2,vtr3,vrel; - double fs1,fs2,fs3,fs; - double shrmag; - double F_C, delta_C, olapsq, olapcubed, sqrtterm, tmp, a0; - double keyterm, keyterm2, keyterm3, aovera0, foverFc; - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/(radi+radj); - a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); - delta_C = 0.5*a0*a0*POW6ONE/R; - - int *touch = fix_history->firstflag[i]; - if ((rsq >= (radsum+delta_C)*(radsum+delta_C) )|| - (rsq >= radsum*radsum && touch[j])){ - fforce = 0.0; - svector[0] = svector[1] = svector[2] = svector[3] = 0.0; - return 0.0; - } - - // relative translational velocity - - double **v = atom->v; - vr1 = v[i][0] - v[j][0]; - vr2 = v[i][1] - v[j][1]; - vr3 = v[i][2] - v[j][2]; - - // normal component - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - - vnnr = vr1*nx + vr2*ny + vr3*nz; - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // tangential component - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - double **omega = atom->omega; - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - double *rmass = atom->rmass; - int *type = atom->type; - int *mask = atom->mask; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - - // normal force = JKR - F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; - overlap = radsum - r; - olapsq = overlap*overlap; - olapcubed = olapsq*olapsq; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,ONETHIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = POW6TWO * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 - a = aovera0*a0; - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) - - Fne = F_C*foverFc; - - //Damping - kn = 4.0/3.0*E[itype][jtype]*a; - if (normaldamp == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - Fntot = Fne + Fdamp; - - // relative velocities - - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - // neighprev = index of found neigh on previous call - // search entire jnum list of neighbors of I for neighbor J - // start from neighprev, since will typically be next neighbor - // reset neighprev to 0 as necessary - - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allshear = fix_history->firstvalue[i]; - - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - - double *shear = &allshear[size_history*neighprev]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // tangential forces = shear + tangential velocity damping - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; - fs1 = -kt*shear[0] - eta_T*vtr1; - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - Fscrit= muS[itype][jtype] * fabs(Fne + 2*F_C); - - if (fs > Fscrit) { - if (shrmag != 0.0) { - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - fs *= Fscrit/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; - } - - // set all forces and return no energy - - fforce = Fntot; - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = vn1; - svector[5] = vn2; - svector[6] = vn3; - svector[7] = vt1; - svector[8] = vt2; - svector[9] = vt3; - return 0.0; -} diff --git a/src/GRANULAR/pair_gran_jkr_rolling.h b/src/GRANULAR/pair_gran_jkr_rolling.h deleted file mode 100644 index 8c4b339eb3..0000000000 --- a/src/GRANULAR/pair_gran_jkr_rolling.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- 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(gran/jkr/rolling,PairGranJKRRolling) - -#else - -#ifndef LMP_PAIR_GRAN_JKR_ROLLING_H -#define LMP_PAIR_GRAN_JKR_ROLLING_H - -#include "pair_gran_hooke_history.h" - -namespace LAMMPS_NS { - -class PairGranJKRRolling : public PairGranHookeHistory { -public: - PairGranJKRRolling(class LAMMPS *); - virtual ~PairGranJKRRolling(); - virtual void compute(int, int); - void settings(int, char **); //Eventually set this through coeff method so that user can specify a particular i-j set of coefficients - double single(int, int, int, int, double, double, double, double &); - double *E_one, *G_one, *pois, *muS_one, *cor, *alpha_one, *Ecoh_one, *kR_one, *muR_one, *etaR_one; //Public so as to be accessible to fix/wall/gran -private: - double **E, **G, **alpha, **muS, **Ecoh, **kR, **muR, **etaR, **gamman; - int normaldamp, rollingdamp; - - - -}; - -} - -#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. - - */ diff --git a/src/GRANULAR/pair_gran_jkr_rolling_multi.cpp b/src/GRANULAR/pair_gran_jkr_rolling_multi.cpp deleted file mode 100644 index a9156390e5..0000000000 --- a/src/GRANULAR/pair_gran_jkr_rolling_multi.cpp +++ /dev/null @@ -1,1181 +0,0 @@ -/* ---------------------------------------------------------------------- -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: Leo Silbert (SNL), Gary Grest (SNL) - ------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include "pair_gran_jkr_rolling_multi.h" -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "modify.h" -#include "fix.h" -#include "fix_neigh_history.h" -#include "comm.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "memory.h" -#include "error.h" -#include "math_const.h" -//#include - -using namespace LAMMPS_NS; -using namespace MathConst; - -#define ONETHIRD 0.33333333333333333 -#define TWOTHIRDS 0.66666666666666666 -#define POW6ONE 0.550321208149104 //6^(-1/3) -#define POW6TWO 0.30285343213869 //6^(-2/3) - -#define EPSILON 1e-10 - -enum {TSUJI, BRILLIANTOV}; -enum {INDEP, BRILLROLL}; - -/* ---------------------------------------------------------------------- */ - -PairGranJKRRollingMulti::PairGranJKRRollingMulti(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 1; - no_virial_fdotr_compute = 1; - history = 1; - fix_history = NULL; - - single_extra = 10; - svector = new double[10]; - - neighprev = 0; - - nmax = 0; - mass_rigid = NULL; - - // set comm size needed by this Pair if used with fix rigid - - comm_forward = 1; -} - -/* ---------------------------------------------------------------------- */ -PairGranJKRRollingMulti::~PairGranJKRRollingMulti() -{ - delete [] svector; - if (fix_history) modify->delete_fix("NEIGH_HISTORY"); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut); - memory->destroy(E); - memory->destroy(G); - memory->destroy(normaldamp); - memory->destroy(rollingdamp); - memory->destroy(alpha); - memory->destroy(gamman); - memory->destroy(muS); - memory->destroy(Ecoh); - memory->destroy(kR); - memory->destroy(muR); - memory->destroy(etaR); - - delete [] onerad_dynamic; - delete [] onerad_frozen; - delete [] maxrad_dynamic; - delete [] maxrad_frozen; - } - memory->destroy(mass_rigid); -} -/* ---------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::compute(int eflag, int vflag) -{ -// feenableexcept(FE_INVALID | FE_OVERFLOW); - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv,R,a; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double kn, kt, k_Q, k_R, eta_N, eta_T, eta_Q, eta_R; - double Fne, Fdamp, Fntot, Fscrit, Frcrit, F_C, delta_C, delta_Cinv; - double overlap, olapsq, olapcubed, sqrtterm, tmp, a0; - double keyterm, keyterm2, keyterm3, aovera0, foverFc; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - double signtwist, magtwist, magtortwist, Mtcrit; - double fs,fs1,fs2,fs3,roll1,roll2,roll3,torroll1,torroll2,torroll3; - double tortwist1, tortwist2, tortwist3; - double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *shear,*allshear,**firstshear; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int shearupdate = 1; - if (update->setupflag) shearupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - double **x = atom->x; - double **v = atom->v; - double **f = atom->f; - int *type = atom->type; - 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 newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firstshear = fix_history->firstvalue; - - // 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]; - radi = radius[i]; - touch = firsttouch[i]; - allshear = firstshear[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]; - jtype = type[j]; - rsq = delx*delx + dely*dely + delz*delz; - radj = radius[j]; - radsum = radi + radj; - R = radi*radj/(radi+radj); - a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); - delta_C = 0.5*a0*a0*POW6ONE/R; - - if ((rsq >= radsum*radsum && touch[jj] == 0) || - (rsq >= (radsum+delta_C)*(radsum+delta_C))) { - - // unset non-touching neighbors - - touch[jj] = 0; - shear = &allshear[3*jj]; - shear[0] = 0.0; - shear[1] = 0.0; - shear[2] = 0.0; - - } else { - F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - //**************************************** - //Normal force = JKR-adjusted Hertzian contact + damping - //**************************************** - if (Ecoh[itype][jtype] != 0.0) delta_Cinv = 1.0/delta_C; - else delta_Cinv = 1.0; - overlap = (radsum - r)*delta_Cinv; - olapsq = overlap*overlap; - olapcubed = olapsq*overlap; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,ONETHIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = POW6TWO * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 - a = aovera0*a0; - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) - - Fne = F_C*foverFc; - - //Damping - kn = 4.0/3.0*E[itype][jtype]*a; - if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - Fntot = Fne + Fdamp; - //if (screen) fprintf(screen,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); - //if (logfile) fprintf(logfile,"%d %d %16.16g %16.16g \n",itype,jtype,Ecoh[itype][jtype],E[itype][jtype]); - - //**************************************** - //Tangential force, including shear history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - // Luding Gran Matt 2008, v10,p235 suggests correcting radi and radj by subtracting - // delta/2, i.e. instead of radi, use distance to center of contact point? - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - touch[jj] = 1; - shear = &allshear[3*jj]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // Rotate and update shear displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (shearupdate) { - rsht = shear[0]*nx + shear[1]*ny + shear[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - shear[0] -= rsht*nx; - shear[1] -= rsht*ny; - shear[2] -= rsht*nz; - //Also rescale to preserve magnitude - shear[0] *= scalefac; - shear[1] *= scalefac; - shear[2] *= scalefac; - } - //Update shear history - shear[0] += vtr1*dt; - shear[1] += vtr2*dt; - shear[2] += vtr3*dt; - } - - // tangential forces = shear + tangential velocity damping - // following Zhao and Marshall Phys Fluids v20, p043302 (2008) - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; //Based on discussion in Marshall; eta_T can also be an independent parameter - fs1 = -kt*shear[0] - eta_T*vtr1; //eq 26 - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = muS[itype][jtype] * fabs(Fne + 2*F_C); - // For JKR, use eq 43 of Marshall. For DMT, use Fne instead - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - //shear[0] = (Fcrit/fs) * (shear[0] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[1] = (Fcrit/fs) * (shear[1] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - //shear[2] = (Fcrit/fs) * (shear[2] + eta_T*vtr1/kt) - eta_T*vtr1/kt; - shear[0] = -1.0/kt*(Fscrit*fs1/fs + eta_T*vtr1); //Same as above, but simpler (check!) - shear[1] = -1.0/kt*(Fscrit*fs2/fs + eta_T*vtr2); - shear[2] = -1.0/kt*(Fscrit*fs3/fs + eta_T*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - - //**************************************** - // Rolling force, including shear history effects - //**************************************** - - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = R*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = R*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = R*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - // Rolling displacement - rollmag = sqrt(shear[3]*shear[3] + shear[4]*shear[4] + shear[5]*shear[5]); - rolldotn = shear[3]*nx + shear[4]*ny + shear[5]*nz; - - if (shearupdate) { - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - shear[3] -= rolldotn*nx; - shear[4] -= rolldotn*ny; - shear[5] -= rolldotn*nz; - //Also rescale to preserve magnitude - shear[3] *= scalefac; - shear[4] *= scalefac; - shear[5] *= scalefac; - } - shear[3] += vrl1*dt; - shear[4] += vrl2*dt; - shear[5] += vrl3*dt; - } - - k_R = kR[itype][jtype]*4.0*F_C*pow(aovera0,1.5); - if (rollingdamp[itype][jtype] == INDEP) eta_R = etaR[itype][jtype]; - else if (rollingdamp[itype][jtype] == BRILLROLL) eta_R = muR[itype][jtype]*fabs(Fne); - fr1 = -k_R*shear[3] - eta_R*vrl1; - fr2 = -k_R*shear[4] - eta_R*vrl2; - fr3 = -k_R*shear[5] - eta_R*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = muR[itype][jtype] * fabs(Fne + 2*F_C); - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - shear[3] = -1.0/k_R*(Frcrit*fr1/fr + eta_R*vrl1); - shear[4] = -1.0/k_R*(Frcrit*fr2/fr + eta_R*vrl2); - shear[5] = -1.0/k_R*(Frcrit*fr3/fr + eta_R*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - - - //**************************************** - // Twisting torque, including shear history effects - //**************************************** - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - shear[6] += magtwist*dt; - k_Q = 0.5*kt*a*a;; //eq 32 - eta_Q = 0.5*eta_T*a*a; - magtortwist = -k_Q*shear[6] - eta_Q*magtwist;//M_t torque (eq 30) - - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit=TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - //shear[6] = Mtcrit/k_Q*magtwist/fabs(magtwist); - shear[6] = 1.0/k_Q*(Mtcrit*signtwist - eta_Q*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - //if (screen) fprintf(screen,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); - //if (logfile) fprintf(logfile,"%16.16g %16.16g %16.16g %16.16g %16.16g %16.16g %16.16g \n",fs1,fs2,fs3,Fntot,nx,ny,nz); - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - - torroll1 = R*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = R*(nz*fr1 - nx*fr3); - torroll3 = R*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - - if (force->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; - - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } -} - - -/* ---------------------------------------------------------------------- - allocate all arrays - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::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(E,n+1,n+1,"pair:E"); - memory->create(G,n+1,n+1,"pair:G"); - memory->create(normaldamp,n+1,n+1,"pair:normaldamp"); - memory->create(rollingdamp,n+1,n+1,"pair:rollingdamp"); - memory->create(alpha,n+1,n+1,"pair:alpha"); - memory->create(gamman,n+1,n+1,"pair:gamman"); - memory->create(muS,n+1,n+1,"pair:muS"); - memory->create(Ecoh,n+1,n+1,"pair:Ecoh"); - memory->create(kR,n+1,n+1,"pair:kR"); - memory->create(muR,n+1,n+1,"pair:muR"); - memory->create(etaR,n+1,n+1,"pair:etaR"); - - onerad_dynamic = new double[n+1]; - onerad_frozen = new double[n+1]; - maxrad_dynamic = new double[n+1]; - maxrad_frozen = new double[n+1]; -} - -/* ---------------------------------------------------------------------- - global settings - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::settings(int narg, char **arg) -{ - if (narg != 1) error->all(FLERR,"Illegal pair_style command"); - - if (strcmp(arg[0],"NULL") == 0 ) cut_global = -1.0; - else cut_global = force->numeric(FLERR,arg[0]); - - // reset cutoffs that have been explicitly set - if (allocated) { - int i,j; - for (i = 1; i <= atom->ntypes; i++) - for (j = i; j <= atom->ntypes; j++) - if (setflag[i][j]) cut[i][j] = cut_global; - } -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::coeff(int narg, char **arg) -{ - if (narg < 10 || narg > 15) - error->all(FLERR,"Incorrect args for pair coefficients2"); - - if (!allocated) allocate(); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - double E_one = force->numeric(FLERR,arg[2]); - double G_one = force->numeric(FLERR,arg[3]); - double muS_one = force->numeric(FLERR,arg[4]); - double cor_one = force->numeric(FLERR,arg[5]); - double Ecoh_one = force->numeric(FLERR,arg[6]); - double kR_one = force->numeric(FLERR,arg[7]); - double muR_one = force->numeric(FLERR,arg[8]); - double etaR_one = force->numeric(FLERR,arg[9]); - - //Defaults - int normaldamp_one = TSUJI; - int rollingdamp_one = INDEP; - double cut_one = cut_global; - - int iarg = 10; - while (iarg < narg) { - if (strcmp(arg[iarg],"normaldamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"tsuji") == 0) normaldamp_one = TSUJI; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) normaldamp_one = BRILLIANTOV; - else error->all(FLERR, "Invalid normal damping model for pair/gran/dmt/rolling"); - iarg += 2; - } - else if (strcmp(arg[iarg],"rollingdamp") == 0){ - if (iarg+2 > narg) error->all(FLERR, "Invalid pair/gran/dmt/rolling entry"); - if (strcmp(arg[iarg+1],"independent") == 0) rollingdamp_one = INDEP; - else if (strcmp(arg[iarg+1],"brilliantov") == 0) rollingdamp_one = BRILLROLL; - else error->all(FLERR, "Invalid rolling damping model for pair/gran/dmt/rolling"); - iarg +=2; - } - else { - if (strcmp(arg[iarg],"NULL") == 0) cut_one = -1.0; - else cut_one = force->numeric(FLERR,arg[iarg]); - iarg += 1; - } - } - - int count = 0; - for (int i = ilo; i <= ihi; i++) { - double pois = E_one/(2.0*G_one) - 1.0; - double alpha_one = 1.2728-4.2783*cor_one+11.087*cor_one*cor_one-22.348*cor_one*cor_one*cor_one+27.467*cor_one*cor_one*cor_one*cor_one-18.022*cor_one*cor_one*cor_one*cor_one*cor_one+4.8218*cor_one*cor_one*cor_one*cor_one*cor_one*cor_one; - - for (int j = MAX(jlo,i); j <= jhi; j++) { - E[i][j] = E_one; - G[i][j] = G_one; - if (normaldamp_one == TSUJI) { - normaldamp[i][j] = TSUJI; - alpha[i][j] = alpha_one; - } - else if (normaldamp_one == BRILLIANTOV) { - normaldamp[i][j] = BRILLIANTOV; - gamman[i][j] = cor_one; - } - if (rollingdamp_one == INDEP) { - rollingdamp[i][j] = INDEP; - } - else if (rollingdamp_one == BRILLROLL) { - rollingdamp[i][j] = BRILLROLL; - } - muS[i][j] = muS_one; - Ecoh[i][j] = Ecoh_one; - kR[i][j] = kR_one; - etaR[i][j] = etaR_one; - muR[i][j] = muR_one; - cut[i][j] = cut_one; - setflag[i][j] = 1; - count++; - } - } - - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients1"); -} - -/* ---------------------------------------------------------------------- - init specific to this pair style - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::init_style() -{ - int i; - - // error and warning checks - - if (!atom->radius_flag || !atom->rmass_flag) - error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); - if (comm->ghost_velocity == 0) - error->all(FLERR,"Pair granular requires ghost atoms store velocity"); - - // need a granular neigh list - - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->size = 1; - if (history) neighbor->requests[irequest]->history = 1; - - dt = update->dt; - - // if shear history is stored: - // if first init, create Fix needed for storing shear history - - if (history && fix_history == NULL) { - char dnumstr[16]; - sprintf(dnumstr,"%d",3); - char **fixarg = new char*[4]; - fixarg[0] = (char *) "NEIGH_HISTORY"; - fixarg[1] = (char *) "all"; - fixarg[2] = (char *) "NEIGH_HISTORY"; - fixarg[3] = dnumstr; - modify->add_fix(4,fixarg,1); - delete [] fixarg; - fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; - fix_history->pair = this; - } - - // check for FixFreeze and set freeze_group_bit - - for (i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"freeze") == 0) break; - if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; - else freeze_group_bit = 0; - - // check for FixRigid so can extract rigid body masses - - fix_rigid = NULL; - for (i = 0; i < modify->nfix; i++) - if (modify->fix[i]->rigid_flag) break; - if (i < modify->nfix) fix_rigid = modify->fix[i]; - - // check for FixPour and FixDeposit so can extract particle radii - - int ipour; - for (ipour = 0; ipour < modify->nfix; ipour++) - if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; - if (ipour == modify->nfix) ipour = -1; - - int idep; - for (idep = 0; idep < modify->nfix; idep++) - if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; - if (idep == modify->nfix) idep = -1; - - // set maxrad_dynamic and maxrad_frozen for each type - // include future FixPour and FixDeposit particles as dynamic - - int itype; - for (i = 1; i <= atom->ntypes; i++) { - onerad_dynamic[i] = onerad_frozen[i] = 0.0; - if (ipour >= 0) { - itype = i; - onerad_dynamic[i] = - *((double *) modify->fix[ipour]->extract("radius",itype)); - } - if (idep >= 0) { - itype = i; - onerad_dynamic[i] = - *((double *) modify->fix[idep]->extract("radius",itype)); - } - } - - double *radius = atom->radius; - int *mask = atom->mask; - int *type = atom->type; - int nlocal = atom->nlocal; - - for (i = 0; i < nlocal; i++) - if (mask[i] & freeze_group_bit) - onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius[i]); - else - onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius[i]); - - MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - - // set fix which stores history info - - if (history) { - int ifix = modify->find_fix("NEIGH_HISTORY"); - if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); - fix_history = (FixNeighHistory *) modify->fix[ifix]; - } -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i - ------------------------------------------------------------------------- */ - -double PairGranJKRRollingMulti::init_one(int i, int j) -{ - if (setflag[i][j] == 0) { - E[i][j] = mix_stiffnessE(E[i][i],E[j][j],G[i][i],G[j][j]); - G[i][j] = mix_stiffnessG(G[i][i],E[j][j],G[i][i],G[j][j]); - if (normaldamp[i][j] == TSUJI) { - alpha[i][j] = mix_geom(alpha[i][i],alpha[j][j]); - } - else if (normaldamp[i][j] == BRILLIANTOV) { - gamman[i][j] = mix_geom(gamman[i][i],gamman[j][j]); - } - muS[i][j] = mix_geom(muS[i][i],muS[j][j]); - Ecoh[i][j] = mix_geom(Ecoh[i][i],Ecoh[j][j]); - kR[i][j] = mix_geom(kR[i][i],kR[j][j]); - etaR[i][j] = mix_geom(etaR[i][i],etaR[j][j]); - muR[i][j] = mix_geom(muR[i][i],muR[j][j]); - } - - E[j][i] = E[i][j]; - G[j][i] = G[i][j]; - normaldamp[j][i] = normaldamp[i][j]; - alpha[j][i] = alpha[i][j]; - gamman[j][i] = gamman[i][j]; - rollingdamp[j][i] = rollingdamp[i][j]; - muS[j][i] = muS[i][j]; - Ecoh[j][i] = Ecoh[i][j]; - kR[j][i] = kR[i][j]; - etaR[j][i] = etaR[i][j]; - muR[j][i] = muR[i][j]; - - double cutoff = cut[i][j]; - - // It is likely that cut[i][j] at this point is still 0.0. This can happen when - // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates - // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size - // To avoid this issue,for cases involving cut[i][j] = 0.0 (possible only - // if there is no current information about radius/cutoff of type i and j). - // we assign cutoff = min(cut[i][j]) for i,j such that cut[i][j] > 0.0. - - if (cut[i][j] < 0.0) { - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); - } - cutoff = cutmax; - } - } - return cutoff; -} - - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::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(&E[i][j],sizeof(double),1,fp); - fwrite(&G[i][j],sizeof(double),1,fp); - fwrite(&normaldamp[i][j],sizeof(int),1,fp); - fwrite(&rollingdamp[i][j],sizeof(int),1,fp); - fwrite(&alpha[i][j],sizeof(double),1,fp); - fwrite(&gamman[i][j],sizeof(double),1,fp); - fwrite(&muS[i][j],sizeof(double),1,fp); - fwrite(&Ecoh[i][j],sizeof(double),1,fp); - fwrite(&kR[i][j],sizeof(double),1,fp); - fwrite(&muR[i][j],sizeof(double),1,fp); - fwrite(&etaR[i][j],sizeof(double),1,fp); - fwrite(&cut[i][j],sizeof(double),1,fp); - } - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::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(&E[i][j],sizeof(double),1,fp); - fread(&G[i][j],sizeof(double),1,fp); - fread(&normaldamp[i][j],sizeof(int),1,fp); - fread(&rollingdamp[i][j],sizeof(int),1,fp); - fread(&alpha[i][j],sizeof(double),1,fp); - fread(&gamman[i][j],sizeof(double),1,fp); - fread(&muS[i][j],sizeof(double),1,fp); - fread(&Ecoh[i][j],sizeof(double),1,fp); - fread(&kR[i][j],sizeof(double),1,fp); - fread(&muR[i][j],sizeof(double),1,fp); - fread(&etaR[i][j],sizeof(double),1,fp); - fread(&cut[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&E[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&G[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&normaldamp[i][j],1,MPI_INT,0,world); - MPI_Bcast(&rollingdamp[i][j],1,MPI_INT,0,world); - MPI_Bcast(&alpha[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&gamman[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&muS[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&Ecoh[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&kR[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&muR[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&etaR[i][j],1,MPI_DOUBLE,0,world); - MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); - } - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::write_restart_settings(FILE *fp) -{ - fwrite(&cut_global,sizeof(double),1,fp); -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts - ------------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::read_restart_settings(FILE *fp) -{ - if (comm->me == 0) { - fread(&cut_global,sizeof(double),1,fp); - } - MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world); -} - -/* ---------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::reset_dt() -{ - dt = update->dt; -} - -/* ---------------------------------------------------------------------- */ - -double PairGranJKRRollingMulti::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, double &fforce) -{ -// feenableexcept(FE_INVALID | FE_OVERFLOW); - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, R; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double overlap, a; - double mi,mj,meff,damp,kn,kt; - double Fdamp,Fne,Fntot,Fscrit; - double eta_N,eta_T; - double vtr1,vtr2,vtr3,vrel; - double fs1,fs2,fs3,fs; - double shrmag; - double F_C, delta_C, olapsq, olapcubed, sqrtterm, tmp, a0; - double keyterm, keyterm2, keyterm3, aovera0, foverFc; - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - - r = sqrt(rsq); - rinv = 1.0/r; - rsqinv = 1.0/rsq; - R = radi*radj/(radi+radj); - a0 = pow(9.0*M_PI*Ecoh[itype][jtype]*R*R/E[itype][jtype],ONETHIRD); - delta_C = 0.5*a0*a0*POW6ONE/R; - - int *touch = fix_history->firstflag[i]; - if ((rsq >= (radsum+delta_C)*(radsum+delta_C) )|| - (rsq >= radsum*radsum && touch[j])){ - fforce = 0.0; - svector[0] = svector[1] = svector[2] = svector[3] = 0.0; - return 0.0; - } - - // relative translational velocity - - double **v = atom->v; - vr1 = v[i][0] - v[j][0]; - vr2 = v[i][1] - v[j][1]; - vr3 = v[i][2] - v[j][2]; - - // normal component - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - - vnnr = vr1*nx + vr2*ny + vr3*nz; - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // tangential component - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - double **omega = atom->omega; - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - double *rmass = atom->rmass; - int *type = atom->type; - int *mask = atom->mask; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - - // normal force = JKR - F_C = 3.0*R*M_PI*Ecoh[itype][jtype]; - overlap = radsum - r; - olapsq = overlap*overlap; - olapcubed = olapsq*olapsq; - sqrtterm = sqrt(1.0 + olapcubed); - tmp = 2.0 + olapcubed + 2.0*sqrtterm; - keyterm = pow(tmp,ONETHIRD); - keyterm2 = olapsq/keyterm; - keyterm3 = sqrt(overlap + keyterm2 + keyterm); - aovera0 = POW6TWO * (keyterm3 + - sqrt(2.0*overlap - keyterm2 - keyterm + 4.0/keyterm3));// eq 41 - a = aovera0*a0; - foverFc = 4.0*((aovera0*aovera0*aovera0) - pow(aovera0,1.5));//F_ne/F_C (eq 40) - - Fne = F_C*foverFc; - - //Damping - kn = 4.0/3.0*E[itype][jtype]*a; - if (normaldamp[itype][jtype] == BRILLIANTOV) eta_N = a*meff*gamman[itype][jtype]; - else if (normaldamp[itype][jtype] == TSUJI) eta_N=alpha[itype][jtype]*sqrt(meff*kn); - - Fdamp = -eta_N*vnnr; //F_nd eq 23 and Zhao eq 19 - - Fntot = Fne + Fdamp; - - // relative velocities - - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // shear history effects - // neighprev = index of found neigh on previous call - // search entire jnum list of neighbors of I for neighbor J - // start from neighprev, since will typically be next neighbor - // reset neighprev to 0 as necessary - - int jnum = list->numneigh[i]; - int *jlist = list->firstneigh[i]; - double *allshear = fix_history->firstvalue[i]; - - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - - double *shear = &allshear[3*neighprev]; - shrmag = sqrt(shear[0]*shear[0] + shear[1]*shear[1] + - shear[2]*shear[2]); - - // tangential forces = shear + tangential velocity damping - kt=8.0*G[itype][jtype]*a; - - eta_T = eta_N; - fs1 = -kt*shear[0] - eta_T*vtr1; - fs2 = -kt*shear[1] - eta_T*vtr2; - fs3 = -kt*shear[2] - eta_T*vtr3; - - // rescale frictional displacements and forces if needed - - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - Fscrit= muS[itype][jtype] * fabs(Fne + 2*F_C); - - if (fs > Fscrit) { - if (shrmag != 0.0) { - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - fs *= Fscrit/fs; - } else fs1 = fs2 = fs3 = fs = 0.0; - } - - // set all forces and return no energy - - fforce = Fntot; - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = vn1; - svector[5] = vn2; - svector[6] = vn3; - svector[7] = vt1; - svector[8] = vt2; - svector[9] = vt3; - return 0.0; -} - -/* ---------------------------------------------------------------------- */ - -int PairGranJKRRollingMulti::pack_forward_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++] = mass_rigid[j]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void PairGranJKRRollingMulti::unpack_forward_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) - mass_rigid[i] = buf[m++]; -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays - ------------------------------------------------------------------------- */ - -double PairGranJKRRollingMulti::memory_usage() -{ - double bytes = nmax * sizeof(double); - return bytes; -} - -/* ---------------------------------------------------------------------- - mixing of stiffness (E) - ------------------------------------------------------------------------- */ - -double PairGranJKRRollingMulti::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) -{ - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); -} - -/* ---------------------------------------------------------------------- - mixing of stiffness (G) - ------------------------------------------------------------------------- */ - -double PairGranJKRRollingMulti::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) -{ - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); -} - -/* ---------------------------------------------------------------------- - mixing of everything else - ------------------------------------------------------------------------- */ - -double PairGranJKRRollingMulti::mix_geom(double valii, double valjj) -{ - return sqrt(valii*valjj); -} diff --git a/src/GRANULAR/pair_gran_jkr_rolling_multi.h b/src/GRANULAR/pair_gran_jkr_rolling_multi.h deleted file mode 100644 index c9c75de9a6..0000000000 --- a/src/GRANULAR/pair_gran_jkr_rolling_multi.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- 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(gran/jkr/rolling/multi,PairGranJKRRollingMulti) - -#else - -#ifndef LMP_PAIR_GRAN_JKR_ROLLING_MULTI_H -#define LMP_PAIR_GRAN_JKR_ROLLING_MULTI_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairGranJKRRollingMulti : public Pair { -public: - PairGranJKRRollingMulti(class LAMMPS *); - virtual ~PairGranJKRRollingMulti(); - virtual void compute(int, int); - virtual void settings(int, char **); - virtual void coeff(int, char **); // Made Virtual by IS Oct 7 2017 - void init_style(); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - void write_restart_settings(FILE *); - void read_restart_settings(FILE *); - void reset_dt(); - virtual double single(int, int, int, int, double, double, double, double &); - int pack_forward_comm(int, int *, double *, int, int *); - void unpack_forward_comm(int, int, double *); - double memory_usage(); - - protected: - double cut_global; - double **E,**G,**alpha,**gamman,**muS,**Ecoh,**kR,**muR,**etaR,**cut; - int **normaldamp, **rollingdamp; - double dt; - int freeze_group_bit; - int history; - - int neighprev; - double *onerad_dynamic,*onerad_frozen; - double *maxrad_dynamic,*maxrad_frozen; - - class FixNeighHistory *fix_history; - - // storage of rigid body masses for use in granular interactions - - class Fix *fix_rigid; // ptr to rigid body fix, NULL if none - double *mass_rigid; // rigid mass for owned+ghost atoms - int nmax; // allocated size of mass_rigid - - virtual void allocate(); // Made Virtual by IS Oct 7 2017 - -private: - double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); - double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); - double mix_geom(double valii, double valjj); -}; - -} - -#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. - - */ diff --git a/src/GRANULAR/pair_granular_multi.cpp b/src/GRANULAR/pair_granular_multi.cpp deleted file mode 100644 index 07a6cab3dd..0000000000 --- a/src/GRANULAR/pair_granular_multi.cpp +++ /dev/null @@ -1,1624 +0,0 @@ -/* ---------------------------------------------------------------------- -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: -Dan Bolintineanu (SNL), Ishan Srivastava (SNL), Jeremy Lechman(SNL) -Leo Silbert (SNL), Gary Grest (SNL) ------------------------------------------------------------------------ */ - -#include -#include -#include -#include -#include "pair_granular_multi.h" -#include "atom.h" -#include "atom_vec.h" -#include "domain.h" -#include "force.h" -#include "update.h" -#include "modify.h" -#include "fix.h" -#include "fix_neigh_history.h" -#include "comm.h" -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "memory.h" -#include "error.h" -#include "math_const.h" - -using namespace LAMMPS_NS; -using namespace MathConst; - -#define PI27SQ 266.47931882941264802866 // 27*PI**2 -#define THREEROOT3 5.19615242270663202362 // 3*sqrt(3) -#define SIXROOT6 14.69693845669906728801 // 6*sqrt(6) -#define INVROOT6 0.40824829046386307274 // 1/sqrt(6) -#define FOURTHIRDS 1.333333333333333 // 4/3 -#define TWOPI 6.28318530717959 // 2*PI - -#define EPSILON 1e-10 - -enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; -enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {TANGENTIAL_NOHISTORY, TANGENTIAL_MINDLIN}; -enum {TWIST_NONE, TWIST_NOHISTORY, TWIST_SDS, TWIST_MARSHALL}; -enum {ROLL_NONE, ROLL_NOHISTORY, ROLL_SDS}; - -/* ---------------------------------------------------------------------- */ - -PairGranularMulti::PairGranularMulti(LAMMPS *lmp) : Pair(lmp) -{ - single_enable = 1; - no_virial_fdotr_compute = 1; - fix_history = NULL; - - single_extra = 9; - svector = new double[single_extra]; - - neighprev = 0; - - nmax = 0; - mass_rigid = NULL; - - onerad_dynamic = NULL; - onerad_frozen = NULL; - maxrad_dynamic = NULL; - maxrad_frozen = NULL; - - dt = update->dt; - - // set comm size needed by this Pair if used with fix rigid - - comm_forward = 1; - - use_history = 0; - beyond_contact = 0; - nondefault_history_transfer = 0; - tangential_history_index = 0; - roll_history_index = twist_history_index = 0; - -} - -/* ---------------------------------------------------------------------- */ -PairGranularMulti::~PairGranularMulti() -{ - delete [] svector; - if (fix_history) modify->delete_fix("NEIGH_HISTORY"); - - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - memory->destroy(cut); - - memory->destroy(normal_coeffs); - memory->destroy(tangential_coeffs); - memory->destroy(roll_coeffs); - memory->destroy(twist_coeffs); - - memory->destroy(normal); - memory->destroy(damping); - memory->destroy(tangential); - memory->destroy(roll); - memory->destroy(twist); - - delete [] onerad_dynamic; - delete [] onerad_frozen; - delete [] maxrad_dynamic; - delete [] maxrad_frozen; - } - memory->destroy(mass_rigid); -} - -void PairGranularMulti::compute(int eflag, int vflag) -{ - int i,j,ii,jj,inum,jnum,itype,jtype; - double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; - double radi,radj,radsum,rsq,r,rinv,rsqinv; - double Reff, delta, dR, dR2; - - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; - double wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - - double knfac, damp_normal; - double k_tangential, damp_tangential; - double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; - double fs, fs1, fs2, fs3; - - //For JKR - double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; - double t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; - - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - - //Rolling - double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - - //Twisting - double k_twist, damp_twist, mu_twist; - double signtwist, magtwist, magtortwist, Mtcrit; - double tortwist1, tortwist2, tortwist3; - - double shrmag,rsht; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *history,*allhistory,**firsthistory; - - bool touchflag; - - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; - - int historyupdate = 1; - if (update->setupflag) historyupdate = 0; - - // update rigid body info for owned & ghost atoms if using FixRigid masses - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (fix_rigid && neighbor->ago == 0){ - int tmp; - int *body = (int *) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"pair:mass_rigid"); - } - int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++) - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - comm->forward_comm_pair(this); - } - - double **x = atom->x; - double **v = atom->v; - double **f = atom->f; - int *type = atom->type; - 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 newton_pair = force->newton_pair; - - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firsthistory = fix_history->firstvalue; - - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - itype = type[i]; - radi = radius[i]; - touch = firsttouch[i]; - allhistory = firsthistory[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]; - jtype = type[j]; - rsq = delx*delx + dely*dely + delz*delz; - radj = radius[j]; - radsum = radi + radj; - - E = normal_coeffs[itype][jtype][0]; - Reff = radi*radj/(radi+radj); - touchflag = false; - - if (normal[itype][jtype] == JKR){ - if (touch[jj]){ - R2 = Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - a = cbrt(9.0*M_PI*coh*R2/(4*E)); - delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); - dist_pulloff = radsum-delta_pulloff; - touchflag = (rsq < dist_pulloff*dist_pulloff); - } - else{ - touchflag = (rsq < radsum*radsum); - } - } - else{ - touchflag = (rsq < radsum*radsum); - } - - if (!touchflag){ - // unset non-touching neighbors - touch[jj] = 0; - history = &allhistory[size_history*jj]; - for (int k = 0; k < size_history; k++) history[k] = 0.0; - } - else{ - r = sqrt(rsq); - rinv = 1.0/r; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // 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*nx + vr2*ny + vr3*nz; //v_R . n - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - delta = radsum - r; - dR = delta*Reff; - if (normal[itype][jtype] == JKR){ - touch[jj] = 1; - R2=Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - dR2 = dR*dR; - t0 = coh*coh*R2*R2*E; - t1 = PI27SQ*t0; - t2 = 8*dR*dR2*E*E*E; - t3 = 4*dR2*E; - sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues - t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); - t5 = t3/t4 + t4/E; - sqrt2 = MAX(0, 2*dR + t5); - t6 = sqrt(sqrt2); - sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); - a = INVROOT6*(t6 + sqrt(sqrt3)); - a2 = a*a; - knfac = FOURTHIRDS*E*a; - Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - } - else{ - knfac = E; //Hooke - Fne = knfac*delta; - if (normal[itype][jtype] != HOOKE) - a = sqrt(dR); - Fne *= a; - if (normal[itype][jtype] == DMT) - Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; - } - - //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping[itype][jtype] == VELOCITY){ - damp_normal = 1; - } - else if (damping[itype][jtype] == VISCOELASTIC){ - if (normal[itype][jtype] == HOOKE) a = sqrt(dR); - damp_normal = a*meff; - } - else if (damping[itype][jtype] == TSUJI){ - damp_normal = sqrt(meff*knfac); - } - - Fdamp = -normal_coeffs[itype][jtype][1]*damp_normal*vnnr; - - Fntot = Fne + Fdamp; - - //**************************************** - //Tangential force, including history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - // If any history is needed: - if (use_history){ - touch[jj] = 1; - history = &allhistory[size_history*jj]; - } - - if (normal[itype][jtype] == JKR){ - F_pulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*F_pulloff); - } - else{ - Fcrit = fabs(Fne); - } - - //------------------------------ - //Tangential forces - //------------------------------ - k_tangential = tangential_coeffs[itype][jtype][0]; - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - - if (tangential_history){ - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - - // Rotate and update displacements. - // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 - if (historyupdate) { - rsht = history[0]*nx + history[1]*ny + history[2]*nz; - if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! - history[0] -= rsht*nx; - history[1] -= rsht*ny; - history[2] -= rsht*nz; - //Also rescale to preserve magnitude - history[0] *= scalefac; - history[1] *= scalefac; - history[2] *= scalefac; - } - //Update history - history[0] += vtr1*dt; - history[1] += vtr2*dt; - history[2] += vtr3*dt; - } - - // tangential forces = history + tangential velocity damping - fs1 = -k_tangential*history[0] - damp_tangential*vtr1; - fs2 = -k_tangential*history[1] - damp_tangential*vtr2; - fs3 = -k_tangential*history[2] - damp_tangential*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); - history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); - history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - } - else{ //Classic pair gran/hooke (no history) - fs = meff*damp_tangential*vrel; - if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; - else Ft = 0.0; - fs1 = -Ft*vtr1; - fs2 = -Ft*vtr2; - fs3 = -Ft*vtr3; - } - - //**************************************** - // Rolling resistance - //**************************************** - - if (roll[itype][jtype] != ROLL_NONE){ - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - if (roll_history){ - int rhist0 = roll_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - - if (historyupdate){ - if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane - scalefac = rollmag/(rollmag - rolldotn); - history[rhist0] -= rolldotn*nx; - history[rhist1] -= rolldotn*ny; - history[rhist2] -= rolldotn*nz; - //Also rescale to preserve magnitude - history[rhist0] *= scalefac; - history[rhist1] *= scalefac; - history[rhist2] *= scalefac; - } - history[rhist0] += vrl1*dt; - history[rhist1] += vrl2*dt; - history[rhist2] += vrl3*dt; - } - - - k_roll = roll_coeffs[itype][jtype][0]; - damp_roll = roll_coeffs[itype][jtype][1]; - fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; - fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; - fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - } - else{ // - fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; - } - } - - //**************************************** - // Twisting torque, including history effects - //**************************************** - if (twist[itype][jtype] != TWIST_NONE){ - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist[itype][jtype] == TWIST_MARSHALL){ - k_twist = 0.5*k_tangential*a*a;; //eq 32 - damp_twist = 0.5*damp_tangential*a*a; - mu_twist = TWOTHIRDS*a; - } - else{ - k_twist = twist_coeffs[itype][jtype][0]; - damp_twist = twist_coeffs[itype][jtype][1]; - mu_twist = twist_coeffs[itype][jtype][2]; - } - if (twist[itype][jtype] > 1){ - if (historyupdate){ - history[twist_history_index] += magtwist*dt; - } - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; - } - } - // Apply forces & torques - - fx = nx*Fntot + fs1; - fy = ny*Fntot + fs2; - fz = nz*Fntot + fs3; - - f[i][0] += fx; - f[i][1] += fy; - f[i][2] += fz; - - tor1 = ny*fs3 - nz*fs2; - tor2 = nz*fs1 - nx*fs3; - tor3 = nx*fs2 - ny*fs1; - - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; - - if (twist[itype][jtype] != TWIST_NONE){ - tortwist1 = magtortwist * nx; - tortwist2 = magtortwist * ny; - tortwist3 = magtortwist * nz; - - torque[i][0] += tortwist1; - torque[i][1] += tortwist2; - torque[i][2] += tortwist3; - } - - if (roll[itype][jtype] != ROLL_NONE){ - torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr - torroll2 = Reff*(nz*fr1 - nx*fr3); - torroll3 = Reff*(nx*fr2 - ny*fr1); - - torque[i][0] += torroll1; - torque[i][1] += torroll2; - torque[i][2] += torroll3; - } - - if (force->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 (twist[itype][jtype] != TWIST_NONE){ - torque[j][0] -= tortwist1; - torque[j][1] -= tortwist2; - torque[j][2] -= tortwist3; - } - if (roll[itype][jtype] != ROLL_NONE){ - torque[j][0] -= torroll1; - torque[j][1] -= torroll2; - torque[j][2] -= torroll3; - } - } - if (evflag) ev_tally_xyz(i,j,nlocal,0, - 0.0,0.0,fx,fy,fz,delx,dely,delz); - } - } - } -} - - -/* ---------------------------------------------------------------------- -allocate all arrays -------------------------------------------------------------------------- */ - -void PairGranularMulti::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(normal_coeffs,n+1,n+1,4,"pair:normal_coeffs"); - memory->create(tangential_coeffs,n+1,n+1,3,"pair:tangential_coeffs"); - memory->create(roll_coeffs,n+1,n+1,3,"pair:roll_coeffs"); - memory->create(twist_coeffs,n+1,n+1,3,"pair:twist_coeffs"); - - memory->create(normal,n+1,n+1,"pair:normal"); - memory->create(damping,n+1,n+1,"pair:damping"); - memory->create(tangential,n+1,n+1,"pair:tangential"); - memory->create(roll,n+1,n+1,"pair:roll"); - memory->create(twist,n+1,n+1,"pair:twist"); - - onerad_dynamic = new double[n+1]; - onerad_frozen = new double[n+1]; - maxrad_dynamic = new double[n+1]; - maxrad_frozen = new double[n+1]; -} - -/* ---------------------------------------------------------------------- - global settings -------------------------------------------------------------------------- */ - -void PairGranularMulti::settings(int narg, char **arg) -{ - if (narg == 1){ - cutoff_global = force->numeric(FLERR,arg[0]); - } - else{ - cutoff_global = -1; //Will be set based on particle sizes, model choice - } - - tangential_history = 0; - roll_history = twist_history = 0; -} - -/* ---------------------------------------------------------------------- - set coeffs for one or more type pairs -------------------------------------------------------------------------- */ - -void PairGranularMulti::coeff(int narg, char **arg) -{ - int normal_local, damping_local, tangential_local, roll_local, twist_local; - - double normal_coeffs_local[4]; - double tangential_coeffs_local[4]; - double roll_coeffs_local[4]; - double twist_coeffs_local[4]; - - if (narg < 2) - error->all(FLERR,"Incorrect args for pair coefficients"); - - if (!allocated) allocate(); - - int ilo,ihi,jlo,jhi; - force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi); - force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi); - - //Defaults - normal_local = tangential_local = -1; - roll_local = twist_local = 0; - damping_local = VISCOELASTIC; - - int iarg = 2; - while (iarg < narg){ - if (strcmp(arg[iarg], "hooke") == 0){ - if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); - normal_local = HOOKE; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - iarg += 3; - } - else if (strcmp(arg[iarg], "hertz") == 0){ - int num_coeffs = 2; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_local = HERTZ; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //kn - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "hertz/material") == 0){ - int num_coeffs = 3; - if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_local = HERTZ; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "dmt") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); - normal_local = DMT; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1])*FOURTHIRDS; //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+3]); //cohesion - iarg += 5; - } - else if (strcmp(arg[iarg], "jkr") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); - beyond_contact = 1; - normal_local = JKR; - normal_coeffs_local[0] = force->numeric(FLERR,arg[iarg+1]); //E - normal_coeffs_local[1] = force->numeric(FLERR,arg[iarg+2]); //damping - normal_coeffs_local[2] = force->numeric(FLERR,arg[iarg+3]); //G - normal_coeffs_local[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion - iarg += 5; - } - else if (strcmp(arg[iarg], "damp") == 0){ - if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); - if (strcmp(arg[iarg+1], "velocity") == 0){ - damping_local = VELOCITY; - iarg += 1; - } - else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ - damping_local = VISCOELASTIC; - iarg += 1; - } - else if (strcmp(arg[iarg], "tsuji") == 0){ - damping_local = TSUJI; - iarg += 1; - } - } - else if (strcmp(arg[iarg], "tangential") == 0){ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - tangential_local = TANGENTIAL_NOHISTORY; - } - else if (strcmp(arg[iarg+1], "mindlin") == 0){ - tangential_local = TANGENTIAL_MINDLIN; - tangential_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); - } - tangential_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - tangential_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - tangential_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - else if (strcmp(arg[iarg], "rolling") == 0){ - if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ - roll_local = ROLL_NONE; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - roll_local = ROLL_NOHISTORY; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ - roll_local = ROLL_SDS; - roll_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); - } - roll_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kR - roll_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR - roll_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. - iarg += 5; - } - } - else if (strcmp(arg[iarg], "twisting") == 0){ - if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ - twist_local = TWIST_NONE; - iarg += 2; - } - else if (strcmp(arg[iarg+1], "marshall") == 0){ - twist_local = TWIST_MARSHALL; - twist_history = 1; - iarg += 2; - } - else{ - if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); - if (strcmp(arg[iarg+1], "nohistory") == 0){ - twist_local = TWIST_NOHISTORY; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ - twist_local = TWIST_SDS; - twist_history = 1; - } - else{ - error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); - } - twist_coeffs_local[0] = force->numeric(FLERR,arg[iarg+2]); //kt - twist_coeffs_local[1] = force->numeric(FLERR,arg[iarg+3]); //gammat - twist_coeffs_local[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. - iarg += 5; - } - } - else error->all(FLERR, "Illegal pair coeff command"); - } - - //It is an error not to specify normal or tangential model - if ((normal_local < 0) || (tangential_local < 0)) error->all(FLERR, "Illegal pair coeff command, must specify normal contact model"); - - int count = 0; - double damp; - if (damping_local == TSUJI){ - double cor; - cor = normal_coeffs_local[1]; - damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ - 27.467*pow(cor,4)-18.022*pow(cor,5)+ - 4.8218*pow(cor,6); - } - else damp = normal_coeffs_local[1]; - - for (int i = ilo; i <= ihi; i++) { - for (int j = MAX(jlo,i); j <= jhi; j++) { - normal[i][j] = normal[j][i] = normal_local; - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_local[0]; - normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; - if (normal_local != HERTZ && normal_local != HOOKE) normal_coeffs[i][j][2] = normal_coeffs_local[2]; - if ((normal_local == JKR) || (normal_local == DMT)) - normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = normal_coeffs_local[3]; - - damping[i][j] = damping[j][i] = damping_local; - - tangential[i][j] = tangential[j][i] = tangential_local; - for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_local[k]; - - roll[i][j] = roll[j][i] = roll_local; - if (roll_local != ROLL_NONE) - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = roll_coeffs_local[k]; - - twist[i][j] = twist[j][i] = twist_local; - if (twist_local != TWIST_NONE && twist_local != TWIST_MARSHALL) - for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = twist_coeffs_local[k]; - - setflag[i][j] = 1; - count++; - } - } - if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); -} - -/* ---------------------------------------------------------------------- - init specific to this pair style -------------------------------------------------------------------------- */ - -void PairGranularMulti::init_style() -{ - int i; - - // error and warning checks - - if (!atom->radius_flag || !atom->rmass_flag) - error->all(FLERR,"Pair granular requires atom attributes radius, rmass"); - if (comm->ghost_velocity == 0) - error->all(FLERR,"Pair granular requires ghost atoms store velocity"); - - // Determine whether we need a granular neigh list, how large it needs to be - use_history = tangential_history || roll_history || twist_history; - - //For JKR, will need fix/neigh/history to keep track of touch arrays - for (int i = 1; i <= atom->ntypes; i++) - for (int j = 1; j <= atom->ntypes; j++) - if (normal[i][j] == JKR) use_history = 1; - - size_history = 3*tangential_history + 3*roll_history + twist_history; - - //Determine location of tangential/roll/twist histories in array - if (roll_history){ - if (tangential_history) roll_history_index = 3; - else roll_history_index = 0; - } - if (twist_history){ - if (tangential_history){ - if (roll_history) twist_history_index = 6; - else twist_history_index = 3; - } - else{ - if (roll_history) twist_history_index = 3; - else twist_history_index = 0; - } - } - - int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->size = 1; - if (use_history) neighbor->requests[irequest]->history = 1; - - dt = update->dt; - - // if history is stored: - // if first init, create Fix needed for storing history - - if (use_history && fix_history == NULL) { - char dnumstr[16]; - sprintf(dnumstr,"%d",size_history); - char **fixarg = new char*[4]; - fixarg[0] = (char *) "NEIGH_HISTORY"; - fixarg[1] = (char *) "all"; - fixarg[2] = (char *) "NEIGH_HISTORY"; - fixarg[3] = dnumstr; - modify->add_fix(4,fixarg,1); - delete [] fixarg; - fix_history = (FixNeighHistory *) modify->fix[modify->nfix-1]; - fix_history->pair = this; - } - - // check for FixFreeze and set freeze_group_bit - - for (i = 0; i < modify->nfix; i++) - if (strcmp(modify->fix[i]->style,"freeze") == 0) break; - if (i < modify->nfix) freeze_group_bit = modify->fix[i]->groupbit; - else freeze_group_bit = 0; - - // check for FixRigid so can extract rigid body masses - - fix_rigid = NULL; - for (i = 0; i < modify->nfix; i++) - if (modify->fix[i]->rigid_flag) break; - if (i < modify->nfix) fix_rigid = modify->fix[i]; - - // check for FixPour and FixDeposit so can extract particle radii - - int ipour; - for (ipour = 0; ipour < modify->nfix; ipour++) - if (strcmp(modify->fix[ipour]->style,"pour") == 0) break; - if (ipour == modify->nfix) ipour = -1; - - int idep; - for (idep = 0; idep < modify->nfix; idep++) - if (strcmp(modify->fix[idep]->style,"deposit") == 0) break; - if (idep == modify->nfix) idep = -1; - - // set maxrad_dynamic and maxrad_frozen for each type - // include future FixPour and FixDeposit particles as dynamic - - int itype; - for (i = 1; i <= atom->ntypes; i++) { - onerad_dynamic[i] = onerad_frozen[i] = 0.0; - if (ipour >= 0) { - itype = i; - double radmax = *((double *) modify->fix[ipour]->extract("radius",itype)); - if (normal[itype][itype] == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); - onerad_dynamic[i] = radmax; - } - if (idep >= 0) { - itype = i; - double radmax = *((double *) modify->fix[idep]->extract("radius",itype)); - if (normal[itype][itype] == JKR) radmax = radmax - 0.5*pulloff_distance(radmax, itype); - onerad_dynamic[i] = radmax; - } - } - - double *radius = atom->radius; - int *mask = atom->mask; - int *type = atom->type; - int nlocal = atom->nlocal; - - for (i = 0; i < nlocal; i++){ - double radius_cut = radius[i]; - if (normal[type[i]][type[i]] == JKR){ - radius_cut = radius[i] - 0.5*pulloff_distance(radius[i], type[i]); - } - if (mask[i] & freeze_group_bit){ - onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); - } - else{ - onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius_cut); - } - } - - MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); - - // set fix which stores history info - - if (size_history > 0){ - int ifix = modify->find_fix("NEIGH_HISTORY"); - if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); - fix_history = (FixNeighHistory *) modify->fix[ifix]; - } -} - -/* ---------------------------------------------------------------------- - init for one type pair i,j and corresponding j,i -------------------------------------------------------------------------- */ - -double PairGranularMulti::init_one(int i, int j) -{ - double cutoff; - if (setflag[i][j] == 0) { - if ((normal[i][i] != normal[j][j]) || - (damping[i][i] != damping[j][j]) || - (tangential[i][i] != tangential[j][j]) || - (roll[i][i] != roll[j][j]) || - (twist[i][i] != twist[j][j])){ - - char str[512]; - sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); - error->one(FLERR,str); - } - - if (normal[i][j] != HOOKE && normal[i][j] != HERTZ){ - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_stiffnessE(normal_coeffs[i][i][0], normal_coeffs[j][j][0], - normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - normal_coeffs[i][j][2] = normal_coeffs[j][i][2] = mix_stiffnessG(normal_coeffs[i][i][0], normal_coeffs[j][j][0], - normal_coeffs[i][i][2], normal_coeffs[j][j][2]); - } - else{ - normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = mix_geom(normal_coeffs[i][i][0], normal_coeffs[j][j][0]); - } - - normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = mix_geom(normal_coeffs[i][i][1], normal_coeffs[j][j][1]); - if ((normal[i][i] == JKR) || (normal[i][i] == DMT)) - normal_coeffs[i][j][3] = normal_coeffs[j][i][3] = mix_geom(normal_coeffs[i][i][3], normal_coeffs[j][j][3]); - - for (int k = 0; k < 3; k++) - tangential_coeffs[i][j][k] = normal_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - - - if (roll[i][i] != ROLL_NONE){ - for (int k = 0; k < 3; k++) - roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); - } - - if (twist[i][i] != TWIST_NONE && twist[i][i] != TWIST_MARSHALL){ - for (int k = 0; k < 3; k++) - twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); - } - } - - // It is possible that cut[i][j] at this point is still 0.0. This can happen when - // there is a future fix_pour after the current run. A cut[i][j] = 0.0 creates - // problems because neighbor.cpp uses min(cut[i][j]) to decide on the bin size - // To avoid this issue, for cases involving cut[i][j] = 0.0 (possible only - // if there is no current information about radius/cutoff of type i and j). - // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. - - if (cutoff_global < 0){ - if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || - ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || - ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist - cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; - cutoff = MAX(cutoff,maxrad_frozen[i]+maxrad_dynamic[j]); - cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) - double cutmax = 0.0; - for (int k = 1; k <= atom->ntypes; k++) { - cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); - cutmax = MAX(cutmax,2.0*maxrad_frozen[k]); - } - cutoff = cutmax; - } - } - else{ - cutoff = cutoff_global; - } - return cutoff; -} - - -/* ---------------------------------------------------------------------- - proc 0 writes to restart file - ------------------------------------------------------------------------- */ - -void PairGranularMulti::write_restart(FILE *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(&normal[i][j],sizeof(int),1,fp); - fwrite(&damping[i][j],sizeof(int),1,fp); - fwrite(&tangential[i][j],sizeof(int),1,fp); - fwrite(&roll[i][j],sizeof(int),1,fp); - fwrite(&twist[i][j],sizeof(int),1,fp); - fwrite(&normal_coeffs[i][j],sizeof(double),4,fp); - fwrite(&tangential_coeffs[i][j],sizeof(double),3,fp); - fwrite(&roll_coeffs[i][j],sizeof(double),3,fp); - fwrite(&twist_coeffs[i][j],sizeof(double),3,fp); - fwrite(&cut[i][j],sizeof(double),1,fp); - } - } - } -} - -/* ---------------------------------------------------------------------- - proc 0 reads from restart file, bcasts - ------------------------------------------------------------------------- */ - -void PairGranularMulti::read_restart(FILE *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(&normal[i][j],sizeof(int),1,fp); - fread(&damping[i][j],sizeof(int),1,fp); - fread(&tangential[i][j],sizeof(int),1,fp); - fread(&roll[i][j],sizeof(int),1,fp); - fread(&twist[i][j],sizeof(int),1,fp); - fread(&normal_coeffs[i][j],sizeof(double),4,fp); - fread(&tangential_coeffs[i][j],sizeof(double),3,fp); - fread(&roll_coeffs[i][j],sizeof(double),3,fp); - fread(&twist_coeffs[i][j],sizeof(double),3,fp); - fread(&cut[i][j],sizeof(double),1,fp); - } - MPI_Bcast(&normal[i][j],1,MPI_INT,0,world); - MPI_Bcast(&damping[i][j],1,MPI_INT,0,world); - MPI_Bcast(&tangential[i][j],1,MPI_INT,0,world); - MPI_Bcast(&roll[i][j],1,MPI_INT,0,world); - MPI_Bcast(&twist[i][j],1,MPI_INT,0,world); - MPI_Bcast(&normal_coeffs[i][j],4,MPI_DOUBLE,0,world); - MPI_Bcast(&tangential_coeffs[i][j],3,MPI_DOUBLE,0,world); - MPI_Bcast(&roll_coeffs[i][j],3,MPI_DOUBLE,0,world); - MPI_Bcast(&twist_coeffs[i][j],3,MPI_DOUBLE,0,world); - MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world); - } - } - } -} - - -/* ---------------------------------------------------------------------- */ - -void PairGranularMulti::reset_dt() -{ - dt = update->dt; -} - -/* ---------------------------------------------------------------------- */ - -double PairGranularMulti::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, double &fforce) -{ - double radi,radj,radsum; - double r,rinv,rsqinv,delx,dely,delz, nx, ny, nz, Reff; - double dR, dR2; - double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3,wr1,wr2,wr3; - double vtr1,vtr2,vtr3,vrel; - double mi,mj,meff,damp,ccel,tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; - - double knfac, damp_normal; - double k_tangential, damp_tangential; - double Fne, Ft, Fdamp, Fntot, Fcrit, Fscrit, Frcrit; - double fs, fs1, fs2, fs3; - - //For JKR - double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; - double delta, t0, t1, t2, t3, t4, t5, t6; - double sqrt1, sqrt2, sqrt3, sqrt4; - - - //Rolling - double k_roll, damp_roll; - double roll1, roll2, roll3, torroll1, torroll2, torroll3; - double rollmag, rolldotn, scalefac; - double fr, fr1, fr2, fr3; - - //Twisting - double k_twist, damp_twist, mu_twist; - double signtwist, magtwist, magtortwist, Mtcrit; - double tortwist1, tortwist2, tortwist3; - - double shrmag,rsht; - int jnum; - int *ilist,*jlist,*numneigh,**firstneigh; - int *touch,**firsttouch; - double *history,*allhistory,**firsthistory; - - double *radius = atom->radius; - radi = radius[i]; - radj = radius[j]; - radsum = radi + radj; - Reff = radi*radj/(radi+radj); - - bool touchflag; - if (normal[itype][jtype] == JKR){ - R2 = Reff*Reff; - coh = normal_coeffs[itype][jtype][3]; - a = cbrt(9.0*M_PI*coh*R2/(4*E)); - delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); - dist_pulloff = radsum+delta_pulloff; - touchflag = (rsq <= dist_pulloff*dist_pulloff); - } - else{ - touchflag = (rsq <= radsum*radsum); - } - - if (touchflag){ - fforce = 0.0; - for (int m = 0; m < single_extra; m++) svector[m] = 0.0; - return 0.0; - } - - double **x = atom->x; - delx = x[i][0] - x[j][0]; - dely = x[i][1] - x[j][1]; - delz = x[i][2] - x[j][2]; - r = sqrt(rsq); - rinv = 1.0/r; - - nx = delx*rinv; - ny = dely*rinv; - nz = delz*rinv; - - // relative translational velocity - - double **v = atom->v; - 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*nx + vr2*ny + vr3*nz; - vn1 = nx*vnnr; - vn2 = ny*vnnr; - vn3 = nz*vnnr; - - double *rmass = atom->rmass; - int *mask = atom->mask; - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - delta = radsum - r; - dR = delta*Reff; - - // tangential component - - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - - double **omega = atom->omega; - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // meff = effective mass of pair of particles - // if I or J part of rigid body, use body mass - // if I or J is frozen, meff is other particle - - int *type = atom->type; - - mi = rmass[i]; - mj = rmass[j]; - if (fix_rigid) { - // NOTE: ensure mass_rigid is current for owned+ghost atoms? - if (mass_rigid[i] > 0.0) mi = mass_rigid[i]; - if (mass_rigid[j] > 0.0) mj = mass_rigid[j]; - } - - meff = mi*mj / (mi+mj); - if (mask[i] & freeze_group_bit) meff = mj; - if (mask[j] & freeze_group_bit) meff = mi; - - delta = radsum - r; - dR = delta*Reff; - if (normal[itype][jtype] == JKR){ - dR2 = dR*dR; - t0 = coh*coh*R2*R2*E; - t1 = PI27SQ*t0; - t2 = 8*dR*dR2*E*E*E; - t3 = 4*dR2*E; - sqrt1 = MAX(0, t0*(t1+2*t2)); //In case of sqrt(0) < 0 due to precision issues - t4 = cbrt(t1+t2+THREEROOT3*M_PI*sqrt(sqrt1)); - t5 = t3/t4 + t4/E; - sqrt2 = MAX(0, 2*dR + t5); - t6 = sqrt(sqrt2); - sqrt3 = MAX(0, 4*dR - t5 + SIXROOT6*coh*M_PI*R2/(E*t6)); - a = INVROOT6*(t6 + sqrt(sqrt3)); - a2 = a*a; - knfac = FOURTHIRDS*E*a; - Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - } - else{ - knfac = E; - Fne = knfac*delta; - if (normal[itype][jtype] != HOOKE) - a = sqrt(dR); - Fne *= a; - if (normal[itype][jtype] == DMT) - Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; - } - - //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping[itype][jtype] == VELOCITY){ - damp_normal = normal_coeffs[itype][jtype][1]; - } - else if (damping[itype][jtype] == VISCOELASTIC){ - if (normal[itype][jtype] == HOOKE) a = sqrt(dR); - damp_normal = normal_coeffs[itype][jtype][1]*a*meff; - } - else if (damping[itype][jtype] == TSUJI){ - damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); - } - - Fdamp = -damp_normal*vnnr; - - Fntot = Fne + Fdamp; - - jnum = list->numneigh[i]; - jlist = list->firstneigh[i]; - - if (use_history){ - allhistory = fix_history->firstvalue[i]; - for (int jj = 0; jj < jnum; jj++) { - neighprev++; - if (neighprev >= jnum) neighprev = 0; - if (jlist[neighprev] == j) break; - } - history = &allhistory[size_history*neighprev]; - } - - //**************************************** - //Tangential force, including history effects - //**************************************** - - // tangential component - vt1 = vr1 - vn1; - vt2 = vr2 - vn2; - vt3 = vr3 - vn3; - - // relative rotational velocity - wr1 = (radi*omega[i][0] + radj*omega[j][0]); - wr2 = (radi*omega[i][1] + radj*omega[j][1]); - wr3 = (radi*omega[i][2] + radj*omega[j][2]); - - // relative tangential velocities - vtr1 = vt1 - (nz*wr2-ny*wr3); - vtr2 = vt2 - (nx*wr3-nz*wr1); - vtr3 = vt3 - (ny*wr1-nx*wr2); - vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; - vrel = sqrt(vrel); - - if (normal[itype][jtype] == JKR){ - F_pulloff = 3*M_PI*coh*Reff; - Fcrit = fabs(Fne + 2*F_pulloff); - } - else{ - Fcrit = fabs(Fne); - } - - //------------------------------ - //Tangential forces - //------------------------------ - k_tangential = tangential_coeffs[itype][jtype][0]; - if (normal[itype][jtype] != HOOKE){ - k_tangential *= a; - } - damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal; - - if (tangential_history){ - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - - // tangential forces = history + tangential velocity damping - fs1 = -k_tangential*history[0] - damp_tangential*vtr1; - fs2 = -k_tangential*history[1] - damp_tangential*vtr2; - fs3 = -k_tangential*history[2] - damp_tangential*vtr3; - - // rescale frictional displacements and forces if needed - Fscrit = tangential_coeffs[itype][jtype][2] * Fcrit; - fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); - if (fs > Fscrit) { - if (shrmag != 0.0) { - history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); - history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); - history[2] = -1.0/k_tangential*(Fscrit*fs3/fs + damp_tangential*vtr3); - fs1 *= Fscrit/fs; - fs2 *= Fscrit/fs; - fs3 *= Fscrit/fs; - } else fs1 = fs2 = fs3 = 0.0; - } - } - else{ //Classic pair gran/hooke (no history) - fs = meff*damp_tangential*vrel; - if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; - else Ft = 0.0; - fs1 = -Ft*vtr1; - fs2 = -Ft*vtr2; - fs3 = -Ft*vtr3; - } - - //**************************************** - // Rolling resistance - //**************************************** - - if (roll[itype][jtype] != ROLL_NONE){ - relrot1 = omega[i][0] - omega[j][0]; - relrot2 = omega[i][1] - omega[j][1]; - relrot3 = omega[i][2] - omega[j][2]; - - // rolling velocity, see eq. 31 of Wang et al, Particuology v 23, p 49 (2015) - // This is different from the Marshall papers, which use the Bagi/Kuhn formulation - // for rolling velocity (see Wang et al for why the latter is wrong) - vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; - vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; - vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; - - if (roll_history){ - int rhist0 = roll_history_index; - int rhist1 = rhist0 + 1; - int rhist2 = rhist1 + 1; - - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - - k_roll = roll_coeffs[itype][jtype][0]; - damp_roll = roll_coeffs[itype][jtype][1]; - fr1 = -k_roll*history[rhist0] - damp_roll*vrl1; - fr2 = -k_roll*history[rhist1] - damp_roll*vrl2; - fr3 = -k_roll*history[rhist2] - damp_roll*vrl3; - - // rescale frictional displacements and forces if needed - Frcrit = roll_coeffs[itype][jtype][2] * Fcrit; - - fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); - if (fr > Frcrit) { - if (rollmag != 0.0) { - history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); - history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); - history[rhist2] = -1.0/k_roll*(Frcrit*fr3/fr + damp_roll*vrl3); - fr1 *= Frcrit/fr; - fr2 *= Frcrit/fr; - fr3 *= Frcrit/fr; - } else fr1 = fr2 = fr3 = 0.0; - } - } - else{ // - fr = meff*roll_coeffs[itype][jtype][1]*vrlmag; - if (vrlmag != 0.0) fr = MIN(Fne, fr) / vrlmag; - else fr = 0.0; - fr1 = -fr*vrl1; - fr2 = -fr*vrl2; - fr3 = -fr*vrl3; - } - } - - //**************************************** - // Twisting torque, including history effects - //**************************************** - if (twist[itype][jtype] != TWIST_NONE){ - magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist[itype][jtype] == TWIST_MARSHALL){ - k_twist = 0.5*k_tangential*a*a;; //eq 32 - damp_twist = 0.5*damp_tangential*a*a; - mu_twist = TWOTHIRDS*a; - } - else{ - k_twist = twist_coeffs[itype][jtype][0]; - damp_twist = twist_coeffs[itype][jtype][1]; - mu_twist = twist_coeffs[itype][jtype][2]; - } - if (twist_history){ - magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) - signtwist = (magtwist > 0) - (magtwist < 0); - Mtcrit = TWOTHIRDS*a*Fscrit;//critical torque (eq 44) - if (fabs(magtortwist) > Mtcrit) { - history[twist_history_index] = 1.0/k_twist*(Mtcrit*signtwist - damp_twist*magtwist); - magtortwist = -Mtcrit * signtwist; //eq 34 - } - } - else{ - if (magtwist > 0) magtortwist = -damp_twist*magtwist; - else magtortwist = 0; - } - } - - // set single_extra quantities - - svector[0] = fs1; - svector[1] = fs2; - svector[2] = fs3; - svector[3] = fs; - svector[4] = fr1; - svector[5] = fr2; - svector[6] = fr3; - svector[7] = fr; - svector[8] = magtortwist; - return 0.0; -} - -/* ---------------------------------------------------------------------- */ - -int PairGranularMulti::pack_forward_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++] = mass_rigid[j]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void PairGranularMulti::unpack_forward_comm(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) - mass_rigid[i] = buf[m++]; -} - -/* ---------------------------------------------------------------------- - memory usage of local atom-based arrays - ------------------------------------------------------------------------- */ - -double PairGranularMulti::memory_usage() -{ - double bytes = nmax * sizeof(double); - return bytes; -} - -/* ---------------------------------------------------------------------- - mixing of Young's modulus (E) -------------------------------------------------------------------------- */ - -double PairGranularMulti::mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj) -{ - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((1-poisii*poisjj)/Eii+(1-poisjj*poisjj)/Ejj); -} - -/* ---------------------------------------------------------------------- - mixing of shear modulus (G) - ------------------------------------------------------------------------- */ - -double PairGranularMulti::mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj) -{ - double poisii = Eii/(2.0*Gii) - 1.0; - double poisjj = Ejj/(2.0*Gjj) - 1.0; - return 1/((2.0 -poisjj)/Gii+(2.0-poisjj)/Gjj); -} - -/* ---------------------------------------------------------------------- - mixing of everything else -------------------------------------------------------------------------- */ - -double PairGranularMulti::mix_geom(double valii, double valjj) -{ - return sqrt(valii*valjj); -} - - -/* ---------------------------------------------------------------------- - Compute pull-off distance (beyond contact) for a given radius and atom type -------------------------------------------------------------------------- */ - -double PairGranularMulti::pulloff_distance(double radius, int itype) -{ - double E, coh, a, delta_pulloff; - coh = normal_coeffs[itype][itype][3]; - E = mix_stiffnessE(normal_coeffs[itype][itype][0], normal_coeffs[itype][itype][0], - normal_coeffs[itype][itype][2], normal_coeffs[itype][itype][2]); - a = cbrt(9*M_PI*coh*radius*radius/(4*E)); - return a*a/radius - 2*sqrt(M_PI*coh*a/E); -} - diff --git a/src/GRANULAR/pair_granular_multi.h b/src/GRANULAR/pair_granular_multi.h deleted file mode 100644 index 95beb950f4..0000000000 --- a/src/GRANULAR/pair_granular_multi.h +++ /dev/null @@ -1,107 +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(granular/multi,PairGranularMulti) - -#else - -#ifndef LMP_PAIR_GRANULAR_MULTI_H -#define LMP_PAIR_GRANULAR_MULTI_H - -#include "pair.h" - -namespace LAMMPS_NS { - -class PairGranularMulti : public Pair { -public: - PairGranularMulti(class LAMMPS *); - virtual ~PairGranularMulti(); - virtual void compute(int, int); - virtual void settings(int, char **); - virtual void coeff(int, char **); - void init_style(); - double init_one(int, int); - void write_restart(FILE *); - void read_restart(FILE *); - void reset_dt(); - virtual double single(int, int, int, int, double, double, double, double &); - int pack_forward_comm(int, int *, double *, int, int *); - void unpack_forward_comm(int, int, double *); - double memory_usage(); - - protected: - double cut_global; - double dt; - int freeze_group_bit; - int use_history; - - int neighprev; - double *onerad_dynamic,*onerad_frozen; - double *maxrad_dynamic,*maxrad_frozen; - double **cut; - - class FixNeighHistory *fix_history; - - // storage of rigid body masses for use in granular interactions - - class Fix *fix_rigid; // ptr to rigid body fix, NULL if none - double *mass_rigid; // rigid mass for owned+ghost atoms - int nmax; // allocated size of mass_rigid - - virtual void allocate(); - -private: - int size_history; - - //Models - int **normal, **damping, **tangential, **roll, **twist; - - //History flags - int tangential_history, roll_history, twist_history; - - //Indices of history entries - int tangential_history_index; - int roll_history_index; - int twist_history_index; - - //Per-type coefficients, set in pair coeff command - double ***normal_coeffs; - double ***tangential_coeffs; - double ***roll_coeffs; - double ***twist_coeffs; - - //Optional user-specified global cutoff - double cutoff_global; - - double mix_stiffnessE(double Eii, double Ejj, double Gii, double Gjj); - double mix_stiffnessG(double Eii, double Ejj, double Gii, double Gjj); - double mix_geom(double valii, double valjj); - double pulloff_distance(double radius, int itype); -}; - -} - -#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. - - */ -- GitLab From 4ee98d18daad7150e1c53f29c1db0962b4f92a1b Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Wed, 6 Mar 2019 14:15:19 -0700 Subject: [PATCH 0201/1243] Fixed missing reference in pair_granular doc page --- doc/src/pair_granular.txt | 56 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 911e3cc1dc..dcc756201c 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -264,7 +264,7 @@ F_\{n0\} = \|\mathbf\{F\}_n\| \end\{equation\} For cohesive models such as {jkr} and {dmt}, the critical force is adjusted so that the critical tangential -force approaches \(\mu_t F_\{pulloff\}\), see "Marshall"_#Marshall2009, equation 43, and "Thornton"_#. +force approaches \(\mu_t F_\{pulloff\}\), see "Marshall"_#Marshall2009, equation 43, and "Thornton"_#Thornton1991. For both models, \(F_\{n0\}\) takes the form: \begin\{equation\} @@ -578,41 +578,41 @@ For the {pair_coeff} settings: {damping viscoelastic}, {rolling none}, {twisting [References:] - :link(Brill1996) +:link(Brill1996) [(Brilliantov et al, 1996)] Brilliantov, N. V., Spahn, F., Hertzsch, J. M., & Poschel, T. (1996). Model for collisions in granular gases. Physical review E, 53(5), 5382. - :link(Tsuji1992) - [(Tsuji et al, 1992)] Tsuji, Y., Tanaka, T., & Ishida, T. (1992). Lagrangian numerical simulation of plug flow of - cohesionless particles in a horizontal pipe. Powder technology, 71(3), 239-250. +:link(Tsuji1992) +[(Tsuji et al, 1992)] Tsuji, Y., Tanaka, T., & Ishida, T. (1992). Lagrangian numerical simulation of plug flow of +cohesionless particles in a horizontal pipe. Powder technology, 71(3), 239-250. - :link(JKR1971) - [(Johnson et al, 1971)] Johnson, K. L., Kendall, K., & Roberts, A. D. (1971). - Surface energy and the contact of elastic solids. Proc. R. Soc. Lond. A, 324(1558), 301-313. +:link(JKR1971) +[(Johnson et al, 1971)] Johnson, K. L., Kendall, K., & Roberts, A. D. (1971). +Surface energy and the contact of elastic solids. Proc. R. Soc. Lond. A, 324(1558), 301-313. - :link(DMT1975) - [Derjaguin et al, 1975)] Derjaguin, B. V., Muller, V. M., & Toporov, Y. P. (1975). Effect of contact deformations on the - adhesion of particles. Journal of Colloid and interface science, 53(2), 314-326. +:link(DMT1975) +[Derjaguin et al, 1975)] Derjaguin, B. V., Muller, V. M., & Toporov, Y. P. (1975). Effect of contact deformations on the +adhesion of particles. Journal of Colloid and interface science, 53(2), 314-326. - :link(Luding2008) - [(Luding, 2008)] Luding, S. (2008). Cohesive, frictional powders: contact models for tension. Granular matter, 10(4), 235. +:link(Luding2008) +[(Luding, 2008)] Luding, S. (2008). Cohesive, frictional powders: contact models for tension. Granular matter, 10(4), 235. - :link(Marshall2009) - [(Marshall, 2009)] Marshall, J. S. (2009). Discrete-element modeling of particulate aerosol flows. - Journal of Computational Physics, 228(5), 1541-1561. +:link(Marshall2009) +[(Marshall, 2009)] Marshall, J. S. (2009). Discrete-element modeling of particulate aerosol flows. +Journal of Computational Physics, 228(5), 1541-1561. - :link(Silbert2001) - [(Silbert, 2001)] Silbert, L. E., Ertas, D., Grest, G. S., Halsey, T. C., Levine, D., & Plimpton, S. J. (2001). - Granular flow down an inclined plane: Bagnold scaling and rheology. Physical Review E, 64(5), 051302. +:link(Silbert2001) +[(Silbert, 2001)] Silbert, L. E., Ertas, D., Grest, G. S., Halsey, T. C., Levine, D., & Plimpton, S. J. (2001). +Granular flow down an inclined plane: Bagnold scaling and rheology. Physical Review E, 64(5), 051302. - :link(Kuhn2004) - [(Kuhn and Bagi, 2005)] Kuhn, M. R., & Bagi, K. (2004). Contact rolling and deformation in granular media. - International journal of solids and structures, 41(21), 5793-5820. +:link(Kuhn2004) +[(Kuhn and Bagi, 2005)] Kuhn, M. R., & Bagi, K. (2004). Contact rolling and deformation in granular media. +International journal of solids and structures, 41(21), 5793-5820. - :link(Wang2015) - [(Wang et al, 2015)] Wang, Y., Alonso-Marroquin, F., & Guo, W. W. (2015). - Rolling and sliding in 3-D discrete element models. Particuology, 23, 49-55. +:link(Wang2015) +[(Wang et al, 2015)] Wang, Y., Alonso-Marroquin, F., & Guo, W. W. (2015). +Rolling and sliding in 3-D discrete element models. Particuology, 23, 49-55. - :link(Thornton1991) - [(Thornton, 1991)] Thornton, C. (1991). Interparticle sliding in the presence of adhesion. - J. Phys. D: Appl. Phys. 24 1942 \ No newline at end of file +:link(Thornton1991) +[(Thornton, 1991)] Thornton, C. (1991). Interparticle sliding in the presence of adhesion. +J. Phys. D: Appl. Phys. 24 1942 -- GitLab From 436e02aa6e0b7cee95d35a6cf2d56e051c7b58ee Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 6 Mar 2019 16:59:17 -0500 Subject: [PATCH 0202/1243] small corrections/clarifications to the pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 83892035c0..9e43aa0244 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,7 +4,7 @@ _Briefly describe the new feature(s), enhancement(s), or bugfix(es) included in **Related Issues** -__If this addresses an open GitHub Issue, mention the issue number here. Use the phrases `fixes #221` or `closes #135`, when you want those issues to be automatically closed when the pull request is merged_ +_If this addresses an open GitHub issue for this project, please mention the issue number here, and describe the relation. Use the phrases `fixes #221` or `closes #135`, when you want an issue to be automatically closed when the pull request is merged_ **Author(s)** @@ -16,7 +16,7 @@ By submitting this pull request, I agree, that my contribution will be included **Backward Compatibility** -_Please state whether any changes in the pull request break backward compatibility for inputs, and - if yes - explain what has been changed and why_ +_Please state whether any changes in the pull request will break backward compatibility for inputs, and - if yes - explain what has been changed and why_ **Implementation Notes** @@ -24,7 +24,7 @@ _Provide any relevant details about how the changes are implemented, how correct **Post Submission Checklist** -_Please check the fields below as they are completed **after** the pull request has been submitted_ +_Please check the fields below as they are completed **after** the pull request has been submitted. Delete lines that don't apply_ - [ ] The feature or features in this pull request is complete - [ ] Licensing information is complete -- GitLab From fe56cf04bca5db169502d59801876eb5401c6a66 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 6 Mar 2019 17:04:14 -0500 Subject: [PATCH 0203/1243] simplify the detection of whether the source folder is checked out from a local git repo --- cmake/CMakeLists.txt | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index ec32049445..1b0272c5e7 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1336,26 +1336,20 @@ set(temp_git_commit "(unknown)") set(temp_git_branch "(unknown)") set(temp_git_describe "(unknown)") set(temp_git_info "false") -if(GIT_FOUND) - execute_process(COMMAND ${GIT_EXECUTABLE} describe HEAD - RESULT_VARIABLE temp_in_git_checkout +if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git) + set(temp_git_info "true") + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + OUTPUT_VARIABLE temp_git_commit + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE temp_git_branch + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} describe --dirty=-modified + OUTPUT_VARIABLE temp_git_describe ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(temp_in_git_checkout EQUAL 0) - set(temp_git_info "true") - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD - OUTPUT_VARIABLE temp_git_commit - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD - OUTPUT_VARIABLE temp_git_branch - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} describe --dirty=-modified - OUTPUT_VARIABLE temp_git_describe - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - endif() endif() set(temp "${temp}const bool LAMMPS_NS::LAMMPS::has_git_info = ${temp_git_info};\n") -- GitLab From 2918dae87e23745aa7f20f81e2a5b32abe8176f1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 6 Mar 2019 17:12:41 -0500 Subject: [PATCH 0204/1243] correct variable name and path to find the local .git folder --- cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 1b0272c5e7..12a34fabc1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1336,7 +1336,7 @@ set(temp_git_commit "(unknown)") set(temp_git_branch "(unknown)") set(temp_git_describe "(unknown)") set(temp_git_info "false") -if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git) +if(GIT_FOUND AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../.git) set(temp_git_info "true") execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD OUTPUT_VARIABLE temp_git_commit -- GitLab From 4e632d1b79e59d1b7bdd644a63289487412e7f55 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 6 Mar 2019 17:32:08 -0500 Subject: [PATCH 0205/1243] implement another suggestion from @junghans --- cmake/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 12a34fabc1..f6f822676e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1338,15 +1338,15 @@ set(temp_git_describe "(unknown)") set(temp_git_info "false") if(GIT_FOUND AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../.git) set(temp_git_info "true") - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git rev-parse HEAD OUTPUT_VARIABLE temp_git_commit ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD + execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git rev-parse --abbrev-ref HEAD OUTPUT_VARIABLE temp_git_branch ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} describe --dirty=-modified + execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git describe --dirty=-modified OUTPUT_VARIABLE temp_git_describe ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) -- GitLab From 9408dd6e925c38819b6b207775a5b21ca720f0c6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 6 Mar 2019 18:41:43 -0500 Subject: [PATCH 0206/1243] use simpler way whether we are inside a git checkout in conventional build --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index f720abe6ec..f1030ae08f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -171,7 +171,7 @@ gitversion: @echo 'Gathering git version information' @echo '#ifndef LMP_GIT_VERSION_H' > ${TMPNAME}.lmpgitversion @echo '#define LMP_GIT_VERSION_H' >> ${TMPNAME}.lmpgitversion - @if (type git && git describe HEAD ) >> /dev/null 2>> /dev/null ; then \ + @if (type git && test -e ../.git ) >> /dev/null 2>> /dev/null ; then \ git='true'; \ commit=$$(git rev-parse HEAD); \ branch=$$(git rev-parse --abbrev-ref HEAD); \ -- GitLab From ff7276e494082d9fca6f766469f826b378970836 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 7 Mar 2019 08:56:13 -0700 Subject: [PATCH 0207/1243] Clean up the fused comm --- src/KOKKOS/atom_vec_kokkos.cpp | 14 +++++++------- src/KOKKOS/atom_vec_kokkos.h | 10 +++++----- src/KOKKOS/comm_kokkos.cpp | 8 +++----- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/KOKKOS/atom_vec_kokkos.cpp b/src/KOKKOS/atom_vec_kokkos.cpp index 5a1b1bde22..076e3e52fa 100644 --- a/src/KOKKOS/atom_vec_kokkos.cpp +++ b/src/KOKKOS/atom_vec_kokkos.cpp @@ -271,7 +271,7 @@ int AtomVecKokkos::pack_comm_self(const int &n, const DAT::tdual_int_2d &list, c /* ---------------------------------------------------------------------- */ template -struct AtomVecKokkos_PackCommSelfSquash { +struct AtomVecKokkos_PackCommSelfFused { typedef DeviceType device_type; typename ArrayTypes::t_x_array_randomread _x; @@ -283,7 +283,7 @@ struct AtomVecKokkos_PackCommSelfSquash { typename ArrayTypes::t_int_1d_const _sendnum_scan; X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; - AtomVecKokkos_PackCommSelfSquash( + AtomVecKokkos_PackCommSelfFused( const typename DAT::tdual_x_array &x, const typename DAT::tdual_int_2d &list, const typename DAT::tdual_int_2d &pbc, @@ -334,18 +334,18 @@ struct AtomVecKokkos_PackCommSelfSquash { /* ---------------------------------------------------------------------- */ -int AtomVecKokkos::pack_comm_self_squash(const int &n, const DAT::tdual_int_2d &list, const DAT::tdual_int_1d &sendnum_scan, +int AtomVecKokkos::pack_comm_self_fused(const int &n, const DAT::tdual_int_2d &list, const DAT::tdual_int_1d &sendnum_scan, const DAT::tdual_int_1d &firstrecv, const DAT::tdual_int_1d &pbc_flag, const DAT::tdual_int_2d &pbc) { if(commKK->forward_comm_on_host) { sync(Host,X_MASK); modified(Host,X_MASK); if(domain->triclinic) { - struct AtomVecKokkos_PackCommSelfSquash f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); } else { - struct AtomVecKokkos_PackCommSelfSquash f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); @@ -354,12 +354,12 @@ int AtomVecKokkos::pack_comm_self_squash(const int &n, const DAT::tdual_int_2d & sync(Device,X_MASK); modified(Device,X_MASK); if(domain->triclinic) { - struct AtomVecKokkos_PackCommSelfSquash f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); } else { - struct AtomVecKokkos_PackCommSelfSquash f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index d8541ceb86..64fd238fc0 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -52,11 +52,11 @@ class AtomVecKokkos : public AtomVec { const int &pbc_flag, const int pbc[]); virtual int - pack_comm_self_squash(const int &n, const DAT::tdual_int_2d &list, - const DAT::tdual_int_1d &sendnum_scan, - const DAT::tdual_int_1d &firstrecv, - const DAT::tdual_int_1d &pbc_flag, - const DAT::tdual_int_2d &pbc); + pack_comm_self_fused(const int &n, const DAT::tdual_int_2d &list, + const DAT::tdual_int_1d &sendnum_scan, + const DAT::tdual_int_1d &firstrecv, + const DAT::tdual_int_1d &pbc_flag, + const DAT::tdual_int_2d &pbc); virtual int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &list, diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index c782305ef5..5aa2cbdfbe 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -187,11 +187,9 @@ void CommKokkos::forward_comm_device(int dummy) k_sendlist.sync(); atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); - int comm_squash = 1; - if (comm_squash) { - n = avec->pack_comm_self_squash(totalsend,k_sendlist,k_sendnum_scan, + if (comm->nprocs == 1) { + n = avec->pack_comm_self_fused(totalsend,k_sendlist,k_sendnum_scan, k_firstrecv,k_pbc_flag,k_pbc); - DeviceType::fence(); } else { for (int iswap = 0; iswap < nswap; iswap++) { @@ -1045,7 +1043,7 @@ void CommKokkos::borders_device() { atom->map_set(); } - if (1) { + if (comm->nprocs == 1) { if (nswap > k_pbc.extent(0)) { k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); k_swap = DAT::tdual_int_2d("comm:swap",3,nswap); -- GitLab From f0e48931e40d833ab964b7abcfb5a08df5f4a3d7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 7 Mar 2019 10:17:32 -0700 Subject: [PATCH 0208/1243] Remove deprecated KOKKO_HAVE macros --- src/KOKKOS/angle_charmm_kokkos.cpp | 2 +- src/KOKKOS/angle_class2_kokkos.cpp | 2 +- src/KOKKOS/angle_cosine_kokkos.cpp | 2 +- src/KOKKOS/angle_harmonic_kokkos.cpp | 2 +- src/KOKKOS/atom_vec_kokkos.h | 2 +- src/KOKKOS/bond_class2_kokkos.cpp | 2 +- src/KOKKOS/bond_fene_kokkos.cpp | 2 +- src/KOKKOS/bond_harmonic_kokkos.cpp | 2 +- src/KOKKOS/compute_temp_kokkos.cpp | 2 +- src/KOKKOS/dihedral_charmm_kokkos.cpp | 2 +- src/KOKKOS/dihedral_class2_kokkos.cpp | 2 +- src/KOKKOS/dihedral_opls_kokkos.cpp | 2 +- src/KOKKOS/fix_dpd_energy_kokkos.cpp | 2 +- src/KOKKOS/fix_enforce2d_kokkos.cpp | 2 +- src/KOKKOS/fix_eos_table_rx_kokkos.cpp | 2 +- src/KOKKOS/fix_freeze_kokkos.cpp | 2 +- src/KOKKOS/fix_gravity_kokkos.cpp | 2 +- src/KOKKOS/fix_langevin_kokkos.cpp | 2 +- src/KOKKOS/fix_momentum_kokkos.cpp | 2 +- src/KOKKOS/fix_neigh_history_kokkos.cpp | 2 +- src/KOKKOS/fix_nh_kokkos.cpp | 2 +- src/KOKKOS/fix_nph_kokkos.cpp | 2 +- src/KOKKOS/fix_npt_kokkos.cpp | 2 +- src/KOKKOS/fix_nve_kokkos.cpp | 2 +- src/KOKKOS/fix_nve_sphere_kokkos.cpp | 2 +- src/KOKKOS/fix_nvt_kokkos.cpp | 2 +- src/KOKKOS/fix_qeq_reax_kokkos.cpp | 2 +- src/KOKKOS/fix_rx_kokkos.cpp | 2 +- src/KOKKOS/fix_setforce_kokkos.cpp | 2 +- src/KOKKOS/fix_shardlow_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_lj93_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_reflect_kokkos.cpp | 2 +- src/KOKKOS/gridcomm_kokkos.cpp | 2 +- src/KOKKOS/improper_class2_kokkos.cpp | 2 +- src/KOKKOS/improper_harmonic_kokkos.cpp | 2 +- src/KOKKOS/kokkos.cpp | 10 +++++----- src/KOKKOS/kokkos_type.h | 10 +++++----- src/KOKKOS/nbin_kokkos.cpp | 2 +- src/KOKKOS/nbin_ssa_kokkos.cpp | 2 +- src/KOKKOS/neigh_bond_kokkos.cpp | 2 +- src/KOKKOS/neigh_list_kokkos.cpp | 2 +- src/KOKKOS/npair_copy_kokkos.cpp | 2 +- src/KOKKOS/npair_halffull_kokkos.cpp | 2 +- src/KOKKOS/npair_kokkos.cpp | 16 ++++++++-------- src/KOKKOS/npair_kokkos.h | 6 +++--- src/KOKKOS/npair_skip_kokkos.cpp | 2 +- src/KOKKOS/npair_ssa_kokkos.cpp | 2 +- src/KOKKOS/pair_buck_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_buck_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_buck_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_debye_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_coul_wolf_kokkos.cpp | 2 +- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 2 +- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 2 +- src/KOKKOS/pair_eam_fs_kokkos.cpp | 2 +- src/KOKKOS/pair_eam_kokkos.cpp | 2 +- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 16 ++++++++-------- src/KOKKOS/pair_gran_hooke_history_kokkos.cpp | 2 +- ...air_lj_charmm_coul_charmm_implicit_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_class2_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_cut_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_expand_kokkos.cpp | 2 +- .../pair_lj_gromacs_coul_gromacs_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_gromacs_kokkos.cpp | 2 +- src/KOKKOS/pair_lj_sdk_kokkos.cpp | 2 +- src/KOKKOS/pair_morse_kokkos.cpp | 2 +- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 2 +- src/KOKKOS/pair_reaxc_kokkos.cpp | 2 +- src/KOKKOS/pair_snap_kokkos.cpp | 2 +- src/KOKKOS/pair_sw_kokkos.cpp | 2 +- src/KOKKOS/pair_table_kokkos.cpp | 2 +- src/KOKKOS/pair_table_rx_kokkos.cpp | 2 +- src/KOKKOS/pair_tersoff_kokkos.cpp | 2 +- src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 2 +- src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 2 +- src/KOKKOS/pair_vashishta_kokkos.cpp | 2 +- src/KOKKOS/pair_yukawa_kokkos.cpp | 2 +- src/KOKKOS/pair_zbl_kokkos.cpp | 2 +- src/KOKKOS/pppm_kokkos.cpp | 4 ++-- src/KOKKOS/rand_pool_wrap_kokkos.h | 2 +- src/KOKKOS/region_block_kokkos.cpp | 2 +- 92 files changed, 117 insertions(+), 117 deletions(-) diff --git a/src/KOKKOS/angle_charmm_kokkos.cpp b/src/KOKKOS/angle_charmm_kokkos.cpp index 7a83e0d654..ec2955b28d 100644 --- a/src/KOKKOS/angle_charmm_kokkos.cpp +++ b/src/KOKKOS/angle_charmm_kokkos.cpp @@ -447,7 +447,7 @@ void AngleCharmmKokkos::ev_tally(EV_FLOAT &ev, const int i, const in namespace LAMMPS_NS { template class AngleCharmmKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class AngleCharmmKokkos; #endif } diff --git a/src/KOKKOS/angle_class2_kokkos.cpp b/src/KOKKOS/angle_class2_kokkos.cpp index 289753a3ee..fe5b1895fe 100644 --- a/src/KOKKOS/angle_class2_kokkos.cpp +++ b/src/KOKKOS/angle_class2_kokkos.cpp @@ -598,7 +598,7 @@ void AngleClass2Kokkos::ev_tally(EV_FLOAT &ev, const int i, const in namespace LAMMPS_NS { template class AngleClass2Kokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class AngleClass2Kokkos; #endif } diff --git a/src/KOKKOS/angle_cosine_kokkos.cpp b/src/KOKKOS/angle_cosine_kokkos.cpp index d22ad20f55..08faa254f4 100644 --- a/src/KOKKOS/angle_cosine_kokkos.cpp +++ b/src/KOKKOS/angle_cosine_kokkos.cpp @@ -387,7 +387,7 @@ void AngleCosineKokkos::ev_tally(EV_FLOAT &ev, const int i, const in namespace LAMMPS_NS { template class AngleCosineKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class AngleCosineKokkos; #endif } diff --git a/src/KOKKOS/angle_harmonic_kokkos.cpp b/src/KOKKOS/angle_harmonic_kokkos.cpp index 250397c8e3..8cdab2063a 100644 --- a/src/KOKKOS/angle_harmonic_kokkos.cpp +++ b/src/KOKKOS/angle_harmonic_kokkos.cpp @@ -405,7 +405,7 @@ void AngleHarmonicKokkos::ev_tally(EV_FLOAT &ev, const int i, const namespace LAMMPS_NS { template class AngleHarmonicKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class AngleHarmonicKokkos; #endif } diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index efe55c47ad..51ae226cc3 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -125,7 +125,7 @@ class AtomVecKokkos : public AtomVec { size_t buffer_size; void* buffer; - #ifdef KOKKOS_HAVE_CUDA + #ifdef KOKKOS_ENABLE_CUDA template Kokkos::View::ev_tally(EV_FLOAT &ev, const int &i, const in namespace LAMMPS_NS { template class BondClass2Kokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class BondClass2Kokkos; #endif } diff --git a/src/KOKKOS/bond_fene_kokkos.cpp b/src/KOKKOS/bond_fene_kokkos.cpp index 4342223f7e..d37943ba82 100644 --- a/src/KOKKOS/bond_fene_kokkos.cpp +++ b/src/KOKKOS/bond_fene_kokkos.cpp @@ -401,7 +401,7 @@ void BondFENEKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int namespace LAMMPS_NS { template class BondFENEKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class BondFENEKokkos; #endif } diff --git a/src/KOKKOS/bond_harmonic_kokkos.cpp b/src/KOKKOS/bond_harmonic_kokkos.cpp index 35b957ffd3..6cdd4fe856 100644 --- a/src/KOKKOS/bond_harmonic_kokkos.cpp +++ b/src/KOKKOS/bond_harmonic_kokkos.cpp @@ -340,7 +340,7 @@ void BondHarmonicKokkos::ev_tally(EV_FLOAT &ev, const int &i, const namespace LAMMPS_NS { template class BondHarmonicKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class BondHarmonicKokkos; #endif } diff --git a/src/KOKKOS/compute_temp_kokkos.cpp b/src/KOKKOS/compute_temp_kokkos.cpp index d94c6e76b5..7b76f54f57 100644 --- a/src/KOKKOS/compute_temp_kokkos.cpp +++ b/src/KOKKOS/compute_temp_kokkos.cpp @@ -153,7 +153,7 @@ void ComputeTempKokkos::operator()(TagComputeTempVector, cons namespace LAMMPS_NS { template class ComputeTempKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class ComputeTempKokkos; #endif } diff --git a/src/KOKKOS/dihedral_charmm_kokkos.cpp b/src/KOKKOS/dihedral_charmm_kokkos.cpp index 9e25dda894..3931309dc1 100644 --- a/src/KOKKOS/dihedral_charmm_kokkos.cpp +++ b/src/KOKKOS/dihedral_charmm_kokkos.cpp @@ -786,7 +786,7 @@ void DihedralCharmmKokkos::ev_tally(EVM_FLOAT &evm, const int i, con namespace LAMMPS_NS { template class DihedralCharmmKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class DihedralCharmmKokkos; #endif } diff --git a/src/KOKKOS/dihedral_class2_kokkos.cpp b/src/KOKKOS/dihedral_class2_kokkos.cpp index de1d9c5458..c7db07a6cb 100644 --- a/src/KOKKOS/dihedral_class2_kokkos.cpp +++ b/src/KOKKOS/dihedral_class2_kokkos.cpp @@ -1127,7 +1127,7 @@ void DihedralClass2Kokkos::ev_tally(EV_FLOAT &ev, const int i1, cons namespace LAMMPS_NS { template class DihedralClass2Kokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class DihedralClass2Kokkos; #endif } diff --git a/src/KOKKOS/dihedral_opls_kokkos.cpp b/src/KOKKOS/dihedral_opls_kokkos.cpp index 3f34c2f5f3..9d01cf1a54 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.cpp +++ b/src/KOKKOS/dihedral_opls_kokkos.cpp @@ -536,7 +536,7 @@ void DihedralOPLSKokkos::ev_tally(EV_FLOAT &ev, const int i1, const namespace LAMMPS_NS { template class DihedralOPLSKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class DihedralOPLSKokkos; #endif } diff --git a/src/KOKKOS/fix_dpd_energy_kokkos.cpp b/src/KOKKOS/fix_dpd_energy_kokkos.cpp index b12c6a476e..d092cb4802 100644 --- a/src/KOKKOS/fix_dpd_energy_kokkos.cpp +++ b/src/KOKKOS/fix_dpd_energy_kokkos.cpp @@ -90,7 +90,7 @@ void FixDPDenergyKokkos::final_integrate() namespace LAMMPS_NS { template class FixDPDenergyKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixDPDenergyKokkos; #endif } diff --git a/src/KOKKOS/fix_enforce2d_kokkos.cpp b/src/KOKKOS/fix_enforce2d_kokkos.cpp index f4f239123b..346e440f55 100644 --- a/src/KOKKOS/fix_enforce2d_kokkos.cpp +++ b/src/KOKKOS/fix_enforce2d_kokkos.cpp @@ -162,7 +162,7 @@ void FixEnforce2DKokkos::post_force_item( int i ) const namespace LAMMPS_NS { template class FixEnforce2DKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixEnforce2DKokkos; #endif } diff --git a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp index 39f612ec46..2f730d1193 100644 --- a/src/KOKKOS/fix_eos_table_rx_kokkos.cpp +++ b/src/KOKKOS/fix_eos_table_rx_kokkos.cpp @@ -563,7 +563,7 @@ void FixEOStableRXKokkos::create_kokkos_tables() namespace LAMMPS_NS { template class FixEOStableRXKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixEOStableRXKokkos; #endif } diff --git a/src/KOKKOS/fix_freeze_kokkos.cpp b/src/KOKKOS/fix_freeze_kokkos.cpp index ccf7c7ff85..fb0c3841e6 100644 --- a/src/KOKKOS/fix_freeze_kokkos.cpp +++ b/src/KOKKOS/fix_freeze_kokkos.cpp @@ -118,7 +118,7 @@ void FixFreezeKokkos::operator()(const int i, OriginalForce &origina namespace LAMMPS_NS { template class FixFreezeKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixFreezeKokkos; #endif } diff --git a/src/KOKKOS/fix_gravity_kokkos.cpp b/src/KOKKOS/fix_gravity_kokkos.cpp index 2aff7af56c..5d3b4f62fb 100644 --- a/src/KOKKOS/fix_gravity_kokkos.cpp +++ b/src/KOKKOS/fix_gravity_kokkos.cpp @@ -115,7 +115,7 @@ void FixGravityKokkos::operator()(TagFixGravityMass, const int i, do namespace LAMMPS_NS { template class FixGravityKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixGravityKokkos; #endif } diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index 63b749a556..0947fee693 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -774,7 +774,7 @@ void FixLangevinKokkos::cleanup_copy() namespace LAMMPS_NS { template class FixLangevinKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixLangevinKokkos; #endif } diff --git a/src/KOKKOS/fix_momentum_kokkos.cpp b/src/KOKKOS/fix_momentum_kokkos.cpp index 493dffc3d9..38500531ca 100644 --- a/src/KOKKOS/fix_momentum_kokkos.cpp +++ b/src/KOKKOS/fix_momentum_kokkos.cpp @@ -199,7 +199,7 @@ void FixMomentumKokkos::end_of_step() namespace LAMMPS_NS { template class FixMomentumKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixMomentumKokkos; #endif } diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index ea0bd138f4..5f53950fe6 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -329,7 +329,7 @@ int FixNeighHistoryKokkos::unpack_exchange(int nlocal, double *buf) namespace LAMMPS_NS { template class FixNeighHistoryKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNeighHistoryKokkos; #endif } diff --git a/src/KOKKOS/fix_nh_kokkos.cpp b/src/KOKKOS/fix_nh_kokkos.cpp index 9e86e47bc9..ba6e8919ea 100644 --- a/src/KOKKOS/fix_nh_kokkos.cpp +++ b/src/KOKKOS/fix_nh_kokkos.cpp @@ -733,7 +733,7 @@ void FixNHKokkos::pre_exchange() namespace LAMMPS_NS { template class FixNHKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNHKokkos; #endif } diff --git a/src/KOKKOS/fix_nph_kokkos.cpp b/src/KOKKOS/fix_nph_kokkos.cpp index ed825ad9ee..c5072e6ae9 100644 --- a/src/KOKKOS/fix_nph_kokkos.cpp +++ b/src/KOKKOS/fix_nph_kokkos.cpp @@ -71,7 +71,7 @@ FixNPHKokkos::FixNPHKokkos(LAMMPS *lmp, int narg, char **arg) : namespace LAMMPS_NS { template class FixNPHKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNPHKokkos; #endif } diff --git a/src/KOKKOS/fix_npt_kokkos.cpp b/src/KOKKOS/fix_npt_kokkos.cpp index b33e733aee..c488c8e4f3 100644 --- a/src/KOKKOS/fix_npt_kokkos.cpp +++ b/src/KOKKOS/fix_npt_kokkos.cpp @@ -71,7 +71,7 @@ FixNPTKokkos::FixNPTKokkos(LAMMPS *lmp, int narg, char **arg) : namespace LAMMPS_NS { template class FixNPTKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNPTKokkos; #endif } diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index 621f16f420..052bf411d6 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -172,7 +172,7 @@ void FixNVEKokkos::cleanup_copy() namespace LAMMPS_NS { template class FixNVEKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNVEKokkos; #endif } diff --git a/src/KOKKOS/fix_nve_sphere_kokkos.cpp b/src/KOKKOS/fix_nve_sphere_kokkos.cpp index 9c408d0630..95945a858f 100644 --- a/src/KOKKOS/fix_nve_sphere_kokkos.cpp +++ b/src/KOKKOS/fix_nve_sphere_kokkos.cpp @@ -149,7 +149,7 @@ void FixNVESphereKokkos::final_integrate_item(const int i) const namespace LAMMPS_NS { template class FixNVESphereKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNVESphereKokkos; #endif } diff --git a/src/KOKKOS/fix_nvt_kokkos.cpp b/src/KOKKOS/fix_nvt_kokkos.cpp index 8b2d936274..4db42a62fb 100644 --- a/src/KOKKOS/fix_nvt_kokkos.cpp +++ b/src/KOKKOS/fix_nvt_kokkos.cpp @@ -52,7 +52,7 @@ FixNVTKokkos::FixNVTKokkos(LAMMPS *lmp, int narg, char **arg) : namespace LAMMPS_NS { template class FixNVTKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixNVTKokkos; #endif } diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp index 52a90eda01..9969ab7257 100644 --- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp @@ -1266,7 +1266,7 @@ int FixQEqReaxKokkos::unpack_exchange(int nlocal, double *buf) namespace LAMMPS_NS { template class FixQEqReaxKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixQEqReaxKokkos; #endif } diff --git a/src/KOKKOS/fix_rx_kokkos.cpp b/src/KOKKOS/fix_rx_kokkos.cpp index f636f6454d..80333e1e9b 100644 --- a/src/KOKKOS/fix_rx_kokkos.cpp +++ b/src/KOKKOS/fix_rx_kokkos.cpp @@ -2276,7 +2276,7 @@ void FixRxKokkos::unpack_reverse_comm(int n, int *list, double *buf) namespace LAMMPS_NS { template class FixRxKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixRxKokkos; #endif } diff --git a/src/KOKKOS/fix_setforce_kokkos.cpp b/src/KOKKOS/fix_setforce_kokkos.cpp index 5150c71249..5d15b88d76 100644 --- a/src/KOKKOS/fix_setforce_kokkos.cpp +++ b/src/KOKKOS/fix_setforce_kokkos.cpp @@ -184,7 +184,7 @@ void FixSetForceKokkos::operator()(TagFixSetForceNonConstant, const namespace LAMMPS_NS { template class FixSetForceKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixSetForceKokkos; #endif } diff --git a/src/KOKKOS/fix_shardlow_kokkos.cpp b/src/KOKKOS/fix_shardlow_kokkos.cpp index 99e51ebe38..968f877abd 100644 --- a/src/KOKKOS/fix_shardlow_kokkos.cpp +++ b/src/KOKKOS/fix_shardlow_kokkos.cpp @@ -808,7 +808,7 @@ double FixShardlowKokkos::memory_usage() namespace LAMMPS_NS { template class FixShardlowKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixShardlowKokkos; #endif } diff --git a/src/KOKKOS/fix_wall_lj93_kokkos.cpp b/src/KOKKOS/fix_wall_lj93_kokkos.cpp index 3aaa45f8a8..5dbb054175 100644 --- a/src/KOKKOS/fix_wall_lj93_kokkos.cpp +++ b/src/KOKKOS/fix_wall_lj93_kokkos.cpp @@ -98,7 +98,7 @@ void FixWallLJ93Kokkos::wall_particle_item(int i, value_type ewall) namespace LAMMPS_NS { template class FixWallLJ93Kokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixWallLJ93Kokkos; #endif } diff --git a/src/KOKKOS/fix_wall_reflect_kokkos.cpp b/src/KOKKOS/fix_wall_reflect_kokkos.cpp index 2516ac6577..75a5c1a81e 100644 --- a/src/KOKKOS/fix_wall_reflect_kokkos.cpp +++ b/src/KOKKOS/fix_wall_reflect_kokkos.cpp @@ -107,7 +107,7 @@ void FixWallReflectKokkos::operator()(TagFixWallReflectPostIntegrate namespace LAMMPS_NS { template class FixWallReflectKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class FixWallReflectKokkos; #endif } diff --git a/src/KOKKOS/gridcomm_kokkos.cpp b/src/KOKKOS/gridcomm_kokkos.cpp index 64a9d6992f..14b84a5733 100644 --- a/src/KOKKOS/gridcomm_kokkos.cpp +++ b/src/KOKKOS/gridcomm_kokkos.cpp @@ -652,7 +652,7 @@ double GridCommKokkos::memory_usage() namespace LAMMPS_NS { template class GridCommKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class GridCommKokkos; #endif } diff --git a/src/KOKKOS/improper_class2_kokkos.cpp b/src/KOKKOS/improper_class2_kokkos.cpp index 2a7e8076d4..e3af52b494 100644 --- a/src/KOKKOS/improper_class2_kokkos.cpp +++ b/src/KOKKOS/improper_class2_kokkos.cpp @@ -1134,7 +1134,7 @@ void ImproperClass2Kokkos::ev_tally(EV_FLOAT &ev, const int i1, cons namespace LAMMPS_NS { template class ImproperClass2Kokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class ImproperClass2Kokkos; #endif } diff --git a/src/KOKKOS/improper_harmonic_kokkos.cpp b/src/KOKKOS/improper_harmonic_kokkos.cpp index b364d0b0c7..4d41f3ef48 100644 --- a/src/KOKKOS/improper_harmonic_kokkos.cpp +++ b/src/KOKKOS/improper_harmonic_kokkos.cpp @@ -484,7 +484,7 @@ void ImproperHarmonicKokkos::ev_tally(EV_FLOAT &ev, const int i1, co namespace LAMMPS_NS { template class ImproperHarmonicKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class ImproperHarmonicKokkos; #endif } diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 9973b5a688..295fddc6e7 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -26,7 +26,7 @@ #include "error.h" #include "memory_kokkos.h" -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA // for detecting GPU-direct support: // the function int have_gpu_direct() @@ -55,7 +55,7 @@ GPU_DIRECT_UNKNOWN GPU_DIRECT_UNKNOWN #endif -#endif // KOKKOS_HAVE_CUDA +#endif // KOKKOS_ENABLE_CUDA using namespace LAMMPS_NS; @@ -92,7 +92,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) } else if (strcmp(arg[iarg],"g") == 0 || strcmp(arg[iarg],"gpus") == 0) { -#ifndef KOKKOS_HAVE_CUDA +#ifndef KOKKOS_ENABLE_CUDA error->all(FLERR,"GPUs are requested but Kokkos has not been compiled for CUDA"); #endif if (iarg+2 > narg) error->all(FLERR,"Invalid Kokkos command-line args"); @@ -142,7 +142,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) if (logfile) fprintf(logfile," will use up to %d GPU(s) per node\n",ngpu); } -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA if (ngpu <= 0) error->all(FLERR,"Kokkos has been compiled for CUDA but no GPUs are requested"); @@ -166,7 +166,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) } #endif -#ifndef KOKKOS_HAVE_SERIAL +#ifndef KOKKOS_ENABLE_SERIAL if (num_threads == 1) error->warning(FLERR,"When using a single thread, the Kokkos Serial backend " "(i.e. Makefile.kokkos_mpi_only) gives better performance " diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index b88c92ff73..eb432cefae 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -24,7 +24,7 @@ enum{FULL=1u,HALFTHREAD=2u,HALF=4u,N2=8u}; -#if defined(KOKKOS_HAVE_CXX11) +#if defined(KOKKOS_ENABLE_CXX11) #undef ISFINITE #define ISFINITE(x) std::isfinite(x) #endif @@ -201,7 +201,7 @@ template<> struct ExecutionSpaceFromDevice { static const LAMMPS_NS::ExecutionSpace space = LAMMPS_NS::Host; }; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template<> struct ExecutionSpaceFromDevice { static const LAMMPS_NS::ExecutionSpace space = LAMMPS_NS::Device; @@ -776,7 +776,7 @@ typedef tdual_int_64::t_dev_um t_int_64_um; }; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template <> struct ArrayTypes { @@ -1087,12 +1087,12 @@ struct params_lj_coul { F_FLOAT cut_ljsq,cut_coulsq,lj1,lj2,lj3,lj4,offset; }; -#if defined(KOKKOS_HAVE_CXX11) +#if defined(KOKKOS_ENABLE_CXX11) #undef ISFINITE #define ISFINITE(x) std::isfinite(x) #endif -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA #define LAMMPS_LAMBDA [=] __device__ #else #define LAMMPS_LAMBDA [=] diff --git a/src/KOKKOS/nbin_kokkos.cpp b/src/KOKKOS/nbin_kokkos.cpp index c35c349675..090519a5a8 100644 --- a/src/KOKKOS/nbin_kokkos.cpp +++ b/src/KOKKOS/nbin_kokkos.cpp @@ -146,7 +146,7 @@ void NBinKokkos::binatomsItem(const int &i) const namespace LAMMPS_NS { template class NBinKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NBinKokkos; #endif } diff --git a/src/KOKKOS/nbin_ssa_kokkos.cpp b/src/KOKKOS/nbin_ssa_kokkos.cpp index d040ee2c83..ecf0e08535 100644 --- a/src/KOKKOS/nbin_ssa_kokkos.cpp +++ b/src/KOKKOS/nbin_ssa_kokkos.cpp @@ -301,7 +301,7 @@ void NBinSSAKokkos::sortBin( namespace LAMMPS_NS { template class NBinSSAKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NBinSSAKokkos; #endif } diff --git a/src/KOKKOS/neigh_bond_kokkos.cpp b/src/KOKKOS/neigh_bond_kokkos.cpp index 615dc94ee2..05a6fd605c 100644 --- a/src/KOKKOS/neigh_bond_kokkos.cpp +++ b/src/KOKKOS/neigh_bond_kokkos.cpp @@ -1301,7 +1301,7 @@ void NeighBondKokkos::update_domain_variables() namespace LAMMPS_NS { template class NeighBondKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NeighBondKokkos; #endif } diff --git a/src/KOKKOS/neigh_list_kokkos.cpp b/src/KOKKOS/neigh_list_kokkos.cpp index 93cf0af937..1c78fe3a68 100644 --- a/src/KOKKOS/neigh_list_kokkos.cpp +++ b/src/KOKKOS/neigh_list_kokkos.cpp @@ -53,7 +53,7 @@ void NeighListKokkos::grow(int nmax) namespace LAMMPS_NS { template class NeighListKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NeighListKokkos; #endif } diff --git a/src/KOKKOS/npair_copy_kokkos.cpp b/src/KOKKOS/npair_copy_kokkos.cpp index 8702816033..7dde05745c 100644 --- a/src/KOKKOS/npair_copy_kokkos.cpp +++ b/src/KOKKOS/npair_copy_kokkos.cpp @@ -53,7 +53,7 @@ void NPairCopyKokkos::build(NeighList *list) namespace LAMMPS_NS { template class NPairCopyKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NPairCopyKokkos; #endif } diff --git a/src/KOKKOS/npair_halffull_kokkos.cpp b/src/KOKKOS/npair_halffull_kokkos.cpp index 67481985da..cc8f663ef2 100644 --- a/src/KOKKOS/npair_halffull_kokkos.cpp +++ b/src/KOKKOS/npair_halffull_kokkos.cpp @@ -121,7 +121,7 @@ void NPairHalffullKokkos::operator()(TagNPairHalffullCompute, namespace LAMMPS_NS { template class NPairHalffullKokkos; template class NPairHalffullKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NPairHalffullKokkos; template class NPairHalffullKokkos; #endif diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index 88017c3f9d..5e1b7b0414 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -187,7 +187,7 @@ void NPairKokkos::build(NeighList *list_) Kokkos::deep_copy(data.resize, data.h_resize); Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA #define BINS_PER_BLOCK 2 const int factor = atoms_per_bin<64?2:1; Kokkos::TeamPolicy config((mbins+factor-1)/factor,atoms_per_bin*factor); @@ -202,7 +202,7 @@ void NPairKokkos::build(NeighList *list_) if (newton_pair) { if (SIZE) { NPairKokkosBuildFunctorSize f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA if (ExecutionSpaceFromDevice::space == Device) Kokkos::parallel_for(config, f); else @@ -212,7 +212,7 @@ void NPairKokkos::build(NeighList *list_) #endif } else { NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA if (ExecutionSpaceFromDevice::space == Device) Kokkos::parallel_for(config, f); else @@ -224,7 +224,7 @@ void NPairKokkos::build(NeighList *list_) } else { if (SIZE) { NPairKokkosBuildFunctorSize f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA if (ExecutionSpaceFromDevice::space == Device) Kokkos::parallel_for(config, f); else @@ -234,7 +234,7 @@ void NPairKokkos::build(NeighList *list_) #endif } else { NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA if (ExecutionSpaceFromDevice::space == Device) Kokkos::parallel_for(config, f); else @@ -470,7 +470,7 @@ void NeighborKokkosExecute:: /* ---------------------------------------------------------------------- */ -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA extern __shared__ X_FLOAT sharedmem[]; /* ---------------------------------------------------------------------- */ @@ -910,7 +910,7 @@ void NeighborKokkosExecute:: /* ---------------------------------------------------------------------- */ -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template template __device__ inline void NeighborKokkosExecute::build_ItemSizeCuda(typename Kokkos::TeamPolicy::member_type dev) const @@ -1093,7 +1093,7 @@ template class NPairKokkos; template class NPairKokkos; template class NPairKokkos; template class NPairKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NPairKokkos; template class NPairKokkos; template class NPairKokkos; diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index 970e40c9fc..62138bd524 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -311,7 +311,7 @@ class NeighborKokkosExecute KOKKOS_FUNCTION void build_ItemSize(const int &i) const; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template __device__ inline void build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const; @@ -388,7 +388,7 @@ struct NPairKokkosBuildFunctor { void operator() (const int & i) const { c.template build_Item(i); } -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA __device__ inline void operator() (typename Kokkos::TeamPolicy::member_type dev) const { @@ -449,7 +449,7 @@ struct NPairKokkosBuildFunctorSize { c.template build_ItemSize(i); } -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA __device__ inline void operator() (typename Kokkos::TeamPolicy::member_type dev) const { c.template build_ItemSizeCuda(dev); diff --git a/src/KOKKOS/npair_skip_kokkos.cpp b/src/KOKKOS/npair_skip_kokkos.cpp index c537afaa6b..e614e624c9 100644 --- a/src/KOKKOS/npair_skip_kokkos.cpp +++ b/src/KOKKOS/npair_skip_kokkos.cpp @@ -151,7 +151,7 @@ void NPairSkipKokkos::operator()(TagNPairSkipCountLocal, const int & namespace LAMMPS_NS { template class NPairSkipKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NPairSkipKokkos; #endif } diff --git a/src/KOKKOS/npair_ssa_kokkos.cpp b/src/KOKKOS/npair_ssa_kokkos.cpp index d17e341f15..5234c4e6d2 100644 --- a/src/KOKKOS/npair_ssa_kokkos.cpp +++ b/src/KOKKOS/npair_ssa_kokkos.cpp @@ -751,7 +751,7 @@ void NPairSSAKokkosExecute::build_ghosts_onePhase(int workPhase) con namespace LAMMPS_NS { template class NPairSSAKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class NPairSSAKokkos; #endif } diff --git a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp index 9c12d2c978..18d09965be 100644 --- a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp @@ -360,7 +360,7 @@ double PairBuckCoulCutKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairBuckCoulCutKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairBuckCoulCutKokkos; #endif } diff --git a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp index 4978d3d7fc..0b44a83ebb 100644 --- a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp @@ -522,7 +522,7 @@ double PairBuckCoulLongKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairBuckCoulLongKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairBuckCoulLongKokkos; #endif } diff --git a/src/KOKKOS/pair_buck_kokkos.cpp b/src/KOKKOS/pair_buck_kokkos.cpp index 8785700186..999aefe4c3 100644 --- a/src/KOKKOS/pair_buck_kokkos.cpp +++ b/src/KOKKOS/pair_buck_kokkos.cpp @@ -274,7 +274,7 @@ double PairBuckKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairBuckKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairBuckKokkos; #endif } diff --git a/src/KOKKOS/pair_coul_cut_kokkos.cpp b/src/KOKKOS/pair_coul_cut_kokkos.cpp index b6e36d4f0d..7d29adc625 100644 --- a/src/KOKKOS/pair_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_coul_cut_kokkos.cpp @@ -280,7 +280,7 @@ double PairCoulCutKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairCoulCutKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairCoulCutKokkos; #endif } diff --git a/src/KOKKOS/pair_coul_debye_kokkos.cpp b/src/KOKKOS/pair_coul_debye_kokkos.cpp index 5d15be7d76..3de83b5bc4 100644 --- a/src/KOKKOS/pair_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_coul_debye_kokkos.cpp @@ -323,7 +323,7 @@ double PairCoulDebyeKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairCoulDebyeKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairCoulDebyeKokkos; #endif } diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index a714f665f7..7d03ee4968 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -422,7 +422,7 @@ int PairCoulDSFKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairCoulDSFKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairCoulDSFKokkos; #endif } diff --git a/src/KOKKOS/pair_coul_long_kokkos.cpp b/src/KOKKOS/pair_coul_long_kokkos.cpp index 1e8c6c5f4e..73b9521da0 100644 --- a/src/KOKKOS/pair_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_coul_long_kokkos.cpp @@ -471,7 +471,7 @@ double PairCoulLongKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairCoulLongKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairCoulLongKokkos; #endif } diff --git a/src/KOKKOS/pair_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_kokkos.cpp index 2bff824c3d..fe9c581cc1 100644 --- a/src/KOKKOS/pair_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_kokkos.cpp @@ -424,7 +424,7 @@ int PairCoulWolfKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairCoulWolfKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairCoulWolfKokkos; #endif } diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index 3282c9da1e..d2fcc81ea4 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -795,7 +795,7 @@ int PairDPDfdtEnergyKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairDPDfdtEnergyKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairDPDfdtEnergyKokkos; #endif } diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index e198ddb85a..6039282141 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -1199,7 +1199,7 @@ void PairEAMAlloyKokkos::file2array_alloy() namespace LAMMPS_NS { template class PairEAMAlloyKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairEAMAlloyKokkos; #endif } diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index f5e4445db3..81d9ba8326 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -1208,7 +1208,7 @@ void PairEAMFSKokkos::file2array_fs() namespace LAMMPS_NS { template class PairEAMFSKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairEAMFSKokkos; #endif } diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 6ef3d99ac3..22383f57c5 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -899,7 +899,7 @@ void PairEAMKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int & namespace LAMMPS_NS { template class PairEAMKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairEAMKokkos; #endif } diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index f38feea5f4..df24a5f4c7 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -232,7 +232,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) } else Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA Kokkos::parallel_for(Kokkos::RangePolicy(0,np_total),*this); #else int errorFlag = 0; @@ -277,7 +277,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) EV_FLOAT ev; -#ifdef KOKKOS_HAVE_CUDA // Use atomics +#ifdef KOKKOS_ENABLE_CUDA // Use atomics if (neighflag == HALF) { if (newton_pair) { @@ -814,7 +814,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics unique_token_type; unique_token_type unique_token; @@ -1156,7 +1156,7 @@ void PairExp6rxKokkos::operator()(TagPairExp6rxComputeNoAtomics::vectorized_operator(const int &ii, EV_FLOAT& Kokkos::View::value> > a_uCGnew = uCGnew; int tid = 0; -#ifndef KOKKOS_HAVE_CUDA +#ifndef KOKKOS_ENABLE_CUDA typedef Kokkos::Experimental::UniqueToken< DeviceType, Kokkos::Experimental::UniqueTokenScope::Global> unique_token_type; unique_token_type unique_token; @@ -1623,7 +1623,7 @@ void PairExp6rxKokkos::vectorized_operator(const int &ii, EV_FLOAT& t_uCGnew(tid,i) += uCGnew_i; } -#ifndef KOKKOS_HAVE_CUDA +#ifndef KOKKOS_ENABLE_CUDA unique_token.release(tid); #endif } @@ -2128,7 +2128,7 @@ void partition_range( const int begin, const int end, int &thread_begin, int &th /* ---------------------------------------------------------------------- */ -#ifndef KOKKOS_HAVE_CUDA +#ifndef KOKKOS_ENABLE_CUDA template template void PairExp6rxKokkos::getMixingWeightsVect(const int np_total, int errorFlag, @@ -2654,7 +2654,7 @@ int PairExp6rxKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairExp6rxKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairExp6rxKokkos; #endif } diff --git a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp index 09e6c709a4..189407b541 100644 --- a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp +++ b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp @@ -581,7 +581,7 @@ void PairGranHookeHistoryKokkos::ev_tally_xyz_atom(EV_FLOAT &ev, int namespace LAMMPS_NS { template class PairGranHookeHistoryKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairGranHookeHistoryKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp index d0d290d1f1..ce7df2bec1 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp @@ -528,7 +528,7 @@ double PairLJCharmmCoulCharmmImplicitKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCharmmCoulCharmmImplicitKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCharmmCoulCharmmImplicitKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp index 2203dfa2a0..b31282e595 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp @@ -529,7 +529,7 @@ double PairLJCharmmCoulCharmmKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCharmmCoulCharmmKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCharmmCoulCharmmKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp index e1ecfbac3c..5d8a202aa4 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp @@ -536,7 +536,7 @@ double PairLJCharmmCoulLongKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCharmmCoulLongKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCharmmCoulLongKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp index abd0183e21..6eb3028101 100644 --- a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp @@ -364,7 +364,7 @@ double PairLJClass2CoulCutKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJClass2CoulCutKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJClass2CoulCutKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp index 5f850689d4..a388694876 100644 --- a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp @@ -517,7 +517,7 @@ double PairLJClass2CoulLongKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJClass2CoulLongKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJClass2CoulLongKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_class2_kokkos.cpp b/src/KOKKOS/pair_lj_class2_kokkos.cpp index 063753f1f8..33d1477443 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_kokkos.cpp @@ -292,7 +292,7 @@ double PairLJClass2Kokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJClass2Kokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJClass2Kokkos; #endif } diff --git a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp index a2067f8cf9..6001fabbed 100644 --- a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp @@ -357,7 +357,7 @@ double PairLJCutCoulCutKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCutCoulCutKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCutCoulCutKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp index 277f1f658c..10923bc5da 100644 --- a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp @@ -386,7 +386,7 @@ double PairLJCutCoulDebyeKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCutCoulDebyeKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCutCoulDebyeKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp index 165bd97276..47aa2ea7cc 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp @@ -377,7 +377,7 @@ double PairLJCutCoulDSFKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCutCoulDSFKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCutCoulDSFKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp index d02e83eb11..fa36cb1866 100644 --- a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp @@ -515,7 +515,7 @@ double PairLJCutCoulLongKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCutCoulLongKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCutCoulLongKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_kokkos.cpp index daaab8d29e..9b0ff902af 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_kokkos.cpp @@ -289,7 +289,7 @@ double PairLJCutKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJCutKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJCutKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_expand_kokkos.cpp b/src/KOKKOS/pair_lj_expand_kokkos.cpp index 55c8b200ef..3b8b9343d8 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_kokkos.cpp @@ -297,7 +297,7 @@ double PairLJExpandKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJExpandKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJExpandKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp index b7fb5acccb..d06ad9b44e 100644 --- a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp @@ -516,7 +516,7 @@ double PairLJGromacsCoulGromacsKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJGromacsCoulGromacsKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJGromacsCoulGromacsKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp index 5d2725ccdd..d447846333 100644 --- a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp @@ -348,7 +348,7 @@ double PairLJGromacsKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJGromacsKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJGromacsKokkos; #endif } diff --git a/src/KOKKOS/pair_lj_sdk_kokkos.cpp b/src/KOKKOS/pair_lj_sdk_kokkos.cpp index 8f719582fa..990e464341 100644 --- a/src/KOKKOS/pair_lj_sdk_kokkos.cpp +++ b/src/KOKKOS/pair_lj_sdk_kokkos.cpp @@ -326,7 +326,7 @@ double PairLJSDKKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairLJSDKKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairLJSDKKokkos; #endif } diff --git a/src/KOKKOS/pair_morse_kokkos.cpp b/src/KOKKOS/pair_morse_kokkos.cpp index 97c5f9be84..ab5eb817a1 100644 --- a/src/KOKKOS/pair_morse_kokkos.cpp +++ b/src/KOKKOS/pair_morse_kokkos.cpp @@ -303,7 +303,7 @@ double PairMorseKokkos::init_one(int i, int j) namespace LAMMPS_NS { template class PairMorseKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairMorseKokkos; #endif } diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index a6af26cb0f..5f19d73dfa 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -993,7 +993,7 @@ void PairMultiLucyRXKokkos::settings(int narg, char **arg) namespace LAMMPS_NS { template class PairMultiLucyRXKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairMultiLucyRXKokkos; #endif } diff --git a/src/KOKKOS/pair_reaxc_kokkos.cpp b/src/KOKKOS/pair_reaxc_kokkos.cpp index 9930894f45..56d2ebd8aa 100644 --- a/src/KOKKOS/pair_reaxc_kokkos.cpp +++ b/src/KOKKOS/pair_reaxc_kokkos.cpp @@ -4292,7 +4292,7 @@ void PairReaxCKokkos::operator()(PairReaxFindBondSpecies, const int } template class PairReaxCKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairReaxCKokkos; #endif } diff --git a/src/KOKKOS/pair_snap_kokkos.cpp b/src/KOKKOS/pair_snap_kokkos.cpp index 32510721d3..76d6aa5462 100644 --- a/src/KOKKOS/pair_snap_kokkos.cpp +++ b/src/KOKKOS/pair_snap_kokkos.cpp @@ -16,7 +16,7 @@ namespace LAMMPS_NS { template class PairSNAPKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairSNAPKokkos; #endif } diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index 5452d2293f..24022475ab 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -972,7 +972,7 @@ void PairSWKokkos::ev_tally3_atom(EV_FLOAT &ev, const int &i, namespace LAMMPS_NS { template class PairSWKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairSWKokkos; #endif } diff --git a/src/KOKKOS/pair_table_kokkos.cpp b/src/KOKKOS/pair_table_kokkos.cpp index b72df04c5f..9522e94706 100644 --- a/src/KOKKOS/pair_table_kokkos.cpp +++ b/src/KOKKOS/pair_table_kokkos.cpp @@ -550,7 +550,7 @@ void PairTableKokkos::cleanup_copy() { namespace LAMMPS_NS { template class PairTableKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairTableKokkos; #endif diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 30ca54986b..376984afa2 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -1301,7 +1301,7 @@ void PairTableRXKokkos::cleanup_copy() { namespace LAMMPS_NS { template class PairTableRXKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairTableRXKokkos; #endif diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index c3e1494d0b..a6668ca064 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -1289,7 +1289,7 @@ int PairTersoffKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairTersoffKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairTersoffKokkos; #endif } diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 61493794ba..303d2bdfda 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -1292,7 +1292,7 @@ int PairTersoffMODKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairTersoffMODKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairTersoffMODKokkos; #endif } diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index f51da2afde..ad4a2d444e 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -1386,7 +1386,7 @@ int PairTersoffZBLKokkos::sbmask(const int& j) const { namespace LAMMPS_NS { template class PairTersoffZBLKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairTersoffZBLKokkos; #endif } diff --git a/src/KOKKOS/pair_vashishta_kokkos.cpp b/src/KOKKOS/pair_vashishta_kokkos.cpp index 3d4bd22a3c..78ab8bfc85 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.cpp +++ b/src/KOKKOS/pair_vashishta_kokkos.cpp @@ -947,7 +947,7 @@ void PairVashishtaKokkos::ev_tally3_atom(EV_FLOAT &ev, const int &i, namespace LAMMPS_NS { template class PairVashishtaKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairVashishtaKokkos; #endif } diff --git a/src/KOKKOS/pair_yukawa_kokkos.cpp b/src/KOKKOS/pair_yukawa_kokkos.cpp index 8fc2fda120..951613a33e 100644 --- a/src/KOKKOS/pair_yukawa_kokkos.cpp +++ b/src/KOKKOS/pair_yukawa_kokkos.cpp @@ -295,7 +295,7 @@ compute_evdwl(const F_FLOAT& rsq, const int& i, const int&j, namespace LAMMPS_NS { template class PairYukawaKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairYukawaKokkos; #endif } diff --git a/src/KOKKOS/pair_zbl_kokkos.cpp b/src/KOKKOS/pair_zbl_kokkos.cpp index f57d5eaad0..bcf33b405d 100644 --- a/src/KOKKOS/pair_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_zbl_kokkos.cpp @@ -433,7 +433,7 @@ void PairZBLKokkos::cleanup_copy() { namespace LAMMPS_NS { template class PairZBLKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PairZBLKokkos; #endif } diff --git a/src/KOKKOS/pppm_kokkos.cpp b/src/KOKKOS/pppm_kokkos.cpp index 7a02e973b1..bcac29ba9b 100644 --- a/src/KOKKOS/pppm_kokkos.cpp +++ b/src/KOKKOS/pppm_kokkos.cpp @@ -1648,7 +1648,7 @@ void PPPMKokkos::make_rho() nlocal = atomKK->nlocal; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA copymode = 1; Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); copymode = 0; @@ -3121,7 +3121,7 @@ double PPPMKokkos::memory_usage() namespace LAMMPS_NS { template class PPPMKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class PPPMKokkos; #endif } diff --git a/src/KOKKOS/rand_pool_wrap_kokkos.h b/src/KOKKOS/rand_pool_wrap_kokkos.h index 12255a8a62..c1461c5216 100644 --- a/src/KOKKOS/rand_pool_wrap_kokkos.h +++ b/src/KOKKOS/rand_pool_wrap_kokkos.h @@ -50,7 +50,7 @@ class RandPoolWrap : protected Pointers { KOKKOS_INLINE_FUNCTION RandWrap get_state() const { -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA error->all(FLERR,"Cannot use Marsaglia RNG with GPUs"); #endif diff --git a/src/KOKKOS/region_block_kokkos.cpp b/src/KOKKOS/region_block_kokkos.cpp index 8ff6e8937d..730ef81466 100644 --- a/src/KOKKOS/region_block_kokkos.cpp +++ b/src/KOKKOS/region_block_kokkos.cpp @@ -167,7 +167,7 @@ void RegBlockKokkos::rotate(double &x, double &y, double &z, double namespace LAMMPS_NS { template class RegBlockKokkos; -#ifdef KOKKOS_HAVE_CUDA +#ifdef KOKKOS_ENABLE_CUDA template class RegBlockKokkos; #endif } -- GitLab From 0edc588458d571e3664614ab33e55f320f1ed8f3 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 7 Mar 2019 10:23:17 -0700 Subject: [PATCH 0209/1243] Replace deprecated Kokkos capacity() with span() --- src/KOKKOS/atom_vec_kokkos.h | 20 ++++++++++---------- src/KOKKOS/kokkos_type.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index 51ae226cc3..b36edf4e2d 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -139,11 +139,11 @@ class AtomVecKokkos : public AtomVec { Kokkos::CudaHostPinnedSpace,typename ViewType::memory_space>::type, Kokkos::MemoryTraits > mirror_type; if (buffer_size == 0) { - buffer = Kokkos::kokkos_malloc(src.capacity()); - buffer_size = src.capacity(); - } else if (buffer_size < src.capacity()) { - buffer = Kokkos::kokkos_realloc(buffer,src.capacity()); - buffer_size = src.capacity(); + buffer = Kokkos::kokkos_malloc(src.span()); + buffer_size = src.span(); + } else if (buffer_size < src.span()) { + buffer = Kokkos::kokkos_realloc(buffer,src.span()); + buffer_size = src.span(); } return mirror_type( buffer , src.extent(0) , @@ -165,11 +165,11 @@ class AtomVecKokkos : public AtomVec { Kokkos::CudaHostPinnedSpace,typename ViewType::memory_space>::type, Kokkos::MemoryTraits > mirror_type; if (buffer_size == 0) { - buffer = Kokkos::kokkos_malloc(src.capacity()*sizeof(typename ViewType::value_type)); - buffer_size = src.capacity(); - } else if (buffer_size < src.capacity()) { - buffer = Kokkos::kokkos_realloc(buffer,src.capacity()*sizeof(typename ViewType::value_type)); - buffer_size = src.capacity(); + buffer = Kokkos::kokkos_malloc(src.span()*sizeof(typename ViewType::value_type)); + buffer_size = src.span(); + } else if (buffer_size < src.span()) { + buffer = Kokkos::kokkos_realloc(buffer,src.span()*sizeof(typename ViewType::value_type)); + buffer_size = src.span(); } mirror_type tmp_view( (typename ViewType::value_type*)buffer , src.extent(0) , diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index eb432cefae..ff96684edc 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -1074,7 +1074,7 @@ void memset_kokkos (ViewType &view) { #ifndef KOKKOS_USING_DEPRECATED_VIEW Kokkos::parallel_for(view.span()*sizeof(typename ViewType::value_type)/4, f); #else - Kokkos::parallel_for(view.capacity()*sizeof(typename ViewType::value_type)/4, f); + Kokkos::parallel_for(view.span()*sizeof(typename ViewType::value_type)/4, f); #endif ViewType::execution_space::fence(); } -- GitLab From 9cb2a5619490b52a70edb886226f9cf379995a2c Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 7 Mar 2019 10:47:40 -0700 Subject: [PATCH 0210/1243] Remove deprecated Kokkos code --- src/KOKKOS/atom_vec_kokkos.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index b36edf4e2d..58f21b9cd4 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -157,7 +157,7 @@ class AtomVecKokkos : public AtomVec { } template - void perform_async_copy(const ViewType& src, unsigned int space) { + void perform_async_copy(ViewType& src, unsigned int space) { typedef Kokkos::View Date: Thu, 7 Mar 2019 15:11:33 -0500 Subject: [PATCH 0211/1243] fix a memory leak in fix bocs --- src/USER-BOCS/fix_bocs.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/USER-BOCS/fix_bocs.cpp b/src/USER-BOCS/fix_bocs.cpp index bf11b1d6ba..7bdb8933e3 100644 --- a/src/USER-BOCS/fix_bocs.cpp +++ b/src/USER-BOCS/fix_bocs.cpp @@ -697,6 +697,11 @@ int FixBocs::read_F_table( char *filename, int p_basis_type ) "of %d in read_F_table",p_basis_type); error->all(FLERR,errmsg); } + // cleanup + for (i = 0; i < N_columns; ++i) { + free(data[i]); + } + free(data); return n_entries; } -- GitLab From a5c93e75a5280464c234ebaa50c652037ee8553e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 7 Mar 2019 15:12:22 -0500 Subject: [PATCH 0212/1243] ignore src/lmpgitversion.h --- src/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/src/.gitignore b/src/.gitignore index 9670d1ca20..d405cb209e 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -6,6 +6,7 @@ /style_*.h /lmpinstalledpkgs.h +/lmpgitversion.h /*_gpu.h /*_gpu.cpp -- GitLab From e62746ef27dd6e55919383f9da625fc720515967 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 7 Mar 2019 15:38:23 -0500 Subject: [PATCH 0213/1243] protect group command against options that require unavailble properties resulting in segfaults --- src/group.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/group.cpp b/src/group.cpp index 3bc3f3d7bf..6c19af8bc6 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -207,6 +207,12 @@ void Group::assign(int narg, char **arg) else if (strcmp(arg[1],"molecule") == 0) category = MOLECULE; else if (strcmp(arg[1],"id") == 0) category = ID; + if ((category == MOLECULE) && (!atom->molecular)) + error->all(FLERR,"Group command requires atom attribute molecule"); + + if ((category == ID) && (!atom->tag_enable)) + error->all(FLERR,"Group command requires atom IDs"); + // args = logical condition if (narg > 3 && @@ -362,10 +368,13 @@ void Group::assign(int narg, char **arg) } else if (strcmp(arg[1],"include") == 0) { if (narg != 3) error->all(FLERR,"Illegal group command"); - if (strcmp(arg[2],"molecule") != 0) - error->all(FLERR,"Illegal group command"); + if (strcmp(arg[2],"molecule") == 0) { + if (!atom->molecular) + error->all(FLERR,"Group command requires atom attribute molecule"); + + add_molecules(igroup,bit); - add_molecules(igroup,bit); + } else error->all(FLERR,"Illegal group command"); // style = subtract -- GitLab From e422e886de5a719a49c9974b92ce9193bcd1de1e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 8 Mar 2019 11:33:29 -0700 Subject: [PATCH 0214/1243] Add error check for team on and full neighborlist --- src/KOKKOS/kokkos.cpp | 3 +++ src/KOKKOS/kokkos.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 6c87835195..efd3a75042 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -344,6 +344,9 @@ void KokkosLMP::accelerator(int narg, char **arg) force->newton = force->newton_pair = force->newton_bond = newtonflag; + if (team_flag && neighflag != FULL) + error->all(FLERR,"Must use KOKKOS package option 'neigh full' with 'team on'"); + neighbor->binsize_user = binsize; if (binsize <= 0.0) neighbor->binsizeflag = 0; else neighbor->binsizeflag = 1; diff --git a/src/KOKKOS/kokkos.h b/src/KOKKOS/kokkos.h index a665329d70..c70d7a31f5 100644 --- a/src/KOKKOS/kokkos.h +++ b/src/KOKKOS/kokkos.h @@ -86,4 +86,8 @@ U: Must use Kokkos half/thread or full neighbor list with threads or GPUs Using Kokkos half-neighbor lists with threading is not allowed. +E: Must use KOKKOS package option 'neigh full' with 'team on' + +The 'team on' option requires a full neighbor list + */ -- GitLab From 14a00662e6efc8795b82262d48a1b6b9d0605db4 Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 11 Mar 2019 13:04:03 -0600 Subject: [PATCH 0215/1243] Commit JT 031119 - first working version of spinmin --- examples/SPIN/read_restart/in.spin.read_data | 2 +- src/SPIN/fix_precession_spin.cpp | 3 + src/SPIN/min_spinmin.cpp | 112 ++++++++++++------- src/SPIN/pair_spin_exchange.cpp | 5 +- 4 files changed, 80 insertions(+), 42 deletions(-) diff --git a/examples/SPIN/read_restart/in.spin.read_data b/examples/SPIN/read_restart/in.spin.read_data index 17343994b5..a450421699 100644 --- a/examples/SPIN/read_restart/in.spin.read_data +++ b/examples/SPIN/read_restart/in.spin.read_data @@ -40,6 +40,6 @@ thermo_style custom step time v_magnorm v_emag v_tmag temp etotal thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 10 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] +dump 1 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] run 100 diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index d3edb3ae8a..65d5e9120e 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -171,6 +171,9 @@ void FixPrecessionSpin::setup(int vflag) void FixPrecessionSpin::post_force(int /*vflag*/) { + + printf("test inside post force (precession) \n"); + // update mag field with time (potential improvement) if (varflag != CONSTANT) { diff --git a/src/SPIN/min_spinmin.cpp b/src/SPIN/min_spinmin.cpp index 08f91abae7..4b362fda87 100644 --- a/src/SPIN/min_spinmin.cpp +++ b/src/SPIN/min_spinmin.cpp @@ -96,7 +96,7 @@ int MinSpinMin::iterate(int maxiter) bigint ntimestep; //double vmax,vdotf,vdotfall,fdotf,fdotfall,scale; //double dtvone,dtv,dtf,dtfm; - //int flag,flagall; + int flag,flagall; //alpha_final = 0.0; @@ -226,29 +226,44 @@ int MinSpinMin::iterate(int maxiter) // } //} - //eprevious = ecurrent; - //ecurrent = energy_force(0); - //neval++; + eprevious = ecurrent; + ecurrent = energy_force(0); + neval++; //// energy tolerance criterion //// only check after DELAYSTEP elapsed since velocties reset to 0 //// sync across replicas if running multi-replica minimization - //if (update->etol > 0.0 && ntimestep-last_negative > DELAYSTEP) { + if (update->etol > 0.0 && ntimestep-last_negative > DELAYSTEP) { + if (update->multireplica == 0) { + if (fabs(ecurrent-eprevious) < + update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + return ETOL; + } else { + if (fabs(ecurrent-eprevious) < + update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) + flag = 0; + else flag = 1; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + if (flagall == 0) return ETOL; + } + } + + //// magnetic force tolerance criterion + //// sync across replicas if running multi-replica minimization + + //if (update->fmtol > 0.0) { + // fmdotfm = fmnorm_sqr(); // if (update->multireplica == 0) { - // if (fabs(ecurrent-eprevious) < - // update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) - // return ETOL; + // if (fmdotfm < update->fmtol*update->fmtol) return FTOL; // } else { - // if (fabs(ecurrent-eprevious) < - // update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY)) - // flag = 0; + // if (fmdotfm < update->fmtol*update->fmtol) flag = 0; // else flag = 1; - // MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); - // if (flagall == 0) return ETOL; + // MPI_Allreduce(&fmlag,&fmlagall,1,MPI_INT,MPI_SUM,universe->uworld); + // if (fmlagall == 0) return FTOL; // } //} - + //// force tolerance criterion //// sync across replicas if running multi-replica minimization @@ -266,11 +281,11 @@ int MinSpinMin::iterate(int maxiter) //// output for thermo, dump, restart files - //if (output->next == ntimestep) { - // timer->stamp(); - // output->write(ntimestep); - // timer->stamp(Timer::OUTPUT); - //} + if (output->next == ntimestep) { + timer->stamp(); + output->write(ntimestep); + timer->stamp(Timer::OUTPUT); + } } return MAXITER; @@ -296,6 +311,7 @@ double MinSpinMin::evaluate_dt() fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; fmaxsqone = MAX(fmaxsqone,fmsq); } + //printf("test inside evaluate dt, fmaxsqone = %g \n",fmaxsqone); //for (int i = 0; i < nlocal; i++) // if (mask[i] & groupbit) { // fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; @@ -310,18 +326,21 @@ double MinSpinMin::evaluate_dt() // finding max fm over all replicas, if necessary // this communicator would be invalid for multiprocess replicas + fmaxsqall = fmaxsqloc; if (update->multireplica == 1) { fmaxsqall = fmaxsqloc; MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); } - if (fmaxsqall < fmaxsqloc) - error->all(FLERR,"Incorrect fmaxall calc."); + //if (fmaxsqall < fmaxsqloc) + // error->all(FLERR,"Incorrect fmaxall calc."); // define max timestep // dividing by 10 the inverse of max frequency + //printf("test inside evaluate dt, fmaxsqall = %g \n",fmaxsqall); dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); + //printf("test inside evaluate dt, dtmax = %g \n",dtmax); return dtmax; } @@ -341,7 +360,7 @@ void MinSpinMin::advance_spins(double dts) double tdampx,tdampy,tdampz; double msq,scale,fm2,energy,dts2; double alpha; - double spi[3],fmi[3]; + //double spi[3],fmi[3]; double cp[3],g[3]; //cp[0] = cp[1] = cp[2] = 0.0; @@ -351,6 +370,9 @@ void MinSpinMin::advance_spins(double dts) // fictitious Gilbert damping of 1 alpha = 1.0; + //printf("test inside spinmin, dts %g \n",dts); + //printf("test inside spinmin, fmi i=%d, %g %g %g \n",1,fm[1][0],fm[1][1],fm[1][2]); + // loop on all spins on proc. //if (ireplica != nreplica-1 && ireplica != 0) @@ -358,19 +380,21 @@ void MinSpinMin::advance_spins(double dts) // if (mask[i] & groupbit) { for (int i = 0; i < nlocal; i++) { - spi[0] = sp[i][0]; - spi[1] = sp[i][1]; - spi[2] = sp[i][2]; - - fmi[0] = fm[i][0]; - fmi[1] = fm[i][1]; - fmi[2] = fm[i][2]; + //spi[0] = sp[i][0]; + //spi[1] = sp[i][1]; + //spi[2] = sp[i][2]; + // + //fmi[0] = fm[i][0]; + //fmi[1] = fm[i][1]; + //fmi[2] = fm[i][2]; // calc. damping torque - tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); - tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); - tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); + tdampx = -alpha*(fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1]); + tdampy = -alpha*(fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); + tdampz = -alpha*(fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); + + //printf("for %d, test tdamp: %g %g %g \n",i,tdampx,tdampy,tdampz); // apply advance algorithm (geometric, norm preserving) @@ -381,18 +405,27 @@ void MinSpinMin::advance_spins(double dts) cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; + //printf("for %d, test cp: %g %g %g \n",i,cp[0],cp[1],cp[2]); + g[0] = sp[i][0]+cp[0]*dts; g[1] = sp[i][1]+cp[1]*dts; g[2] = sp[i][2]+cp[2]*dts; - g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; - g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; - g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; + //g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; + //g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; + //g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; + g[0] += (tdampx*energy-0.5*sp[i][0]*fm2)*0.5*dts2; + g[1] += (tdampy*energy-0.5*sp[i][1]*fm2)*0.5*dts2; + g[2] += (tdampz*energy-0.5*sp[i][2]*fm2)*0.5*dts2; g[0] /= (1+0.25*fm2*dts2); g[1] /= (1+0.25*fm2*dts2); g[2] /= (1+0.25*fm2*dts2); - + + //printf("test inside spinmin, spi i=%d, %g %g %g \n",i,sp[i][0],sp[i][1],sp[i][2]); + //printf("test inside spinmin, fmi i=%d, %g %g %g \n",i,fm[i][0],fm[i][1],fm[i][2]); + //printf("for %d, test g: %g %g %g \n",i,g[0],g[1],g[2]); + sp[i][0] = g[0]; sp[i][1] = g[1]; sp[i][2] = g[2]; @@ -422,7 +455,8 @@ void MinSpinMin::advance_spins(double dts) // } - printf("test inside spinmin, dts = %g \n",dts); - printf("test inside spinmin, fmi i=%d, %g %g %g \n",1,fm[1][0],fm[1][1],fm[1][2]); - printf("test inside spinmin, spi i=%d, %g %g %g \n",1,sp[1][0],sp[1][1],sp[1][2]); + //printf("test inside spinmin, dts = %g \n",dts); + //printf("test inside spinmin, fmi i=%d, %g %g %g \n",1,fm[1][0],fm[1][1],fm[1][2]); + //printf("test inside spinmin, spi i=%d, %g %g %g \n",1,sp[1][0],sp[1][1],sp[1][2]); } + diff --git a/src/SPIN/pair_spin_exchange.cpp b/src/SPIN/pair_spin_exchange.cpp index ec21fe8838..84e771a2ed 100644 --- a/src/SPIN/pair_spin_exchange.cpp +++ b/src/SPIN/pair_spin_exchange.cpp @@ -161,8 +161,9 @@ void PairSpinExchange::init_style() if (strcmp(modify->fix[ifix]->style,"neb/spin") == 0) break; ifix++; } - if (ifix == modify->nfix) - error->all(FLERR,"pair/spin style requires nve/spin"); + // test remove if test + //if (ifix == modify->nfix) + // error->all(FLERR,"pair/spin style requires nve/spin"); // get the lattice_flag from nve/spin -- GitLab From 5fff18932d446df46a48f284f2df251a360fce38 Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 11 Mar 2019 13:23:55 -0600 Subject: [PATCH 0216/1243] Commit 2 JT 031119 - new input files gneb and spinmin --- examples/SPIN/gneb_bfo/Si.sw | 18 - examples/SPIN/gneb_bfo/final.hop1 | 2 - examples/SPIN/gneb_bfo/final.iron_spin_data | 82 -- .../{in.neb.spin_iron => in.gneb.iron} | 0 examples/SPIN/gneb_bfo/in.neb.hop1 | 67 -- examples/SPIN/gneb_bfo/in.neb.spin_iron_min | 42 - examples/SPIN/gneb_bfo/in.spin.bfo | 56 -- examples/SPIN/gneb_bfo/in.spin.dyna_iron | 53 -- examples/SPIN/gneb_bfo/in.spin.iron | 56 -- examples/SPIN/gneb_bfo/in.spin.single_spin | 57 -- examples/SPIN/gneb_bfo/in.spinmin.bfo | 83 ++ examples/SPIN/gneb_bfo/in.spinmin.iron | 71 ++ examples/SPIN/gneb_bfo/in.tad | 110 --- examples/SPIN/gneb_bfo/initial.hop1 | 860 ------------------ 14 files changed, 154 insertions(+), 1403 deletions(-) delete mode 100644 examples/SPIN/gneb_bfo/Si.sw delete mode 100644 examples/SPIN/gneb_bfo/final.hop1 delete mode 100644 examples/SPIN/gneb_bfo/final.iron_spin_data rename examples/SPIN/gneb_bfo/{in.neb.spin_iron => in.gneb.iron} (100%) delete mode 100644 examples/SPIN/gneb_bfo/in.neb.hop1 delete mode 100644 examples/SPIN/gneb_bfo/in.neb.spin_iron_min delete mode 100644 examples/SPIN/gneb_bfo/in.spin.bfo delete mode 100644 examples/SPIN/gneb_bfo/in.spin.dyna_iron delete mode 100644 examples/SPIN/gneb_bfo/in.spin.iron delete mode 100644 examples/SPIN/gneb_bfo/in.spin.single_spin create mode 100644 examples/SPIN/gneb_bfo/in.spinmin.bfo create mode 100644 examples/SPIN/gneb_bfo/in.spinmin.iron delete mode 100644 examples/SPIN/gneb_bfo/in.tad delete mode 100644 examples/SPIN/gneb_bfo/initial.hop1 diff --git a/examples/SPIN/gneb_bfo/Si.sw b/examples/SPIN/gneb_bfo/Si.sw deleted file mode 100644 index db4be100ef..0000000000 --- a/examples/SPIN/gneb_bfo/Si.sw +++ /dev/null @@ -1,18 +0,0 @@ -# DATE: 2007-06-11 CONTRIBUTOR: Aidan Thompson, athomps@sandia.gov CITATION: Stillinger and Weber, Phys Rev B, 31, 5262, (1985) -# Stillinger-Weber 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: -# epsilon = eV; sigma = Angstroms -# other quantities are unitless - -# format of a single entry (one or more lines): -# element 1, element 2, element 3, -# epsilon, sigma, a, lambda, gamma, costheta0, A, B, p, q, tol - -# Here are the original parameters in metal units, for Silicon from: -# -# Stillinger and Weber, Phys. Rev. B, v. 31, p. 5262, (1985) -# - -Si Si Si 2.1683 2.0951 1.80 21.0 1.20 -0.333333333333 - 7.049556277 0.6022245584 4.0 0.0 0.0 diff --git a/examples/SPIN/gneb_bfo/final.hop1 b/examples/SPIN/gneb_bfo/final.hop1 deleted file mode 100644 index 338e674a9c..0000000000 --- a/examples/SPIN/gneb_bfo/final.hop1 +++ /dev/null @@ -1,2 +0,0 @@ -1 -412 14.0 20.5 0 diff --git a/examples/SPIN/gneb_bfo/final.iron_spin_data b/examples/SPIN/gneb_bfo/final.iron_spin_data deleted file mode 100644 index b337bac188..0000000000 --- a/examples/SPIN/gneb_bfo/final.iron_spin_data +++ /dev/null @@ -1,82 +0,0 @@ -LAMMPS data file via write_data, version 4 Jan 2019, timestep = 0 - -32 atoms -1 atom types - -0.0000000000000000e+00 1.1465999999999999e+01 xlo xhi -0.0000000000000000e+00 1.1465999999999999e+01 ylo yhi -0.0000000000000000e+00 2.8664999999999998e+00 zlo zhi - -Masses - -1 55.845 - -Atoms # spin - -1 1 2.2000000000000002e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -2 1 2.2000000000000002e+00 1.4332499999999999e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -3 1 2.2000000000000002e+00 2.8664999999999998e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -4 1 2.2000000000000002e+00 4.2997499999999995e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -5 1 2.2000000000000002e+00 5.7329999999999997e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -6 1 2.2000000000000002e+00 7.1662499999999998e+00 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -7 1 2.2000000000000002e+00 8.5994999999999990e+00 0.0000000000000000e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -8 1 2.2000000000000002e+00 1.0032750000000000e+01 1.4332499999999999e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -9 1 2.2000000000000002e+00 0.0000000000000000e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -11 1 2.2000000000000002e+00 2.8664999999999998e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -13 1 2.2000000000000002e+00 5.7329999999999997e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -15 1 2.2000000000000002e+00 8.5994999999999990e+00 2.8664999999999998e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -10 1 2.2000000000000002e+00 1.4332499999999999e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -12 1 2.2000000000000002e+00 4.2997499999999995e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -14 1 2.2000000000000002e+00 7.1662499999999998e+00 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -16 1 2.2000000000000002e+00 1.0032750000000000e+01 4.2997499999999995e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -17 1 2.2000000000000002e+00 0.0000000000000000e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -18 1 2.2000000000000002e+00 1.4332499999999999e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -19 1 2.2000000000000002e+00 2.8664999999999998e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -20 1 2.2000000000000002e+00 4.2997499999999995e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -21 1 2.2000000000000002e+00 5.7329999999999997e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -22 1 2.2000000000000002e+00 7.1662499999999998e+00 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -23 1 2.2000000000000002e+00 8.5994999999999990e+00 5.7329999999999997e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -24 1 2.2000000000000002e+00 1.0032750000000000e+01 7.1662499999999998e+00 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -25 1 2.2000000000000002e+00 0.0000000000000000e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -27 1 2.2000000000000002e+00 2.8664999999999998e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -29 1 2.2000000000000002e+00 5.7329999999999997e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -31 1 2.2000000000000002e+00 8.5994999999999990e+00 8.5994999999999990e+00 0.0000000000000000e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -26 1 2.2000000000000002e+00 1.4332499999999999e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -28 1 2.2000000000000002e+00 4.2997499999999995e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -30 1 2.2000000000000002e+00 7.1662499999999998e+00 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -32 1 2.2000000000000002e+00 1.0032750000000000e+01 1.0032750000000000e+01 1.4332499999999999e+00 -1.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 - -Velocities - -1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 diff --git a/examples/SPIN/gneb_bfo/in.neb.spin_iron b/examples/SPIN/gneb_bfo/in.gneb.iron similarity index 100% rename from examples/SPIN/gneb_bfo/in.neb.spin_iron rename to examples/SPIN/gneb_bfo/in.gneb.iron diff --git a/examples/SPIN/gneb_bfo/in.neb.hop1 b/examples/SPIN/gneb_bfo/in.neb.hop1 deleted file mode 100644 index 6697330faa..0000000000 --- a/examples/SPIN/gneb_bfo/in.neb.hop1 +++ /dev/null @@ -1,67 +0,0 @@ -# 2d NEB surface simulation, hop from surface to become adatom -print "Test 1" - -dimension 2 -boundary p s p - -atom_style atomic -neighbor 0.3 bin -neigh_modify delay 5 -atom_modify map array sort 0 0.0 - -variable u uloop 20 - -# create geometry with flat surface - -lattice hex 0.9 -region box block 0 20 0 10 -0.25 0.25 - -#create_box 3 box -#create_atoms 1 box -#mass * 1.0 -#write_data initial.hop1 - -read_data ../examples/SPIN/gneb_bfo/initial.hop1 - -# LJ potentials - -pair_style lj/cut 2.5 -pair_coeff * * 1.0 1.0 2.5 -pair_modify shift yes - -# initial minimization to relax surface - -minimize 1.0e-6 1.0e-4 1000 10000 -reset_timestep 0 - -# define groups - -region 1 block INF INF INF 1.25 INF INF -group lower region 1 -group mobile subtract all lower -set group lower type 2 - -timestep 0.05 - -# group of NEB atoms - either block or single atom ID 412 - -region surround block 10 18 17 20 0 0 units box -group nebatoms region surround -#group nebatoms id 412 -set group nebatoms type 3 -group nonneb subtract all nebatoms - -fix 1 lower setforce 0.0 0.0 0.0 -fix 2 nebatoms neb 1.0 parallel ideal -fix 3 all enforce2d - -thermo 100 - -#dump 1 nebatoms atom 10 dump.neb.$u -#dump 2 nonneb atom 10 dump.nonneb.$u - -# run NEB for 2000 steps or to force tolerance - -min_style quickmin - -neb 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.hop1 diff --git a/examples/SPIN/gneb_bfo/in.neb.spin_iron_min b/examples/SPIN/gneb_bfo/in.neb.spin_iron_min deleted file mode 100644 index a38a8fbde5..0000000000 --- a/examples/SPIN/gneb_bfo/in.neb.spin_iron_min +++ /dev/null @@ -1,42 +0,0 @@ -# bcc iron in a 3d periodic box - -units metal -dimension 3 -boundary p p f - -atom_style spin - -# necessary for the serial algorithm (sametag) -atom_modify map array - -lattice bcc 2.8665 -region box block 0.0 4.0 0.0 4.0 0.0 1.0 -#create_box 1 box -#create_atoms 1 box - -read_data ../examples/SPIN/gneb_bfo/initial.iron_spin - -# setting mass, mag. moments, and interactions for bcc iron - -mass 1 55.845 -#set group all spin 2.2 -1.0 0.0 0.0 - -pair_style spin/exchange 3.5 -pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 - -neighbor 0.1 bin -neigh_modify every 10 check yes delay 20 - -fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 -fix 2 all langevin/spin 0.1 0.0 21 -fix 3 all neb/spin 1.0 -fix 4 all nve/spin lattice no -#parallel ideal - -timestep 0.0001 -thermo 100 - - -min_style spinmin -neb/spin 0.0 0.1 10 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin -#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spin.bfo b/examples/SPIN/gneb_bfo/in.spin.bfo deleted file mode 100644 index e3c88b0f06..0000000000 --- a/examples/SPIN/gneb_bfo/in.spin.bfo +++ /dev/null @@ -1,56 +0,0 @@ -# layer sc iron atoms (in the [001] plane) in bismuth oxide - -clear -units metal -atom_style spin - -dimension 3 -boundary p p f - -# necessary for the serial algorithm (sametag) -atom_modify map array - -lattice sc 3.96 -region box block 0.0 34.0 0.0 34.0 0.0 5.0 -create_box 1 box -create_atoms 1 box - -# setting mass, mag. moments, and interactions for bfo - -mass 1 1.0 - -set group all spin/random 11 2.50 - -#pair_style hybrid/overlay spin/exchange 6.0 spin/magelec 4.5 -pair_style hybrid/overlay spin/exchange 6.0 spin/magelec 4.5 spin/dmi 4.5 -pair_coeff * * spin/exchange exchange 6.0 -0.01575 0.0 1.965 -pair_coeff * * spin/magelec magelec 4.5 0.000109 1.0 1.0 1.0 -pair_coeff * * spin/dmi dmi 4.5 0.00005 1.0 1.0 1.0 - -neighbor 0.1 bin -neigh_modify every 10 check yes delay 20 - -fix 1 all precession/spin anisotropy 0.0000033 0.0 0.0 1.0 -fix 2 all langevin/spin 0.0 0.1 21 -fix 3 all nve/spin lattice no - -timestep 0.0002 - -compute out_mag all spin -compute out_pe all pe -compute out_ke all ke -compute out_temp all temp - -variable magz equal c_out_mag[3] -variable magnorm equal c_out_mag[4] -variable emag equal c_out_mag[5] -variable tmag equal c_out_mag[6] - -#thermo_style custom step time v_magnorm v_emag temp etotal -thermo_style custom step time v_magnorm pe ke v_emag temp etotal -thermo 10 - -compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 100 all custom 1 dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] - -run 2000 diff --git a/examples/SPIN/gneb_bfo/in.spin.dyna_iron b/examples/SPIN/gneb_bfo/in.spin.dyna_iron deleted file mode 100644 index 918819c816..0000000000 --- a/examples/SPIN/gneb_bfo/in.spin.dyna_iron +++ /dev/null @@ -1,53 +0,0 @@ -# bcc iron in a 3d periodic box - -clear -units metal -atom_style spin - -dimension 3 -boundary f f f - -# necessary for the serial algorithm (sametag) -atom_modify map array - -lattice bcc 2.8665 -region box block 0.0 4.0 0.0 4.0 0.0 1.0 -create_box 1 box -create_atoms 1 box - -#read_data ../examples/SPIN/gneb_bfo/initial.iron_spin - -# setting mass, mag. moments, and interactions for bcc iron - -mass 1 55.845 -set group all spin 2.2 -1.0 0.0 0.0 - -pair_style spin/exchange 3.5 -pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 - -neighbor 0.1 bin -neigh_modify every 10 check yes delay 20 - -fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 -fix 2 all langevin/spin 300.0 0.01 21 -#fix 3 all neb/spin 1.0 -fix 3 all nve/spin lattice no -timestep 0.0001 - -compute out_mag all spin -compute out_pe all pe -compute out_ke all ke -compute out_temp all temp - -variable magx equal c_out_mag[1] -variable magz equal c_out_mag[3] -variable magnorm equal c_out_mag[4] -variable emag equal c_out_mag[5] -variable tmag equal c_out_mag[6] - -thermo_style custom step time v_magx v_magnorm v_tmag temp v_emag ke pe etotal -thermo 100 - -compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] -run 10000 diff --git a/examples/SPIN/gneb_bfo/in.spin.iron b/examples/SPIN/gneb_bfo/in.spin.iron deleted file mode 100644 index 0c84845f5f..0000000000 --- a/examples/SPIN/gneb_bfo/in.spin.iron +++ /dev/null @@ -1,56 +0,0 @@ -# bcc iron in a 3d periodic box - -clear -units metal -atom_style spin - -dimension 3 -boundary p p p - -# necessary for the serial algorithm (sametag) -atom_modify map array - -lattice bcc 2.8665 -region box block 0.0 4.0 0.0 4.0 0.0 1.0 -create_box 1 box -create_atoms 1 box - -# setting mass, mag. moments, and interactions for bcc iron - -mass 1 55.845 - -set group all spin 2.2 1.0 0.0 0.0 -#velocity all create 100 4928459 rot yes dist gaussian - -pair_style spin/exchange 3.5 -pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 - -neighbor 0.1 bin -neigh_modify every 10 check yes delay 20 - -fix 1 all precession/spin zeeman 0.0 0.0 0.0 1.0 -fix 2 all langevin/spin 0.0 0.0 21 - -fix 3 all nve/spin lattice yes -timestep 0.0001 - -# compute and output options - -compute out_mag all spin -compute out_pe all pe -compute out_ke all ke -compute out_temp all temp - -variable magz equal c_out_mag[3] -variable magnorm equal c_out_mag[4] -variable emag equal c_out_mag[5] -variable tmag equal c_out_mag[6] - -thermo_style custom step time v_magnorm v_tmag temp v_emag ke pe etotal -thermo 50 - -compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] - -run 0 -write_data initial.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spin.single_spin b/examples/SPIN/gneb_bfo/in.spin.single_spin deleted file mode 100644 index 3a63c87b8c..0000000000 --- a/examples/SPIN/gneb_bfo/in.spin.single_spin +++ /dev/null @@ -1,57 +0,0 @@ -# bcc iron in a 3d periodic box - -clear -units metal -atom_style spin - -dimension 3 -boundary f f f -#boundary p p p - -# necessary for the serial algorithm (sametag) -atom_modify map array - -lattice sc 2.8665 -region box block 0.0 1.0 0.0 1.0 0.0 1.0 -create_box 1 box -create_atoms 1 box - -# setting mass, mag. moments, and interactions for bcc iron - -mass 1 55.845 - -set group all spin 2.2 0.0 0.0 1.0 -#velocity all create 100 4928459 rot yes dist gaussian - -pair_style spin/exchange 3.5 -pair_coeff * * exchange 3.4 0.0 0.2171 1.841 - -neighbor 0.1 bin -neigh_modify every 10 check yes delay 20 - -fix 1 all precession/spin zeeman 0.01 0.0 1.0 0.0 anisotropy 0.005 0.0 0.0 1.0 -fix 2 all langevin/spin 50.0 0.1 21 - -fix 3 all nve/spin lattice no -timestep 0.0001 - -# compute and output options - -compute out_mag all spin -compute out_pe all pe -compute out_ke all ke -compute out_temp all temp - -variable magz equal c_out_mag[3] -variable magnorm equal c_out_mag[4] -variable emag equal c_out_mag[5] -variable tmag equal c_out_mag[6] - -thermo_style custom step time v_magz v_magnorm v_tmag temp v_emag ke pe etotal -thermo 100 - -compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 100 all custom 1 dump_iron.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] - -run 50000 -write_data final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spinmin.bfo b/examples/SPIN/gneb_bfo/in.spinmin.bfo new file mode 100644 index 0000000000..c048ac32c6 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.spinmin.bfo @@ -0,0 +1,83 @@ +# bcc iron in a 3d periodic box + +units metal +dimension 3 +boundary p p f +atom_style spin + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice sc 3.96 +region box block 0.0 68.0 0.0 68.0 0.0 1.0 +create_box 1 box +create_atoms 1 box + +#read_data ../examples/SPIN/gneb_bfo/initial.iron_spin + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 1.0 +set group all spin/random 11 2.50 +#set group all spin 2.5 -1.0 0.0 0.0 + +pair_style hybrid/overlay spin/exchange 6.0 spin/magelec 4.5 spin/dmi 4.5 +pair_coeff * * spin/exchange exchange 6.0 -0.01575 0.0 1.965 +#pair_coeff * * spin/magelec magelec 4.5 0.000109 1.0 1.0 1.0 +pair_coeff * * spin/magelec magelec 4.5 0.00109 1.0 1.0 1.0 +pair_coeff * * spin/dmi dmi 4.5 0.00005 1.0 1.0 1.0 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +#fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 +fix 1 all precession/spin anisotropy 0.0000033 0.0 0.0 1.0 +fix 2 all langevin/spin 0.1 0.0 21 +fix 3 all nve/spin lattice no +#fix 3 all neb/spin 1.0 +#fix 4 all nve/spin lattice no +#parallel ideal + +timestep 0.0001 +#thermo 10 + +#compute outsp all property/atom spx spy spz sp fmx fmy fmz +#dump 1 all custom 100 dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +#min_style spinmin +#minimize 1.0e-6 1.0e-6 1000 10000 +#minimize 1.0e-6 1.0e-6 10000 10000 +#minimize 1.0e-7 1.0e-7 10000 10000 + +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo 50 +thermo_style custom step time v_magnorm v_emag v_tmag temp etotal +thermo_modify format float %20.15g + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 200 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] + +#timestep 0.0001 +#run 1 +min_style spinmin +#minimize 1.0e-6 1.0e-6 1000 10000 +#minimize 1.0e-6 1.0e-6 10000 10000 +minimize 1.0e-8 1.0e-8 10000 1000 + +#write_dump all custom dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] + +#compute outsp all property/atom spx spy spz sp fmx fmy fmz +#dump 1 all custom 1 dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] +#thermo 1 + +#neb/spin 0.0 0.1 10 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin +#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spinmin.iron b/examples/SPIN/gneb_bfo/in.spinmin.iron new file mode 100644 index 0000000000..4439960390 --- /dev/null +++ b/examples/SPIN/gneb_bfo/in.spinmin.iron @@ -0,0 +1,71 @@ +# bcc iron in a 3d periodic box + +units metal +dimension 3 +boundary p p f +atom_style spin + +# necessary for the serial algorithm (sametag) +atom_modify map array + +lattice bcc 2.8665 +region box block 0.0 4.0 0.0 4.0 0.0 1.0 +create_box 1 box +create_atoms 1 box + +#read_data ../examples/SPIN/gneb_bfo/initial.iron_spin + +# setting mass, mag. moments, and interactions for bcc iron + +mass 1 55.845 +set group all spin/random 31 2.2 +#set group all spin 2.2 -1.0 0.0 0.0 + +pair_style spin/exchange 3.5 +pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 + +neighbor 0.1 bin +neigh_modify every 10 check yes delay 20 + +#fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 +fix 1 all precession/spin anisotropy 0.001 0.0 0.0 1.0 +fix 2 all langevin/spin 0.1 0.0 21 +fix 3 all nve/spin lattice no +#fix 3 all neb/spin 1.0 +#fix 4 all nve/spin lattice no +#parallel ideal + +timestep 0.0001 + +#min_style spinmin +#minimize 1.0e-6 1.0e-6 1000 10000 +#minimize 1.0e-8 1.0e-6 1000 10000 + +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] +variable tmag equal c_out_mag[6] + +thermo 1 +thermo_style custom step time v_magnorm v_emag v_tmag temp etotal +thermo_modify format float %20.15g + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +dump 1 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] + +#timestep 0.0001 +#run 1 + +min_style spinmin +#minimize 1.0e-6 1.0e-6 1000 10000 +minimize 1.0e-8 1.0e-6 1000 10000 + + + +#neb/spin 0.0 0.1 10 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin +#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.tad b/examples/SPIN/gneb_bfo/in.tad deleted file mode 100644 index 674fdc8172..0000000000 --- a/examples/SPIN/gneb_bfo/in.tad +++ /dev/null @@ -1,110 +0,0 @@ -# temperature accelerated dynamics model for a single vacancy in bulk Si -# events occur when a neighboring atom diffuses to the vacant site -# run this on multiple partitions as -# mpirun -np 3 lmp_g++ -partition 3x1 -in in.tad - -units metal - -atom_style atomic -atom_modify map array -boundary p p p -atom_modify sort 0 0.0 - -# temperatures -variable tlo equal 1800.0 -variable thi equal 2400.0 - -# coordination number cutoff - -variable r equal 2.835 - -# minimization parameters - -variable etol equal 1.0e-5 -variable ftol equal 1.0e-5 -variable maxiter equal 100 -variable maxeval equal 100 -variable dmax equal 1.0e-1 - -# diamond unit cell - -variable a equal 5.431 -lattice custom $a & - a1 1.0 0.0 0.0 & - a2 0.0 1.0 0.0 & - a3 0.0 0.0 1.0 & - basis 0.0 0.0 0.0 & - basis 0.0 0.5 0.5 & - basis 0.5 0.0 0.5 & - basis 0.5 0.5 0.0 & - basis 0.25 0.25 0.25 & - basis 0.25 0.75 0.75 & - basis 0.75 0.25 0.75 & - basis 0.75 0.75 0.25 - -region myreg block 0 4 & - 0 4 & - 0 4 -create_box 1 myreg -create_atoms 1 region myreg - -mass 1 28.06 - -group Si type 1 - -velocity all create ${thi} 5287286 mom yes rot yes dist gaussian - -# make a vacancy - -group del id 300 -delete_atoms group del - -pair_style sw -pair_coeff * * ../examples/SPIN/gneb_bfo/Si.sw Si - -thermo 10 - -fix 1 all nve -fix 2 all langevin ${thi} ${thi} 0.1 48278 - -timestep 1.0e-3 -neighbor 1.0 bin -neigh_modify every 1 delay 10 check yes - -# equilibrate - -run 1000 - -# Eliminate COM motion -velocity all zero linear - -# only output atoms near vacancy - -compute coord all coord/atom cutoff $r - -#dump events all custom 1 dump.prd id type x y z -#dump_modify events thresh c_coord != 4 - -compute patom all pe/atom -compute pe all reduce sum c_patom -compute satom all stress/atom NULL -compute str all reduce sum c_satom[1] c_satom[2] c_satom[3] -variable press equal (c_str[1]+c_str[2]+c_str[3])/(3*vol) - -thermo_style custom step temp pe c_pe press v_press - -compute event all event/displace 1.0 - -unfix 1 -unfix 2 -fix 1 all nvt temp ${thi} ${thi} 0.1 - -# tad nsteps nevent tlo thi delta_conf tmax compute -# [min etol ftol niter neval] -# [neb etol_neb ftol_neb n1steps n2steps nevery] -# [neb_style min_style] -# [neb_log logfile] - -tad 2000 50 ${tlo} ${thi} 0.05 1.0 event & - min ${etol} ${ftol} ${maxiter} ${maxeval} & - neb 0.0 0.01 200 200 20 neb_style fire neb_log log.neb diff --git a/examples/SPIN/gneb_bfo/initial.hop1 b/examples/SPIN/gneb_bfo/initial.hop1 deleted file mode 100644 index 228708c314..0000000000 --- a/examples/SPIN/gneb_bfo/initial.hop1 +++ /dev/null @@ -1,860 +0,0 @@ -LAMMPS data file via write_data, version 27 Sep 2016, timestep = 0 - -420 atoms -3 atom types - -0.0000000000000000e+00 2.2653923264628304e+01 xlo xhi --1.9618873042551413e-03 1.9620834929855668e+01 ylo yhi --2.8317404080785380e-01 2.8317404080785380e-01 zlo zhi - -Masses - -1 1 -2 1 -3 1 - -Atoms # atomic - -1 1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -2 1 5.6634808161570760e-01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -3 1 1.1326961632314152e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -4 1 1.6990442448471228e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -5 1 2.2653923264628304e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -6 1 2.8317404080785380e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -7 1 3.3980884896942456e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -8 1 3.9644365713099532e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -9 1 4.5307846529256608e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -10 1 5.0971327345413684e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -11 1 5.6634808161570760e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -12 1 6.2298288977727836e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -13 1 6.7961769793884912e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -14 1 7.3625250610041988e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -15 1 7.9288731426199064e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -16 1 8.4952212242356140e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -17 1 9.0615693058513216e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -18 1 9.6279173874670292e+00 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -19 1 1.0194265469082737e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -20 1 1.0760613550698444e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -21 1 1.1326961632314152e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -22 1 1.1893309713929860e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -23 1 1.2459657795545567e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -24 1 1.3026005877161275e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -25 1 1.3592353958776982e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -26 1 1.4158702040392690e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -27 1 1.4725050122008398e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -28 1 1.5291398203624105e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -29 1 1.5857746285239813e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -30 1 1.6424094366855520e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -31 1 1.6990442448471228e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -32 1 1.7556790530086936e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -33 1 1.8123138611702643e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -34 1 1.8689486693318351e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -35 1 1.9255834774934058e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -36 1 1.9822182856549766e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -37 1 2.0388530938165474e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -38 1 2.0954879019781181e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -39 1 2.1521227101396889e+01 0.0000000000000000e+00 0.0000000000000000e+00 0 0 0 -40 1 2.2087575183012596e+01 9.8094365212757073e-01 0.0000000000000000e+00 0 0 0 -41 1 0.0000000000000000e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -42 1 5.6634808161570760e-01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -43 1 1.1326961632314152e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -44 1 1.6990442448471228e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -45 1 2.2653923264628304e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -46 1 2.8317404080785380e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -47 1 3.3980884896942456e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -48 1 3.9644365713099532e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -49 1 4.5307846529256608e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -50 1 5.0971327345413684e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -51 1 5.6634808161570760e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -52 1 6.2298288977727836e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -53 1 6.7961769793884912e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -54 1 7.3625250610041988e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -55 1 7.9288731426199064e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -56 1 8.4952212242356140e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -57 1 9.0615693058513216e+00 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -58 1 9.6279173874670292e+00 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -59 1 1.0194265469082737e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -60 1 1.0760613550698444e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -61 1 1.1326961632314152e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -62 1 1.1893309713929860e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -63 1 1.2459657795545567e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -64 1 1.3026005877161275e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -65 1 1.3592353958776982e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -66 1 1.4158702040392690e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -67 1 1.4725050122008398e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -68 1 1.5291398203624105e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -69 1 1.5857746285239813e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -70 1 1.6424094366855520e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -71 1 1.6990442448471228e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -72 1 1.7556790530086936e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -73 1 1.8123138611702643e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -74 1 1.8689486693318351e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -75 1 1.9255834774934058e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -76 1 1.9822182856549766e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -77 1 2.0388530938165474e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -78 1 2.0954879019781181e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -79 1 2.1521227101396889e+01 1.9618873042551415e+00 0.0000000000000000e+00 0 0 0 -80 1 2.2087575183012596e+01 2.9428309563827124e+00 0.0000000000000000e+00 0 0 0 -81 1 0.0000000000000000e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -82 1 5.6634808161570760e-01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -83 1 1.1326961632314152e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -84 1 1.6990442448471228e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -85 1 2.2653923264628304e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -86 1 2.8317404080785380e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -87 1 3.3980884896942456e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -88 1 3.9644365713099532e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -89 1 4.5307846529256608e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -90 1 5.0971327345413684e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -91 1 5.6634808161570760e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -92 1 6.2298288977727836e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -93 1 6.7961769793884912e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -94 1 7.3625250610041988e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -95 1 7.9288731426199064e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -96 1 8.4952212242356140e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -97 1 9.0615693058513216e+00 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -98 1 9.6279173874670292e+00 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -99 1 1.0194265469082737e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -100 1 1.0760613550698444e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -101 1 1.1326961632314152e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -102 1 1.1893309713929860e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -103 1 1.2459657795545567e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -104 1 1.3026005877161275e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -105 1 1.3592353958776982e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -106 1 1.4158702040392690e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -107 1 1.4725050122008398e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -108 1 1.5291398203624105e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -109 1 1.5857746285239813e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -110 1 1.6424094366855520e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -111 1 1.6990442448471228e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -112 1 1.7556790530086936e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -113 1 1.8123138611702643e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -114 1 1.8689486693318351e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -115 1 1.9255834774934058e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -116 1 1.9822182856549766e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -117 1 2.0388530938165474e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -118 1 2.0954879019781181e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -119 1 2.1521227101396889e+01 3.9237746085102829e+00 0.0000000000000000e+00 0 0 0 -120 1 2.2087575183012596e+01 4.9047182606378534e+00 0.0000000000000000e+00 0 0 0 -121 1 0.0000000000000000e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -122 1 5.6634808161570760e-01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -123 1 1.1326961632314152e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -124 1 1.6990442448471228e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -125 1 2.2653923264628304e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -126 1 2.8317404080785380e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -127 1 3.3980884896942456e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -128 1 3.9644365713099532e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -129 1 4.5307846529256608e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -130 1 5.0971327345413684e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -131 1 5.6634808161570760e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -132 1 6.2298288977727836e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -133 1 6.7961769793884912e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -134 1 7.3625250610041988e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -135 1 7.9288731426199064e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -136 1 8.4952212242356140e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -137 1 9.0615693058513216e+00 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -138 1 9.6279173874670292e+00 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -139 1 1.0194265469082737e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -140 1 1.0760613550698444e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -141 1 1.1326961632314152e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -142 1 1.1893309713929860e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -143 1 1.2459657795545567e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -144 1 1.3026005877161275e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -145 1 1.3592353958776982e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -146 1 1.4158702040392690e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -147 1 1.4725050122008398e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -148 1 1.5291398203624105e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -149 1 1.5857746285239813e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -150 1 1.6424094366855520e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -151 1 1.6990442448471228e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -152 1 1.7556790530086936e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -153 1 1.8123138611702643e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -154 1 1.8689486693318351e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -155 1 1.9255834774934058e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -156 1 1.9822182856549766e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -157 1 2.0388530938165474e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -158 1 2.0954879019781181e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -159 1 2.1521227101396889e+01 5.8856619127654248e+00 0.0000000000000000e+00 0 0 0 -160 1 2.2087575183012596e+01 6.8666055648929953e+00 0.0000000000000000e+00 0 0 0 -161 1 0.0000000000000000e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -162 1 5.6634808161570760e-01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -163 1 1.1326961632314152e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -164 1 1.6990442448471228e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -165 1 2.2653923264628304e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -166 1 2.8317404080785380e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -167 1 3.3980884896942456e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -168 1 3.9644365713099532e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -169 1 4.5307846529256608e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -170 1 5.0971327345413684e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -171 1 5.6634808161570760e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -172 1 6.2298288977727836e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -173 1 6.7961769793884912e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -174 1 7.3625250610041988e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -175 1 7.9288731426199064e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -176 1 8.4952212242356140e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -177 1 9.0615693058513216e+00 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -178 1 9.6279173874670292e+00 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -179 1 1.0194265469082737e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -180 1 1.0760613550698444e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -181 1 1.1326961632314152e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -182 1 1.1893309713929860e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -183 1 1.2459657795545567e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -184 1 1.3026005877161275e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -185 1 1.3592353958776982e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -186 1 1.4158702040392690e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -187 1 1.4725050122008398e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -188 1 1.5291398203624105e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -189 1 1.5857746285239813e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -190 1 1.6424094366855520e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -191 1 1.6990442448471228e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -192 1 1.7556790530086936e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -193 1 1.8123138611702643e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -194 1 1.8689486693318351e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -195 1 1.9255834774934058e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -196 1 1.9822182856549766e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -197 1 2.0388530938165474e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -198 1 2.0954879019781181e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -199 1 2.1521227101396889e+01 7.8475492170205658e+00 0.0000000000000000e+00 0 0 0 -200 1 2.2087575183012596e+01 8.8284928691481355e+00 0.0000000000000000e+00 0 0 0 -201 1 0.0000000000000000e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -202 1 5.6634808161570760e-01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -203 1 1.1326961632314152e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -204 1 1.6990442448471228e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -205 1 2.2653923264628304e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -206 1 2.8317404080785380e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -207 1 3.3980884896942456e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -208 1 3.9644365713099532e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -209 1 4.5307846529256608e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -210 1 5.0971327345413684e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -211 1 5.6634808161570760e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -212 1 6.2298288977727836e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -213 1 6.7961769793884912e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -214 1 7.3625250610041988e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -215 1 7.9288731426199064e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -216 1 8.4952212242356140e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -217 1 9.0615693058513216e+00 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -218 1 9.6279173874670292e+00 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -219 1 1.0194265469082737e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -220 1 1.0760613550698444e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -221 1 1.1326961632314152e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -222 1 1.1893309713929860e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -223 1 1.2459657795545567e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -224 1 1.3026005877161275e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -225 1 1.3592353958776982e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -226 1 1.4158702040392690e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -227 1 1.4725050122008398e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -228 1 1.5291398203624105e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -229 1 1.5857746285239813e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -230 1 1.6424094366855520e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -231 1 1.6990442448471228e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -232 1 1.7556790530086936e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -233 1 1.8123138611702643e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -234 1 1.8689486693318351e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -235 1 1.9255834774934058e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -236 1 1.9822182856549766e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -237 1 2.0388530938165474e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -238 1 2.0954879019781181e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -239 1 2.1521227101396889e+01 9.8094365212757069e+00 0.0000000000000000e+00 0 0 0 -240 1 2.2087575183012596e+01 1.0790380173403278e+01 0.0000000000000000e+00 0 0 0 -241 1 0.0000000000000000e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -242 1 5.6634808161570760e-01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -243 1 1.1326961632314152e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -244 1 1.6990442448471228e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -245 1 2.2653923264628304e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -246 1 2.8317404080785380e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -247 1 3.3980884896942456e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -248 1 3.9644365713099532e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -249 1 4.5307846529256608e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -250 1 5.0971327345413684e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -251 1 5.6634808161570760e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -252 1 6.2298288977727836e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -253 1 6.7961769793884912e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -254 1 7.3625250610041988e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -255 1 7.9288731426199064e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -256 1 8.4952212242356140e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -257 1 9.0615693058513216e+00 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -258 1 9.6279173874670292e+00 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -259 1 1.0194265469082737e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -260 1 1.0760613550698444e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -261 1 1.1326961632314152e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -262 1 1.1893309713929860e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -263 1 1.2459657795545567e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -264 1 1.3026005877161275e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -265 1 1.3592353958776982e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -266 1 1.4158702040392690e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -267 1 1.4725050122008398e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -268 1 1.5291398203624105e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -269 1 1.5857746285239813e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -270 1 1.6424094366855520e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -271 1 1.6990442448471228e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -272 1 1.7556790530086936e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -273 1 1.8123138611702643e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -274 1 1.8689486693318351e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -275 1 1.9255834774934058e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -276 1 1.9822182856549766e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -277 1 2.0388530938165474e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -278 1 2.0954879019781181e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -279 1 2.1521227101396889e+01 1.1771323825530850e+01 0.0000000000000000e+00 0 0 0 -280 1 2.2087575183012596e+01 1.2752267477658419e+01 0.0000000000000000e+00 0 0 0 -281 1 0.0000000000000000e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -282 1 5.6634808161570760e-01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -283 1 1.1326961632314152e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -284 1 1.6990442448471228e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -285 1 2.2653923264628304e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -286 1 2.8317404080785380e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -287 1 3.3980884896942456e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -288 1 3.9644365713099532e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -289 1 4.5307846529256608e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -290 1 5.0971327345413684e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -291 1 5.6634808161570760e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -292 1 6.2298288977727836e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -293 1 6.7961769793884912e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -294 1 7.3625250610041988e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -295 1 7.9288731426199064e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -296 1 8.4952212242356140e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -297 1 9.0615693058513216e+00 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -298 1 9.6279173874670292e+00 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -299 1 1.0194265469082737e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -300 1 1.0760613550698444e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -301 1 1.1326961632314152e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -302 1 1.1893309713929860e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -303 1 1.2459657795545567e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -304 1 1.3026005877161275e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -305 1 1.3592353958776982e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -306 1 1.4158702040392690e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -307 1 1.4725050122008398e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -308 1 1.5291398203624105e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -309 1 1.5857746285239813e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -310 1 1.6424094366855520e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -311 1 1.6990442448471228e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -312 1 1.7556790530086936e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -313 1 1.8123138611702643e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -314 1 1.8689486693318351e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -315 1 1.9255834774934058e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -316 1 1.9822182856549766e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -317 1 2.0388530938165474e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -318 1 2.0954879019781181e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -319 1 2.1521227101396889e+01 1.3733211129785991e+01 0.0000000000000000e+00 0 0 0 -320 1 2.2087575183012596e+01 1.4714154781913560e+01 0.0000000000000000e+00 0 0 0 -321 1 0.0000000000000000e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -322 1 5.6634808161570760e-01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -323 1 1.1326961632314152e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -324 1 1.6990442448471228e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -325 1 2.2653923264628304e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -326 1 2.8317404080785380e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -327 1 3.3980884896942456e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -328 1 3.9644365713099532e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -329 1 4.5307846529256608e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -330 1 5.0971327345413684e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -331 1 5.6634808161570760e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -332 1 6.2298288977727836e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -333 1 6.7961769793884912e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -334 1 7.3625250610041988e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -335 1 7.9288731426199064e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -336 1 8.4952212242356140e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -337 1 9.0615693058513216e+00 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -338 1 9.6279173874670292e+00 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -339 1 1.0194265469082737e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -340 1 1.0760613550698444e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -341 1 1.1326961632314152e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -342 1 1.1893309713929860e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -343 1 1.2459657795545567e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -344 1 1.3026005877161275e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -345 1 1.3592353958776982e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -346 1 1.4158702040392690e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -347 1 1.4725050122008398e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -348 1 1.5291398203624105e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -349 1 1.5857746285239813e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -350 1 1.6424094366855520e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -351 1 1.6990442448471228e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -352 1 1.7556790530086936e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -353 1 1.8123138611702643e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -354 1 1.8689486693318351e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -355 1 1.9255834774934058e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -356 1 1.9822182856549766e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -357 1 2.0388530938165474e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -358 1 2.0954879019781181e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -359 1 2.1521227101396889e+01 1.5695098434041132e+01 0.0000000000000000e+00 0 0 0 -360 1 2.2087575183012596e+01 1.6676042086168703e+01 0.0000000000000000e+00 0 0 0 -361 1 0.0000000000000000e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -362 1 5.6634808161570760e-01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -363 1 1.1326961632314152e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -364 1 1.6990442448471228e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -365 1 2.2653923264628304e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -366 1 2.8317404080785380e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -367 1 3.3980884896942456e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -368 1 3.9644365713099532e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -369 1 4.5307846529256608e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -370 1 5.0971327345413684e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -371 1 5.6634808161570760e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -372 1 6.2298288977727836e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -373 1 6.7961769793884912e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -374 1 7.3625250610041988e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -375 1 7.9288731426199064e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -376 1 8.4952212242356140e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -377 1 9.0615693058513216e+00 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -378 1 9.6279173874670292e+00 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -379 1 1.0194265469082737e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -380 1 1.0760613550698444e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -381 1 1.1326961632314152e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -382 1 1.1893309713929860e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -383 1 1.2459657795545567e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -384 1 1.3026005877161275e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -385 1 1.3592353958776982e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -386 1 1.4158702040392690e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -387 1 1.4725050122008398e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -388 1 1.5291398203624105e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -389 1 1.5857746285239813e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -390 1 1.6424094366855520e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -391 1 1.6990442448471228e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -392 1 1.7556790530086936e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -393 1 1.8123138611702643e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -394 1 1.8689486693318351e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -395 1 1.9255834774934058e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -396 1 1.9822182856549766e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -397 1 2.0388530938165474e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -398 1 2.0954879019781181e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -399 1 2.1521227101396889e+01 1.7656985738296271e+01 0.0000000000000000e+00 0 0 0 -400 1 2.2087575183012596e+01 1.8637929390423842e+01 0.0000000000000000e+00 0 0 0 -401 1 0.0000000000000000e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -402 1 1.1326961632314152e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -403 1 2.2653923264628304e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -404 1 3.3980884896942456e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -405 1 4.5307846529256608e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -406 1 5.6634808161570760e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -407 1 6.7961769793884912e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -408 1 7.9288731426199064e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -409 1 9.0615693058513216e+00 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -410 1 1.0194265469082737e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -411 1 1.1326961632314152e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -412 1 1.2459657795545567e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -413 1 1.3592353958776982e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -414 1 1.4725050122008398e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -415 1 1.5857746285239813e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -416 1 1.6990442448471228e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -417 1 1.8123138611702643e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -418 1 1.9255834774934058e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -419 1 2.0388530938165474e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 -420 1 2.1521227101396889e+01 1.9618873042551414e+01 0.0000000000000000e+00 0 0 0 - -Velocities - -1 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -2 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -3 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -4 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -5 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -6 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -7 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -8 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -9 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -10 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -11 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -12 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -13 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -14 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -15 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -16 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -17 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -18 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -19 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -20 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -21 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -22 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -23 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -24 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -25 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -26 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -27 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -28 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -29 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -30 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -31 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -32 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -33 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -34 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -35 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -36 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -37 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -38 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -39 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -40 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -41 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -42 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -43 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -44 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -45 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -46 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -47 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -48 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -49 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -50 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -51 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -52 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -53 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -54 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -55 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -56 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -57 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -58 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -59 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -60 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -61 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -62 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -63 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -64 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -65 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -66 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -67 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -68 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -69 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -70 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -71 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -72 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -73 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -74 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -75 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -76 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -77 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -78 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -79 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -80 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -81 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -82 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -83 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -84 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -85 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -86 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -87 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -88 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -89 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -90 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -91 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -92 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -93 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -94 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -95 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -96 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -97 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -98 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -99 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -100 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -101 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -102 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -103 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -104 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -105 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -106 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -107 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -108 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -109 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -110 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -111 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -112 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -113 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -114 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -115 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -116 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -117 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -118 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -119 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -120 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -121 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -122 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -123 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -124 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -125 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -126 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -127 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -128 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -129 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -130 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -131 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -132 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -133 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -134 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -135 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -136 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -137 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -138 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -139 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -140 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -141 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -142 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -143 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -144 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -145 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -146 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -147 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -148 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -149 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -150 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -151 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -152 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -153 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -154 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -155 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -156 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -157 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -158 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -159 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -160 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -161 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -162 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -163 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -164 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -165 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -166 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -167 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -168 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -169 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -170 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -171 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -172 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -173 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -174 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -175 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -176 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -177 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -178 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -179 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -180 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -181 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -182 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -183 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -184 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -185 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -186 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -187 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -188 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -189 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -190 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -191 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -192 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -193 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -194 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -195 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -196 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -197 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -198 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -199 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -200 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -201 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -202 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -203 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -204 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -205 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -206 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -207 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -208 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -209 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -210 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -211 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -212 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -213 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -214 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -215 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -216 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -217 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -218 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -219 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -220 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -221 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -222 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -223 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -224 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -225 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -226 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -227 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -228 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -229 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -230 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -231 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -232 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -233 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -234 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -235 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -236 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -237 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -238 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -239 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -240 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -241 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -242 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -243 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -244 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -245 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -246 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -247 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -248 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -249 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -250 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -251 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -252 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -253 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -254 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -255 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -256 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -257 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -258 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -259 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -260 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -261 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -262 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -263 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -264 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -265 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -266 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -267 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -268 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -269 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -270 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -271 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -272 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -273 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -274 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -275 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -276 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -277 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -278 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -279 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -280 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -281 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -282 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -283 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -284 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -285 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -286 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -287 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -288 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -289 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -290 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -291 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -292 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -293 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -294 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -295 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -296 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -297 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -298 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -299 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -300 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -301 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -302 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -303 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -304 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -305 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -306 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -307 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -308 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -309 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -310 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -311 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -312 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -313 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -314 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -315 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -316 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -317 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -318 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -319 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -320 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -321 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -322 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -323 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -324 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -325 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -326 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -327 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -328 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -329 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -330 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -331 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -332 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -333 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -334 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -335 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -336 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -337 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -338 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -339 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -340 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -341 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -342 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -343 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -344 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -345 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -346 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -347 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -348 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -349 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -350 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -351 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -352 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -353 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -354 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -355 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -356 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -357 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -358 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -359 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -360 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -361 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -362 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -363 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -364 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -365 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -366 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -367 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -368 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -369 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -370 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -371 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -372 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -373 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -374 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -375 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -376 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -377 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -378 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -379 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -380 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -381 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -382 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -383 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -384 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -385 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -386 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -387 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -388 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -389 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -390 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -391 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -392 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -393 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -394 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -395 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -396 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -397 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -398 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -399 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -400 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -401 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -402 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -403 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -404 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -405 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -406 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -407 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -408 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -409 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -410 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -411 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -412 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -413 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -414 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -415 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -416 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -417 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -418 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -419 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -420 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 -- GitLab From aecef752e8beee76465feb03c05276235dd41952 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 11 Mar 2019 13:41:20 -0600 Subject: [PATCH 0217/1243] Remove unnecessary data movement in fix_nve_kokkos --- src/KOKKOS/fix_nve_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index 052bf411d6..6db8ff8c0f 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -113,8 +113,8 @@ void FixNVEKokkos::initial_integrate_rmass_item(int i) const template void FixNVEKokkos::final_integrate() { - atomKK->sync(execution_space,datamask_read); - atomKK->modified(execution_space,datamask_modify); + atomKK->sync(execution_space,V_MASK | F_MASK | MASK_MASK | RMASS_MASK | TYPE_MASK); + atomKK->modified(execution_space,V_MASK); v = atomKK->k_v.view(); f = atomKK->k_f.view(); -- GitLab From e0c935b52d9d0384cfa397b13b48e66acf02f721 Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Mon, 11 Mar 2019 14:28:18 -0600 Subject: [PATCH 0218/1243] Additional changes to pair_granular: -added mindlin and mindlin/rescale tangential model options -torque from tangential force is now applied at the same point on both contacting particles -updated doc page to reflect changes above --- doc/src/pair_granular.txt | 56 ++++++++++++++++++---- src/GRANULAR/pair_granular.cpp | 88 +++++++++++++++++++++++++--------- src/GRANULAR/pair_granular.h | 2 + 3 files changed, 116 insertions(+), 30 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index dcc756201c..8db9567692 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -28,17 +28,17 @@ pair_style granular pair_coeff * * hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 :pre pair_style granular -pair_coeff * * hertz 1000.0 50.0 tangential linear_history 800.0 1.0 0.4 :pre +pair_coeff * * hertz 1000.0 50.0 tangential mindlin 800.0 1.0 0.4 :pre pair_style granular pair_coeff * * hertz 1000.0 0.3 tangential linear_history 800.0 1.0 0.4 damping tsuji :pre pair_style granular -pair_coeff 1 1 jkr 1000.0 50.0 tangential linear_history 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 1 1 jkr 1000.0 50.0 tangential mindlin 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall pair_coeff 2 2 hertz 200.0 20.0 tangential linear_history 300.0 1.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre pair_style granular -pair_coeff 1 1 hertz 1000.0 50.0 tangential linear_history 800.0 0.5 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 0.5 0.5 rolling sds 500.0 200.0 0.5 twisting marshall pair_coeff 2 2 dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall pair_coeff 1 2 dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre @@ -219,7 +219,9 @@ choice and associated parameters. Currently supported tangential model choices a expected parameters are as follows: {linear_nohistory} : \(x_\{\gamma,t\}\), \(\mu_s\) -{linear_history} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) :ol +{linear_history} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) +{mindlin} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) +{mindlin_rescale} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) :ol Here, \(x_\{\gamma,t\}\) is a dimensionless multiplier for the normal damping \(\eta_n\) that determines the magnitude of the @@ -273,6 +275,10 @@ F_\{n0\} = \|\mathbf\{F\}_ne + 2 F_\{pulloff\}\| Where \(F_\{pulloff\} = 3\pi \gamma R \) for {jkr}, and \(F_\{pulloff\} = 4\pi \gamma R \) for {dmt}. +The remaining tangential options all use accumulated tangential displacement (i.e. contact history). This +is discussed below in the context of the {linear_history} option, but the same treatment of the +accumulated displacement applies to the other options as well. + For {tangential linear_history}, the tangential force is given by: \begin\{equation\} @@ -320,17 +326,39 @@ equation 20 and related discussion): \end\{equation\} The tangential force is added to the total normal force (elastic plus damping) to produce the total force -on the particle. The tangential force also acts at the contact point to induce a torque on each -particle according to: +on the particle. The tangential force also acts at the contact point (defined as the center of the overlap region) +to induce a torque on each particle according to: \begin\{equation\} -\mathbf\{\tau\}_i = -R_i \mathbf\{n\} \times \mathbf\{F\}_t +\mathbf\{\tau\}_i = -(R_i - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t \end\{equation\} \begin\{equation\} -\mathbf\{\tau\}_j = -R_j \mathbf\{n\} \times \mathbf\{F\}_t +\mathbf\{\tau\}_j = -(R_j - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t \end\{equation\} +For {tangential mindlin}, the Mindlin no-slip solution is used, which differs from the {linear_history} +option by an additional factor of {a}, the radius of the contact region. The tangential force is given by: + +\begin\{equation\} +\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|-k_t a \mathbf\{\xi\} + \mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} +\end\{equation\} + +Here, {a} is the radius of the contact region, given by \(a = \delta R\) for all normal contact models, +except for {jkr}, where it is given implicitly by \(\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\), +see discussion above. + +The {mindlin_rescale} option uses the same form as {mindlin}, but the magnitude of the tangential +displacement is re-scaled as the contact unloads, i.e. if \(a < a_\{t_n-1\}\): +\begin\{equation\} +\mathbf\{\xi\} = \mathbf\{xi_\{t_n-1\}\} \frac\{a\}\{a_\{t_n-1\}\} +\end\{equation\} + +This accounts for the fact that a decrease in the contact area upon unloading leads to the contact +being unable to support the previous tangential loading, and spurious energy is created +without the rescaling above ("Walton"_#WaltonPC). See also discussion in "Thornton et al, 2013"_#Thornton2013, +particularly equation 18(b) of that work and associated discussion. + :line The optional {rolling} keyword enables rolling friction, which resists pure rolling @@ -616,3 +644,15 @@ Rolling and sliding in 3-D discrete element models. Particuology, 23, 49-55. :link(Thornton1991) [(Thornton, 1991)] Thornton, C. (1991). Interparticle sliding in the presence of adhesion. J. Phys. D: Appl. Phys. 24 1942 + +:link(Mindlin1949) +[(Mindlin, 1949)] Mindlin, R. D. (1949). Compliance of elastic bodies in contact. +J. Appl. Mech., ASME 16, 259-268. + +:line(Thornton2013) +[(Thornton et al, 2013)] Thornton, C., Cummins, S. J., & Cleary, P. W. (2013). +An investigation of the comparative behaviour of alternative contact force models +during inelastic collisions. Powder Technology, 233, 30-46. + +:line(WaltonPC) +[(Otis R. Walton)] Walton, O.R., Personal Communication diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index caef852ab0..19633a96c2 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -52,7 +52,7 @@ using namespace MathConst; enum {HOOKE, HERTZ, HERTZ_MATERIAL, DMT, JKR}; enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN, TANGENTIAL_MINDLIN_RESCALE}; enum {TWIST_NONE, TWIST_SDS, TWIST_MARSHALL}; enum {ROLL_NONE, ROLL_SDS}; @@ -77,6 +77,8 @@ PairGranular::PairGranular(LAMMPS *lmp) : Pair(lmp) maxrad_dynamic = NULL; maxrad_frozen = NULL; + history_transfer_factors = NULL; + dt = update->dt; // set comm size needed by this Pair if used with fix rigid @@ -131,7 +133,7 @@ void PairGranular::compute(int eflag, int vflag) int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,nx,ny,nz; double radi,radj,radsum,rsq,r,rinv; - double Reff, delta, dR, dR2; + double Reff, delta, dR, dR2, dist_to_contact; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double wr1,wr2,wr3; @@ -397,16 +399,27 @@ void PairGranular::compute(int eflag, int vflag) damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor; if (tangential_history){ - shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + - history[2]*history[2]); - + if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN){ + k_tangential *= a; + } + else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE){ + k_tangential *= a; + if (a < history[3]){ //On unloading, rescale the shear displacements + double factor = a/history[3]; + history[0] *= factor; + history[1] *= factor; + history[2] *= factor; + } + } // Rotate and update displacements. // See e.g. eq. 17 of Luding, Gran. Matter 2008, v10,p235 if (historyupdate) { rsht = history[0]*nx + history[1]*ny + history[2]*nz; if (fabs(rsht) < EPSILON) rsht = 0; if (rsht > 0){ - scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); + scalefac = shrmag/(shrmag - rsht); //if rsht == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! history[0] -= rsht*nx; history[1] -= rsht*ny; history[2] -= rsht*nz; @@ -419,6 +432,7 @@ void PairGranular::compute(int eflag, int vflag) history[0] += vtr1*dt; history[1] += vtr2*dt; history[2] += vtr3*dt; + if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) history[3] = a; } // tangential forces = history + tangential velocity damping @@ -430,6 +444,8 @@ void PairGranular::compute(int eflag, int vflag) Fscrit = tangential_coeffs[itype][jtype][2] * Fncrit; fs = sqrt(fs1*fs1 + fs2*fs2 + fs3*fs3); if (fs > Fscrit) { + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + + history[2]*history[2]); if (shrmag != 0.0) { history[0] = -1.0/k_tangential*(Fscrit*fs1/fs + damp_tangential*vtr1); history[1] = -1.0/k_tangential*(Fscrit*fs2/fs + damp_tangential*vtr2); @@ -469,16 +485,13 @@ void PairGranular::compute(int eflag, int vflag) int rhist1 = rhist0 + 1; int rhist2 = rhist1 + 1; - // Rolling displacement - rollmag = sqrt(history[rhist0]*history[rhist0] + - history[rhist1]*history[rhist1] + - history[rhist2]*history[rhist2]); - rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - if (historyupdate){ if (fabs(rolldotn) < EPSILON) rolldotn = 0; if (rolldotn > 0){ //Rotate into tangential plane + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); scalefac = rollmag/(rollmag - rolldotn); history[rhist0] -= rolldotn*nx; history[rhist1] -= rolldotn*ny; @@ -504,6 +517,9 @@ void PairGranular::compute(int eflag, int vflag) fr = sqrt(fr1*fr1 + fr2*fr2 + fr3*fr3); if (fr > Frcrit) { + rollmag = sqrt(history[rhist0]*history[rhist0] + + history[rhist1]*history[rhist1] + + history[rhist2]*history[rhist2]); if (rollmag != 0.0) { history[rhist0] = -1.0/k_roll*(Frcrit*fr1/fr + damp_roll*vrl1); history[rhist1] = -1.0/k_roll*(Frcrit*fr2/fr + damp_roll*vrl2); @@ -555,9 +571,10 @@ void PairGranular::compute(int eflag, int vflag) tor2 = nz*fs1 - nx*fs3; tor3 = nx*fs2 - ny*fs1; - torque[i][0] -= radi*tor1; - torque[i][1] -= radi*tor2; - torque[i][2] -= radi*tor3; + dist_to_contact = radi-0.5*delta; + torque[i][0] -= dist_to_contact*tor1; + torque[i][1] -= dist_to_contact*tor2; + torque[i][2] -= dist_to_contact*tor3; if (twist_model[itype][jtype] != TWIST_NONE){ tortwist1 = magtortwist * nx; @@ -584,9 +601,10 @@ void PairGranular::compute(int eflag, int vflag) f[j][1] -= fy; f[j][2] -= fz; - torque[j][0] -= radj*tor1; - torque[j][1] -= radj*tor2; - torque[j][2] -= radj*tor3; + dist_to_contact = radj-0.5*delta; + torque[j][0] -= dist_to_contact*tor1; + torque[j][1] -= dist_to_contact*tor2; + torque[j][2] -= dist_to_contact*tor3; if (twist_model[itype][jtype] != TWIST_NONE){ torque[j][0] -= tortwist1; @@ -762,9 +780,13 @@ void PairGranular::coeff(int narg, char **arg) tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } - else if (strcmp(arg[iarg+1], "linear_history") == 0){ + else if ((strcmp(arg[iarg+1], "linear_history") == 0) || + (strcmp(arg[iarg+1], "mindlin") == 0) || + (strcmp(arg[iarg+1], "mindlin_rescale") == 0)){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - tangential_model_one = TANGENTIAL_HISTORY; + if (strcmp(arg[iarg+1], "linear_history") == 0) tangential_model_one = TANGENTIAL_HISTORY; + else if (strcmp(arg[iarg+1], "mindlin") == 0) tangential_model_one = TANGENTIAL_MINDLIN; + else if (strcmp(arg[iarg+1], "mindlin_rescale") == 0) tangential_model_one = TANGENTIAL_MINDLIN_RESCALE; tangential_history = 1; tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat @@ -896,11 +918,11 @@ void PairGranular::init_style() error->all(FLERR,"Pair granular requires ghost atoms store velocity"); // Determine whether we need a granular neigh list, how large it needs to be - use_history = tangential_history || roll_history || twist_history; + use_history = normal_history || tangential_history || roll_history || twist_history; //For JKR, will need fix/neigh/history to keep track of touch arrays for (int i = 1; i <= atom->ntypes; i++) - for (int j = 1; j <= atom->ntypes; j++) + for (int j = i; j <= atom->ntypes; j++) if (normal_model[i][j] == JKR) use_history = 1; size_history = 3*tangential_history + 3*roll_history + twist_history; @@ -920,6 +942,19 @@ void PairGranular::init_style() else twist_history_index = 0; } } + for (int i = 1; i <= atom->ntypes; i++) + for (int j = i; j <= atom->ntypes; j++) + if (tangential_model[i][j] == TANGENTIAL_MINDLIN_RESCALE){ + size_history += 1; + roll_history_index += 1; + twist_history_index += 1; + nondefault_history_transfer = 1; + history_transfer_factors = new int[size_history]; + for (int ii = 0; ii < size_history; ++ii) + history_transfer_factors[ii] = -1; + history_transfer_factors[3] = 1; + break; + } int irequest = neighbor->request(this,instance_me); neighbor->requests[irequest]->size = 1; @@ -1612,3 +1647,12 @@ double PairGranular::pulloff_distance(double radi, double radj, int itype, int j return a*a/Reff - 2*sqrt(M_PI*coh*a/E); } +/* ---------------------------------------------------------------------- + Transfer history during fix/neigh/history exchange + Only needed if any history entries i-j are not just negative of j-i entries +------------------------------------------------------------------------- */ +void PairGranular::transfer_history(double* source, double* target){ + for (int i = 0; i < size_history; i++) + target[i] = history_transfer_factors[i]*source[i]; +} + diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index 7bce3831f1..ebddc17ade 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -61,9 +61,11 @@ public: int nmax; // allocated size of mass_rigid void allocate(); + void transfer_history(double*, double*); private: int size_history; + int *history_transfer_factors; //Model choices int **normal_model, **damping_model; -- GitLab From cc2b5fbb80d1087fbb4fe272f48cc08ef3c24967 Mon Sep 17 00:00:00 2001 From: julient31 Date: Mon, 11 Mar 2019 17:37:44 -0600 Subject: [PATCH 0219/1243] Commit JT 031119 - add min_post_force in precession --- examples/SPIN/gneb_bfo/in.gneb.iron | 1 - examples/SPIN/gneb_bfo/in.spinmin.bfo | 30 ++---------------- examples/SPIN/gneb_bfo/in.spinmin.iron | 21 ++---------- src/SPIN/fix_precession_spin.cpp | 8 +++++ src/SPIN/fix_precession_spin.h | 5 +-- src/SPIN/min_spinmin.cpp | 44 ++------------------------ src/SPIN/min_spinmin.h | 5 ++- 7 files changed, 19 insertions(+), 95 deletions(-) diff --git a/examples/SPIN/gneb_bfo/in.gneb.iron b/examples/SPIN/gneb_bfo/in.gneb.iron index 860db24a61..80ab698c16 100644 --- a/examples/SPIN/gneb_bfo/in.gneb.iron +++ b/examples/SPIN/gneb_bfo/in.gneb.iron @@ -1,5 +1,4 @@ # bcc iron in a 3d periodic box -print "Test 1" units metal dimension 3 diff --git a/examples/SPIN/gneb_bfo/in.spinmin.bfo b/examples/SPIN/gneb_bfo/in.spinmin.bfo index c048ac32c6..15a4d6e0f9 100644 --- a/examples/SPIN/gneb_bfo/in.spinmin.bfo +++ b/examples/SPIN/gneb_bfo/in.spinmin.bfo @@ -13,8 +13,6 @@ region box block 0.0 68.0 0.0 68.0 0.0 1.0 create_box 1 box create_atoms 1 box -#read_data ../examples/SPIN/gneb_bfo/initial.iron_spin - # setting mass, mag. moments, and interactions for bcc iron mass 1 1.0 @@ -34,20 +32,8 @@ neigh_modify every 10 check yes delay 20 fix 1 all precession/spin anisotropy 0.0000033 0.0 0.0 1.0 fix 2 all langevin/spin 0.1 0.0 21 fix 3 all nve/spin lattice no -#fix 3 all neb/spin 1.0 -#fix 4 all nve/spin lattice no -#parallel ideal timestep 0.0001 -#thermo 10 - -#compute outsp all property/atom spx spy spz sp fmx fmy fmz -#dump 1 all custom 100 dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] - -#min_style spinmin -#minimize 1.0e-6 1.0e-6 1000 10000 -#minimize 1.0e-6 1.0e-6 10000 10000 -#minimize 1.0e-7 1.0e-7 10000 10000 compute out_mag all spin compute out_pe all pe @@ -66,18 +52,6 @@ thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 200 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] -#timestep 0.0001 -#run 1 min_style spinmin -#minimize 1.0e-6 1.0e-6 1000 10000 -#minimize 1.0e-6 1.0e-6 10000 10000 -minimize 1.0e-8 1.0e-8 10000 1000 - -#write_dump all custom dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] - -#compute outsp all property/atom spx spy spz sp fmx fmy fmz -#dump 1 all custom 1 dump_bfo.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] -#thermo 1 - -#neb/spin 0.0 0.1 10 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin -#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin +minimize 1.0e-6 1.0e-6 10000 10000 +#minimize 1.0e-8 1.0e-8 10000 1000 diff --git a/examples/SPIN/gneb_bfo/in.spinmin.iron b/examples/SPIN/gneb_bfo/in.spinmin.iron index 4439960390..67d8095c06 100644 --- a/examples/SPIN/gneb_bfo/in.spinmin.iron +++ b/examples/SPIN/gneb_bfo/in.spinmin.iron @@ -13,8 +13,6 @@ region box block 0.0 4.0 0.0 4.0 0.0 1.0 create_box 1 box create_atoms 1 box -#read_data ../examples/SPIN/gneb_bfo/initial.iron_spin - # setting mass, mag. moments, and interactions for bcc iron mass 1 55.845 @@ -31,16 +29,9 @@ neigh_modify every 10 check yes delay 20 fix 1 all precession/spin anisotropy 0.001 0.0 0.0 1.0 fix 2 all langevin/spin 0.1 0.0 21 fix 3 all nve/spin lattice no -#fix 3 all neb/spin 1.0 -#fix 4 all nve/spin lattice no -#parallel ideal timestep 0.0001 -#min_style spinmin -#minimize 1.0e-6 1.0e-6 1000 10000 -#minimize 1.0e-8 1.0e-6 1000 10000 - compute out_mag all spin compute out_pe all pe compute out_ke all ke @@ -58,14 +49,6 @@ thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 1 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] -#timestep 0.0001 -#run 1 - min_style spinmin -#minimize 1.0e-6 1.0e-6 1000 10000 -minimize 1.0e-8 1.0e-6 1000 10000 - - - -#neb/spin 0.0 0.1 10 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin -#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin +minimize 1.0e-6 1.0e-6 1000 10000 +#minimize 1.0e-8 1.0e-6 1000 10000 diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index 65d5e9120e..08e4fd5a63 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -115,6 +115,7 @@ int FixPrecessionSpin::setmask() { int mask = 0; mask |= POST_FORCE; + mask |= MIN_POST_FORCE; mask |= THERMO_ENERGY; mask |= POST_FORCE_RESPA; return mask; @@ -283,3 +284,10 @@ double FixPrecessionSpin::compute_scalar() } return emag_all; } + +/* ---------------------------------------------------------------------- */ + +void FixPrecessionSpin::min_post_force(int vflag) +{ + post_force(vflag); +} diff --git a/src/SPIN/fix_precession_spin.h b/src/SPIN/fix_precession_spin.h index 53ae4ba124..2fe6b5a673 100644 --- a/src/SPIN/fix_precession_spin.h +++ b/src/SPIN/fix_precession_spin.h @@ -33,8 +33,9 @@ class FixPrecessionSpin : public Fix { int setmask(); void init(); void setup(int); - virtual void post_force(int); - virtual void post_force_respa(int, int, int); + void post_force(int); + void post_force_respa(int, int, int); + void min_post_force(int); double compute_scalar(); int zeeman_flag, aniso_flag; diff --git a/src/SPIN/min_spinmin.cpp b/src/SPIN/min_spinmin.cpp index 4b362fda87..2e03086bf0 100644 --- a/src/SPIN/min_spinmin.cpp +++ b/src/SPIN/min_spinmin.cpp @@ -88,7 +88,7 @@ void MinSpinMin::reset_vectors() } /* ---------------------------------------------------------------------- - minimization via QuickMin damped dynamics + minimization via damped spin dynamics ------------------------------------------------------------------------- */ int MinSpinMin::iterate(int maxiter) @@ -98,16 +98,6 @@ int MinSpinMin::iterate(int maxiter) //double dtvone,dtv,dtf,dtfm; int flag,flagall; - //alpha_final = 0.0; - - // search for and allocate neb_spin fix - - //int ineb; - //for (ineb = 0; ineb < modify->nfix; ineb++) - // if (strcmp(modify->fix[ineb]->style,"neb/spin") == 0) break; - //if (ineb == modify->nfix) error->all(FLERR,"spinmin requires use of fix neb/spin"); - //fneb = (FixNEB_spin *) modify->fix[ineb]; - for (int iter = 0; iter < maxiter; iter++) { if (timer->check_timeout(niter)) @@ -118,12 +108,10 @@ int MinSpinMin::iterate(int maxiter) // optimize timestep accross processes / replicas - //dts = fneb->evaluate_dt(); dts = evaluate_dt(); // apply damped precessional dynamics to the spins - //fneb->advance_spins(dts); advance_spins(dts); @@ -351,8 +339,6 @@ double MinSpinMin::evaluate_dt() void MinSpinMin::advance_spins(double dts) { - //int j=0; - //int *sametag = atom->sametag; int nlocal = atom->nlocal; int *mask = atom->mask; double **sp = atom->sp; @@ -360,18 +346,14 @@ void MinSpinMin::advance_spins(double dts) double tdampx,tdampy,tdampz; double msq,scale,fm2,energy,dts2; double alpha; - //double spi[3],fmi[3]; double cp[3],g[3]; - //cp[0] = cp[1] = cp[2] = 0.0; - //g[0] = g[1] = g[2] = 0.0; dts2 = dts*dts; // fictitious Gilbert damping of 1 + alpha = 1.0; - //printf("test inside spinmin, dts %g \n",dts); - //printf("test inside spinmin, fmi i=%d, %g %g %g \n",1,fm[1][0],fm[1][1],fm[1][2]); // loop on all spins on proc. @@ -379,14 +361,6 @@ void MinSpinMin::advance_spins(double dts) // for (int i = 0; i < nlocal; i++) // if (mask[i] & groupbit) { for (int i = 0; i < nlocal; i++) { - - //spi[0] = sp[i][0]; - //spi[1] = sp[i][1]; - //spi[2] = sp[i][2]; - // - //fmi[0] = fm[i][0]; - //fmi[1] = fm[i][1]; - //fmi[2] = fm[i][2]; // calc. damping torque @@ -394,8 +368,6 @@ void MinSpinMin::advance_spins(double dts) tdampy = -alpha*(fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); tdampz = -alpha*(fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); - //printf("for %d, test tdamp: %g %g %g \n",i,tdampx,tdampy,tdampz); - // apply advance algorithm (geometric, norm preserving) fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); @@ -405,15 +377,10 @@ void MinSpinMin::advance_spins(double dts) cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; - //printf("for %d, test cp: %g %g %g \n",i,cp[0],cp[1],cp[2]); - g[0] = sp[i][0]+cp[0]*dts; g[1] = sp[i][1]+cp[1]*dts; g[2] = sp[i][2]+cp[2]*dts; - //g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; - //g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; - //g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; g[0] += (tdampx*energy-0.5*sp[i][0]*fm2)*0.5*dts2; g[1] += (tdampy*energy-0.5*sp[i][1]*fm2)*0.5*dts2; g[2] += (tdampz*energy-0.5*sp[i][2]*fm2)*0.5*dts2; @@ -421,10 +388,6 @@ void MinSpinMin::advance_spins(double dts) g[0] /= (1+0.25*fm2*dts2); g[1] /= (1+0.25*fm2*dts2); g[2] /= (1+0.25*fm2*dts2); - - //printf("test inside spinmin, spi i=%d, %g %g %g \n",i,sp[i][0],sp[i][1],sp[i][2]); - //printf("test inside spinmin, fmi i=%d, %g %g %g \n",i,fm[i][0],fm[i][1],fm[i][2]); - //printf("for %d, test g: %g %g %g \n",i,g[0],g[1],g[2]); sp[i][0] = g[0]; sp[i][1] = g[1]; @@ -455,8 +418,5 @@ void MinSpinMin::advance_spins(double dts) // } - //printf("test inside spinmin, dts = %g \n",dts); - //printf("test inside spinmin, fmi i=%d, %g %g %g \n",1,fm[1][0],fm[1][1],fm[1][2]); - //printf("test inside spinmin, spi i=%d, %g %g %g \n",1,sp[1][0],sp[1][1],sp[1][2]); } diff --git a/src/SPIN/min_spinmin.h b/src/SPIN/min_spinmin.h index fe2cf7c51d..943b2d2749 100644 --- a/src/SPIN/min_spinmin.h +++ b/src/SPIN/min_spinmin.h @@ -39,14 +39,13 @@ class MinSpinMin : public Min { private: - // spin timestep + // global and spin timesteps + double dt; double dts; double *spvec; // variables for atomic dof, as 1d vector double *fmvec; // variables for atomic dof, as 1d vector - - double dt; bigint last_negative; }; -- GitLab From 3a4bb6f9802b33d29fa510af7e90f3f0907a63cd Mon Sep 17 00:00:00 2001 From: mkanski Date: Tue, 12 Mar 2019 20:19:56 +0100 Subject: [PATCH 0220/1243] All errors and warning are now printed through LAMMPS --- src/USER-REAXC/pair_reaxc.cpp | 28 +- src/USER-REAXC/reaxc_allocate.cpp | 326 ++++++++++++------------ src/USER-REAXC/reaxc_allocate.h | 8 +- src/USER-REAXC/reaxc_bond_orders.cpp | 3 +- src/USER-REAXC/reaxc_bond_orders.h | 2 +- src/USER-REAXC/reaxc_bonds.cpp | 2 +- src/USER-REAXC/reaxc_bonds.h | 2 +- src/USER-REAXC/reaxc_control.cpp | 12 +- src/USER-REAXC/reaxc_control.h | 5 +- src/USER-REAXC/reaxc_ffield.cpp | 149 +++++------ src/USER-REAXC/reaxc_ffield.h | 2 +- src/USER-REAXC/reaxc_forces.cpp | 23 +- src/USER-REAXC/reaxc_hydrogen_bonds.cpp | 2 +- src/USER-REAXC/reaxc_hydrogen_bonds.h | 2 +- src/USER-REAXC/reaxc_init_md.cpp | 94 ++++--- src/USER-REAXC/reaxc_io_tools.cpp | 8 +- src/USER-REAXC/reaxc_io_tools.h | 4 +- src/USER-REAXC/reaxc_list.cpp | 68 ++--- src/USER-REAXC/reaxc_list.h | 4 +- src/USER-REAXC/reaxc_lookup.cpp | 102 ++++---- src/USER-REAXC/reaxc_lookup.h | 8 +- src/USER-REAXC/reaxc_multi_body.cpp | 2 +- src/USER-REAXC/reaxc_multi_body.h | 2 +- src/USER-REAXC/reaxc_reset_tools.cpp | 16 +- src/USER-REAXC/reaxc_tool_box.cpp | 44 ++-- src/USER-REAXC/reaxc_tool_box.h | 6 +- src/USER-REAXC/reaxc_torsion_angles.cpp | 3 +- src/USER-REAXC/reaxc_torsion_angles.h | 3 +- src/USER-REAXC/reaxc_traj.cpp | 56 ++-- src/USER-REAXC/reaxc_traj.h | 4 +- src/USER-REAXC/reaxc_types.h | 7 +- src/USER-REAXC/reaxc_valence_angles.cpp | 9 +- src/USER-REAXC/reaxc_valence_angles.h | 2 +- 33 files changed, 506 insertions(+), 502 deletions(-) diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index 0f4b3a5b3d..24612a3a40 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -137,15 +137,15 @@ PairReaxC::~PairReaxC() // deallocate reax data-structures - if (control->tabulate ) Deallocate_Lookup_Tables( system); + if (control->tabulate ) Deallocate_Lookup_Tables( lmp, system); - if (control->hbond_cut > 0 ) Delete_List( lists+HBONDS, world); - Delete_List( lists+BONDS, world ); - Delete_List( lists+THREE_BODIES, world ); - Delete_List( lists+FAR_NBRS, world ); + if (control->hbond_cut > 0 ) Delete_List( lmp, lists+HBONDS, world); + Delete_List( lmp, lists+BONDS, world ); + Delete_List( lmp, lists+THREE_BODIES, world ); + Delete_List( lmp, lists+FAR_NBRS, world ); - DeAllocate_Workspace( control, workspace ); - DeAllocate_System( system ); + DeAllocate_Workspace( lmp, control, workspace ); + DeAllocate_System( lmp, system ); } memory->destroy( system ); @@ -223,7 +223,7 @@ void PairReaxC::settings(int narg, char **arg) out_control->atom_info = 0; out_control->bond_info = 0; out_control->angle_info = 0; - } else Read_Control_File(arg[0], control, out_control); + } else Read_Control_File(lmp, arg[0], control, out_control); // default values @@ -298,7 +298,7 @@ void PairReaxC::coeff( int nargs, char **args ) FILE *fp; fp = force->open_potential(file); if (fp != NULL) - Read_Force_Field(fp, &(system->reax_param), control); + Read_Force_Field(lmp, fp, &(system->reax_param), control); else { char str[128]; snprintf(str,128,"Cannot open ReaxFF potential file %s",file); @@ -394,7 +394,7 @@ void PairReaxC::init_style( ) "increased neighbor list skin."); for( int i = 0; i < LIST_N; ++i ) - if (lists[i].allacated != 1) + if (lists[i].allocated != 1) lists[i].allocated = 0; if (fix_reax == NULL) { @@ -437,13 +437,13 @@ void PairReaxC::setup( ) // initialize my data structures - PreAllocate_Space( system, control, workspace, world ); + PreAllocate_Space( lmp, system, control, workspace, world ); write_reax_atoms(); int num_nbrs = estimate_reax_lists(); - if(!Make_List(system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, + if(!Make_List(lmp, system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, lists+FAR_NBRS, world)) - error->all(FLERR,"Pair reax/c problem in far neighbor list"); + error->one(FLERR,"Pair reax/c problem in far neighbor list"); write_reax_lists(); Initialize( lmp, system, control, data, workspace, &lists, out_control, @@ -582,7 +582,7 @@ void PairReaxC::compute(int eflag, int vflag) data->step = update->ntimestep; - Output_Results( system, control, data, &lists, out_control, mpi_data ); + Output_Results( lmp, system, control, data, &lists, out_control, mpi_data ); // populate tmpid and tmpbo arrays for fix reax/c/species int i, j; diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp index ebf0684389..2f970399f2 100644 --- a/src/USER-REAXC/reaxc_allocate.cpp +++ b/src/USER-REAXC/reaxc_allocate.cpp @@ -43,7 +43,7 @@ using namespace LAMMPS_NS; important: we cannot know the exact number of atoms that will fall into a process's box throughout the whole simulation. therefore we need to make upper bound estimates for various data structures */ -int PreAllocate_Space( reax_system *system, control_params * /*control*/, +int PreAllocate_Space( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * /*control*/, storage * workspace, MPI_Comm comm ) { int mincap = system->mincap; @@ -55,7 +55,7 @@ int PreAllocate_Space( reax_system *system, control_params * /*control*/, system->total_cap = MAX( (int)(system->N * safezone), mincap ); system->my_atoms = (reax_atom*) - scalloc( system->total_cap, sizeof(reax_atom), "my_atoms", comm ); + scalloc(lmp, system->total_cap, sizeof(reax_atom), "my_atoms", comm ); // Nullify some arrays only used in omp styles // Should be safe to do here since called in pair->setup(); @@ -84,45 +84,45 @@ int Allocate_System( reax_system *system, int /*local_cap*/, int total_cap, } -void DeAllocate_System( reax_system *system ) +void DeAllocate_System( LAMMPS_NS::LAMMPS *lmp, reax_system *system ) { int i, j, k; int ntypes; reax_interaction *ff_params; // dealloocate the atom list - sfree( system->my_atoms, "system->my_atoms" ); + sfree(lmp, system->my_atoms, "system->my_atoms" ); // deallocate the ffield parameters storage ff_params = &(system->reax_param); ntypes = ff_params->num_atom_types; - sfree( ff_params->gp.l, "ff:globals" ); + sfree(lmp, ff_params->gp.l, "ff:globals" ); for( i = 0; i < ntypes; ++i ) { for( j = 0; j < ntypes; ++j ) { for( k = 0; k < ntypes; ++k ) { - sfree( ff_params->fbp[i][j][k], "ff:fbp[i,j,k]" ); + sfree(lmp, ff_params->fbp[i][j][k], "ff:fbp[i,j,k]" ); } - sfree( ff_params->fbp[i][j], "ff:fbp[i,j]" ); - sfree( ff_params->thbp[i][j], "ff:thbp[i,j]" ); - sfree( ff_params->hbp[i][j], "ff:hbp[i,j]" ); + sfree(lmp, ff_params->fbp[i][j], "ff:fbp[i,j]" ); + sfree(lmp, ff_params->thbp[i][j], "ff:thbp[i,j]" ); + sfree(lmp, ff_params->hbp[i][j], "ff:hbp[i,j]" ); } - sfree( ff_params->fbp[i], "ff:fbp[i]" ); - sfree( ff_params->thbp[i], "ff:thbp[i]" ); - sfree( ff_params->hbp[i], "ff:hbp[i]" ); - sfree( ff_params->tbp[i], "ff:tbp[i]" ); + sfree(lmp, ff_params->fbp[i], "ff:fbp[i]" ); + sfree(lmp, ff_params->thbp[i], "ff:thbp[i]" ); + sfree(lmp, ff_params->hbp[i], "ff:hbp[i]" ); + sfree(lmp, ff_params->tbp[i], "ff:tbp[i]" ); } - sfree( ff_params->fbp, "ff:fbp" ); - sfree( ff_params->thbp, "ff:thbp" ); - sfree( ff_params->hbp, "ff:hbp" ); - sfree( ff_params->tbp, "ff:tbp" ); - sfree( ff_params->sbp, "ff:sbp" ); + sfree(lmp, ff_params->fbp, "ff:fbp" ); + sfree(lmp, ff_params->thbp, "ff:thbp" ); + sfree(lmp, ff_params->hbp, "ff:hbp" ); + sfree(lmp, ff_params->tbp, "ff:tbp" ); + sfree(lmp, ff_params->sbp, "ff:sbp" ); } /************* workspace *************/ -void DeAllocate_Workspace( control_params * /*control*/, storage *workspace ) +void DeAllocate_Workspace( LAMMPS_NS::LAMMPS* lmp, control_params * /*control*/, storage *workspace ) { int i; @@ -133,84 +133,84 @@ void DeAllocate_Workspace( control_params * /*control*/, storage *workspace ) /* communication storage */ for( i = 0; i < MAX_NBRS; ++i ) { - sfree( workspace->tmp_dbl[i], "tmp_dbl[i]" ); - sfree( workspace->tmp_rvec[i], "tmp_rvec[i]" ); - sfree( workspace->tmp_rvec2[i], "tmp_rvec2[i]" ); + sfree(lmp, workspace->tmp_dbl[i], "tmp_dbl[i]" ); + sfree(lmp, workspace->tmp_rvec[i], "tmp_rvec[i]" ); + sfree(lmp, workspace->tmp_rvec2[i], "tmp_rvec2[i]" ); } /* bond order storage */ - sfree( workspace->within_bond_box, "skin" ); - sfree( workspace->total_bond_order, "total_bo" ); - sfree( workspace->Deltap, "Deltap" ); - sfree( workspace->Deltap_boc, "Deltap_boc" ); - sfree( workspace->dDeltap_self, "dDeltap_self" ); - sfree( workspace->Delta, "Delta" ); - sfree( workspace->Delta_lp, "Delta_lp" ); - sfree( workspace->Delta_lp_temp, "Delta_lp_temp" ); - sfree( workspace->dDelta_lp, "dDelta_lp" ); - sfree( workspace->dDelta_lp_temp, "dDelta_lp_temp" ); - sfree( workspace->Delta_e, "Delta_e" ); - sfree( workspace->Delta_boc, "Delta_boc" ); - sfree( workspace->Delta_val, "Delta_val" ); - sfree( workspace->nlp, "nlp" ); - sfree( workspace->nlp_temp, "nlp_temp" ); - sfree( workspace->Clp, "Clp" ); - sfree( workspace->vlpex, "vlpex" ); - sfree( workspace->bond_mark, "bond_mark" ); - sfree( workspace->done_after, "done_after" ); + sfree(lmp, workspace->within_bond_box, "skin" ); + sfree(lmp, workspace->total_bond_order, "total_bo" ); + sfree(lmp, workspace->Deltap, "Deltap" ); + sfree(lmp, workspace->Deltap_boc, "Deltap_boc" ); + sfree(lmp, workspace->dDeltap_self, "dDeltap_self" ); + sfree(lmp, workspace->Delta, "Delta" ); + sfree(lmp, workspace->Delta_lp, "Delta_lp" ); + sfree(lmp, workspace->Delta_lp_temp, "Delta_lp_temp" ); + sfree(lmp, workspace->dDelta_lp, "dDelta_lp" ); + sfree(lmp, workspace->dDelta_lp_temp, "dDelta_lp_temp" ); + sfree(lmp, workspace->Delta_e, "Delta_e" ); + sfree(lmp, workspace->Delta_boc, "Delta_boc" ); + sfree(lmp, workspace->Delta_val, "Delta_val" ); + sfree(lmp, workspace->nlp, "nlp" ); + sfree(lmp, workspace->nlp_temp, "nlp_temp" ); + sfree(lmp, workspace->Clp, "Clp" ); + sfree(lmp, workspace->vlpex, "vlpex" ); + sfree(lmp, workspace->bond_mark, "bond_mark" ); + sfree(lmp, workspace->done_after, "done_after" ); /* QEq storage */ - sfree( workspace->Hdia_inv, "Hdia_inv" ); - sfree( workspace->b_s, "b_s" ); - sfree( workspace->b_t, "b_t" ); - sfree( workspace->b_prc, "b_prc" ); - sfree( workspace->b_prm, "b_prm" ); - sfree( workspace->s, "s" ); - sfree( workspace->t, "t" ); - sfree( workspace->droptol, "droptol" ); - sfree( workspace->b, "b" ); - sfree( workspace->x, "x" ); + sfree(lmp, workspace->Hdia_inv, "Hdia_inv" ); + sfree(lmp, workspace->b_s, "b_s" ); + sfree(lmp, workspace->b_t, "b_t" ); + sfree(lmp, workspace->b_prc, "b_prc" ); + sfree(lmp, workspace->b_prm, "b_prm" ); + sfree(lmp, workspace->s, "s" ); + sfree(lmp, workspace->t, "t" ); + sfree(lmp, workspace->droptol, "droptol" ); + sfree(lmp, workspace->b, "b" ); + sfree(lmp, workspace->x, "x" ); /* GMRES storage */ for( i = 0; i < RESTART+1; ++i ) { - sfree( workspace->h[i], "h[i]" ); - sfree( workspace->v[i], "v[i]" ); + sfree(lmp, workspace->h[i], "h[i]" ); + sfree(lmp, workspace->v[i], "v[i]" ); } - sfree( workspace->h, "h" ); - sfree( workspace->v, "v" ); - sfree( workspace->y, "y" ); - sfree( workspace->z, "z" ); - sfree( workspace->g, "g" ); - sfree( workspace->hs, "hs" ); - sfree( workspace->hc, "hc" ); + sfree(lmp, workspace->h, "h" ); + sfree(lmp, workspace->v, "v" ); + sfree(lmp, workspace->y, "y" ); + sfree(lmp, workspace->z, "z" ); + sfree(lmp, workspace->g, "g" ); + sfree(lmp, workspace->hs, "hs" ); + sfree(lmp, workspace->hc, "hc" ); /* CG storage */ - sfree( workspace->r, "r" ); - sfree( workspace->d, "d" ); - sfree( workspace->q, "q" ); - sfree( workspace->p, "p" ); - sfree( workspace->r2, "r2" ); - sfree( workspace->d2, "d2" ); - sfree( workspace->q2, "q2" ); - sfree( workspace->p2, "p2" ); + sfree(lmp, workspace->r, "r" ); + sfree(lmp, workspace->d, "d" ); + sfree(lmp, workspace->q, "q" ); + sfree(lmp, workspace->p, "p" ); + sfree(lmp, workspace->r2, "r2" ); + sfree(lmp, workspace->d2, "d2" ); + sfree(lmp, workspace->q2, "q2" ); + sfree(lmp, workspace->p2, "p2" ); /* integrator storage */ - sfree( workspace->v_const, "v_const" ); + sfree(lmp, workspace->v_const, "v_const" ); /* force related storage */ - sfree( workspace->f, "f" ); - sfree( workspace->CdDelta, "CdDelta" ); + sfree(lmp, workspace->f, "f" ); + sfree(lmp, workspace->CdDelta, "CdDelta" ); /* reductions */ #ifdef LMP_USER_OMP - if (workspace->CdDeltaReduction) sfree( workspace->CdDeltaReduction, "cddelta_reduce" ); - if (workspace->forceReduction) sfree( workspace->forceReduction, "f_reduce" ); - if (workspace->valence_angle_atom_myoffset) sfree( workspace->valence_angle_atom_myoffset, "valence_angle_atom_myoffset"); - if (workspace->my_ext_pressReduction) sfree( workspace->my_ext_pressReduction, "ext_press_reduce"); + if (workspace->CdDeltaReduction) sfree(lmp, workspace->CdDeltaReduction, "cddelta_reduce" ); + if (workspace->forceReduction) sfree(lmp, workspace->forceReduction, "f_reduce" ); + if (workspace->valence_angle_atom_myoffset) sfree(lmp, workspace->valence_angle_atom_myoffset, "valence_angle_atom_myoffset"); + if (workspace->my_ext_pressReduction) sfree(lmp, workspace->my_ext_pressReduction, "ext_press_reduce"); #endif } -int Allocate_Workspace( reax_system * /*system*/, control_params * control, +int Allocate_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system * /*system*/, control_params * control, storage *workspace, int local_cap, int total_cap, MPI_Comm comm, char * /*msg*/ ) { @@ -224,94 +224,94 @@ int Allocate_Workspace( reax_system * /*system*/, control_params * control, /* communication storage */ for( i = 0; i < MAX_NBRS; ++i ) { workspace->tmp_dbl[i] = (double*) - scalloc( total_cap, sizeof(double), "tmp_dbl", comm ); + scalloc(lmp, total_cap, sizeof(double), "tmp_dbl", comm ); workspace->tmp_rvec[i] = (rvec*) - scalloc( total_cap, sizeof(rvec), "tmp_rvec", comm ); + scalloc(lmp, total_cap, sizeof(rvec), "tmp_rvec", comm ); workspace->tmp_rvec2[i] = (rvec2*) - scalloc( total_cap, sizeof(rvec2), "tmp_rvec2", comm ); + scalloc(lmp, total_cap, sizeof(rvec2), "tmp_rvec2", comm ); } /* bond order related storage */ workspace->within_bond_box = (int*) - scalloc( total_cap, sizeof(int), "skin", comm ); - workspace->total_bond_order = (double*) smalloc( total_real, "total_bo", comm ); - workspace->Deltap = (double*) smalloc( total_real, "Deltap", comm ); - workspace->Deltap_boc = (double*) smalloc( total_real, "Deltap_boc", comm ); - workspace->dDeltap_self = (rvec*) smalloc( total_rvec, "dDeltap_self", comm ); - workspace->Delta = (double*) smalloc( total_real, "Delta", comm ); - workspace->Delta_lp = (double*) smalloc( total_real, "Delta_lp", comm ); + scalloc(lmp, total_cap, sizeof(int), "skin", comm ); + workspace->total_bond_order = (double*) smalloc(lmp, total_real, "total_bo", comm ); + workspace->Deltap = (double*) smalloc(lmp, total_real, "Deltap", comm ); + workspace->Deltap_boc = (double*) smalloc(lmp, total_real, "Deltap_boc", comm ); + workspace->dDeltap_self = (rvec*) smalloc(lmp, total_rvec, "dDeltap_self", comm ); + workspace->Delta = (double*) smalloc(lmp, total_real, "Delta", comm ); + workspace->Delta_lp = (double*) smalloc(lmp, total_real, "Delta_lp", comm ); workspace->Delta_lp_temp = (double*) - smalloc( total_real, "Delta_lp_temp", comm ); - workspace->dDelta_lp = (double*) smalloc( total_real, "dDelta_lp", comm ); + smalloc(lmp, total_real, "Delta_lp_temp", comm ); + workspace->dDelta_lp = (double*) smalloc(lmp, total_real, "dDelta_lp", comm ); workspace->dDelta_lp_temp = (double*) - smalloc( total_real, "dDelta_lp_temp", comm ); - workspace->Delta_e = (double*) smalloc( total_real, "Delta_e", comm ); - workspace->Delta_boc = (double*) smalloc( total_real, "Delta_boc", comm ); - workspace->Delta_val = (double*) smalloc( total_real, "Delta_val", comm ); - workspace->nlp = (double*) smalloc( total_real, "nlp", comm ); - workspace->nlp_temp = (double*) smalloc( total_real, "nlp_temp", comm ); - workspace->Clp = (double*) smalloc( total_real, "Clp", comm ); - workspace->vlpex = (double*) smalloc( total_real, "vlpex", comm ); + smalloc(lmp, total_real, "dDelta_lp_temp", comm ); + workspace->Delta_e = (double*) smalloc(lmp, total_real, "Delta_e", comm ); + workspace->Delta_boc = (double*) smalloc(lmp, total_real, "Delta_boc", comm ); + workspace->Delta_val = (double*) smalloc(lmp, total_real, "Delta_val", comm ); + workspace->nlp = (double*) smalloc(lmp, total_real, "nlp", comm ); + workspace->nlp_temp = (double*) smalloc(lmp, total_real, "nlp_temp", comm ); + workspace->Clp = (double*) smalloc(lmp, total_real, "Clp", comm ); + workspace->vlpex = (double*) smalloc(lmp, total_real, "vlpex", comm ); workspace->bond_mark = (int*) - scalloc( total_cap, sizeof(int), "bond_mark", comm ); + scalloc(lmp, total_cap, sizeof(int), "bond_mark", comm ); workspace->done_after = (int*) - scalloc( total_cap, sizeof(int), "done_after", comm ); + scalloc(lmp, total_cap, sizeof(int), "done_after", comm ); /* QEq storage */ workspace->Hdia_inv = (double*) - scalloc( total_cap, sizeof(double), "Hdia_inv", comm ); - workspace->b_s = (double*) scalloc( total_cap, sizeof(double), "b_s", comm ); - workspace->b_t = (double*) scalloc( total_cap, sizeof(double), "b_t", comm ); - workspace->b_prc = (double*) scalloc( total_cap, sizeof(double), "b_prc", comm ); - workspace->b_prm = (double*) scalloc( total_cap, sizeof(double), "b_prm", comm ); - workspace->s = (double*) scalloc( total_cap, sizeof(double), "s", comm ); - workspace->t = (double*) scalloc( total_cap, sizeof(double), "t", comm ); + scalloc(lmp, total_cap, sizeof(double), "Hdia_inv", comm ); + workspace->b_s = (double*) scalloc(lmp, total_cap, sizeof(double), "b_s", comm ); + workspace->b_t = (double*) scalloc(lmp, total_cap, sizeof(double), "b_t", comm ); + workspace->b_prc = (double*) scalloc(lmp, total_cap, sizeof(double), "b_prc", comm ); + workspace->b_prm = (double*) scalloc(lmp, total_cap, sizeof(double), "b_prm", comm ); + workspace->s = (double*) scalloc(lmp, total_cap, sizeof(double), "s", comm ); + workspace->t = (double*) scalloc(lmp, total_cap, sizeof(double), "t", comm ); workspace->droptol = (double*) - scalloc( total_cap, sizeof(double), "droptol", comm ); - workspace->b = (rvec2*) scalloc( total_cap, sizeof(rvec2), "b", comm ); - workspace->x = (rvec2*) scalloc( total_cap, sizeof(rvec2), "x", comm ); + scalloc(lmp, total_cap, sizeof(double), "droptol", comm ); + workspace->b = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "b", comm ); + workspace->x = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "x", comm ); /* GMRES storage */ - workspace->y = (double*) scalloc( RESTART+1, sizeof(double), "y", comm ); - workspace->z = (double*) scalloc( RESTART+1, sizeof(double), "z", comm ); - workspace->g = (double*) scalloc( RESTART+1, sizeof(double), "g", comm ); - workspace->h = (double**) scalloc( RESTART+1, sizeof(double*), "h", comm ); - workspace->hs = (double*) scalloc( RESTART+1, sizeof(double), "hs", comm ); - workspace->hc = (double*) scalloc( RESTART+1, sizeof(double), "hc", comm ); - workspace->v = (double**) scalloc( RESTART+1, sizeof(double*), "v", comm ); + workspace->y = (double*) scalloc(lmp, RESTART+1, sizeof(double), "y", comm ); + workspace->z = (double*) scalloc(lmp, RESTART+1, sizeof(double), "z", comm ); + workspace->g = (double*) scalloc(lmp, RESTART+1, sizeof(double), "g", comm ); + workspace->h = (double**) scalloc(lmp, RESTART+1, sizeof(double*), "h", comm ); + workspace->hs = (double*) scalloc(lmp, RESTART+1, sizeof(double), "hs", comm ); + workspace->hc = (double*) scalloc(lmp, RESTART+1, sizeof(double), "hc", comm ); + workspace->v = (double**) scalloc(lmp, RESTART+1, sizeof(double*), "v", comm ); for( i = 0; i < RESTART+1; ++i ) { - workspace->h[i] = (double*) scalloc( RESTART+1, sizeof(double), "h[i]", comm ); - workspace->v[i] = (double*) scalloc( total_cap, sizeof(double), "v[i]", comm ); + workspace->h[i] = (double*) scalloc(lmp, RESTART+1, sizeof(double), "h[i]", comm ); + workspace->v[i] = (double*) scalloc(lmp, total_cap, sizeof(double), "v[i]", comm ); } /* CG storage */ - workspace->r = (double*) scalloc( total_cap, sizeof(double), "r", comm ); - workspace->d = (double*) scalloc( total_cap, sizeof(double), "d", comm ); - workspace->q = (double*) scalloc( total_cap, sizeof(double), "q", comm ); - workspace->p = (double*) scalloc( total_cap, sizeof(double), "p", comm ); - workspace->r2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "r2", comm ); - workspace->d2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "d2", comm ); - workspace->q2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "q2", comm ); - workspace->p2 = (rvec2*) scalloc( total_cap, sizeof(rvec2), "p2", comm ); + workspace->r = (double*) scalloc(lmp, total_cap, sizeof(double), "r", comm ); + workspace->d = (double*) scalloc(lmp, total_cap, sizeof(double), "d", comm ); + workspace->q = (double*) scalloc(lmp, total_cap, sizeof(double), "q", comm ); + workspace->p = (double*) scalloc(lmp, total_cap, sizeof(double), "p", comm ); + workspace->r2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "r2", comm ); + workspace->d2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "d2", comm ); + workspace->q2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "q2", comm ); + workspace->p2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "p2", comm ); /* integrator storage */ - workspace->v_const = (rvec*) smalloc( local_rvec, "v_const", comm ); + workspace->v_const = (rvec*) smalloc(lmp, local_rvec, "v_const", comm ); /* force related storage */ - workspace->f = (rvec*) scalloc( total_cap, sizeof(rvec), "f", comm ); + workspace->f = (rvec*) scalloc(lmp, total_cap, sizeof(rvec), "f", comm ); workspace->CdDelta = (double*) - scalloc( total_cap, sizeof(double), "CdDelta", comm ); + scalloc(lmp, total_cap, sizeof(double), "CdDelta", comm ); // storage for reductions with multiple threads #ifdef LMP_USER_OMP - workspace->CdDeltaReduction = (double *) scalloc(sizeof(double), total_cap*control->nthreads, + workspace->CdDeltaReduction = (double *) scalloc(lmp, sizeof(double), total_cap*control->nthreads, "cddelta_reduce", comm); - workspace->forceReduction = (rvec *) scalloc(sizeof(rvec), total_cap*control->nthreads, + workspace->forceReduction = (rvec *) scalloc(lmp, sizeof(rvec), total_cap*control->nthreads, "forceReduction", comm); - workspace->valence_angle_atom_myoffset = (int *) scalloc(sizeof(int), total_cap, "valence_angle_atom_myoffset", comm); + workspace->valence_angle_atom_myoffset = (int *) scalloc(lmp, sizeof(int), total_cap, "valence_angle_atom_myoffset", comm); workspace->my_ext_pressReduction = (rvec *) calloc(sizeof(rvec), control->nthreads); #else LMP_UNUSED_PARAM(control); @@ -321,18 +321,17 @@ int Allocate_Workspace( reax_system * /*system*/, control_params * control, } -static void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, +static void Reallocate_Neighbor_List( LAMMPS* lmp, reax_list *far_nbrs, int n, int num_intrs, MPI_Comm comm ) { - Delete_List( far_nbrs, comm ); - if(!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs, comm )){ - fprintf(stderr, "Problem in initializing far nbrs list. Terminating!\n"); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + Delete_List( lmp, far_nbrs, comm ); + if(!Make_List( lmp, n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs, comm )){ + lmp->error->one(FLERR,"Problem in initializing far neighbors list"); } } -static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, +static int Reallocate_HBonds_List( LAMMPS *lmp, reax_system *system, reax_list *hbonds, MPI_Comm comm ) { int i, total_hbonds; @@ -347,10 +346,9 @@ static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, } total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS )); - Delete_List( hbonds, comm ); - if (!Make_List( system->Hcap, total_hbonds, TYP_HBOND, hbonds, comm )) { - fprintf( stderr, "not enough space for hbonds list. terminating!\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + Delete_List( lmp, hbonds, comm ); + if (!Make_List( lmp, system->Hcap, total_hbonds, TYP_HBOND, hbonds, comm )) { + lmp->error->one(FLERR, "Not enough space for hydrogen bonds list"); } return total_hbonds; @@ -377,13 +375,12 @@ static int Reallocate_Bonds_List( LAMMPS *lmp, reax_system *system, reax_list *b #ifdef LMP_USER_OMP if (system->omp_active) for (i = 0; i < bonds->num_intrs; ++i) - sfree(bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction"); + sfree(lmp, bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction"); #endif - Delete_List( bonds, comm ); - if(!Make_List(system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) { - fprintf( stderr, "not enough space for bonds list. terminating!\n" ); - lmp->error->all(FLERR, "Can't allocate space for hbonds."); + Delete_List( lmp, bonds, comm ); + if(!Make_List(lmp, system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) { + lmp->error->one(FLERR, "Not enough space for bonds list"); } #ifdef LMP_USER_OMP @@ -396,7 +393,7 @@ static int Reallocate_Bonds_List( LAMMPS *lmp, reax_system *system, reax_list *b if (system->omp_active) for (i = 0; i < bonds->num_intrs; ++i) bonds->select.bond_list[i].bo_data.CdboReduction = - (double*) smalloc(sizeof(double)*nthreads, "CdboReduction", comm); + (double*) smalloc(lmp, sizeof(double)*nthreads, "CdboReduction", comm); #endif return SUCCESS; @@ -437,21 +434,19 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, /* system */ ret = Allocate_System( system, system->local_cap, system->total_cap, msg ); if (ret != SUCCESS) { - fprintf( stderr, "not enough space for atom_list: total_cap=%d", - system->total_cap ); - fprintf( stderr, "terminating...\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + char errmsg[128]; + snprintf(errmsg, 128, "Not enough space for atom_list: total_cap=%d", system->total_cap); + lmp->error->one(FLERR, errmsg); } /* workspace */ - DeAllocate_Workspace( control, workspace ); - ret = Allocate_Workspace( system, control, workspace, system->local_cap, + DeAllocate_Workspace( lmp, control, workspace ); + ret = Allocate_Workspace( lmp, system, control, workspace, system->local_cap, system->total_cap, comm, msg ); if (ret != SUCCESS) { - fprintf( stderr, "no space for workspace: local_cap=%d total_cap=%d", - system->local_cap, system->total_cap ); - fprintf( stderr, "terminating...\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + char errmsg[128]; + snprintf(errmsg, 128, "Not enough space for workspace: local_cap=%d total_cap=%d", system->local_cap, system->total_cap); + lmp->error->one(FLERR, errmsg); } } @@ -463,15 +458,15 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, if (Nflag || realloc->num_far >= far_nbrs->num_intrs * DANGER_ZONE) { if (realloc->num_far > far_nbrs->num_intrs) { - fprintf( stderr, "step%d-ran out of space on far_nbrs: top=%d, max=%d", - data->step, realloc->num_far, far_nbrs->num_intrs ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + char errmsg[128]; + snprintf(errmsg, 128, "step%d-ran out of space on far_nbrs: top=%d, max=%d", data->step, realloc->num_far, far_nbrs->num_intrs); + lmp->error->one(FLERR, errmsg); } newsize = static_cast (MAX( realloc->num_far*safezone, mincap*MIN_NBRS )); - Reallocate_Neighbor_List( far_nbrs, system->total_cap, newsize, comm ); + Reallocate_Neighbor_List( lmp, far_nbrs, system->total_cap, newsize, comm ); realloc->num_far = 0; } } @@ -486,7 +481,7 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, } if (Hflag || realloc->hbonds) { - ret = Reallocate_HBonds_List( system, (*lists)+HBONDS, comm ); + ret = Reallocate_HBonds_List( lmp, system, (*lists)+HBONDS, comm ); realloc->hbonds = 0; } } @@ -502,17 +497,16 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, /* 3-body list */ if (realloc->num_3body > 0) { - Delete_List( (*lists)+THREE_BODIES, comm ); + Delete_List( lmp, (*lists)+THREE_BODIES, comm ); if (num_bonds == -1) num_bonds = ((*lists)+BONDS)->num_intrs; realloc->num_3body = (int)(MAX(realloc->num_3body*safezone, MIN_3BODIES)); - if( !Make_List( num_bonds, realloc->num_3body, TYP_THREE_BODY, + if( !Make_List( lmp, num_bonds, realloc->num_3body, TYP_THREE_BODY, (*lists)+THREE_BODIES, comm ) ) { - fprintf( stderr, "Problem in initializing angles list. Terminating!\n" ); - MPI_Abort( comm, CANNOT_INITIALIZE ); + lmp->error->one(FLERR, "Problem in initializing angles list"); } realloc->num_3body = -1; } diff --git a/src/USER-REAXC/reaxc_allocate.h b/src/USER-REAXC/reaxc_allocate.h index 786ee6ee8b..9f009b0916 100644 --- a/src/USER-REAXC/reaxc_allocate.h +++ b/src/USER-REAXC/reaxc_allocate.h @@ -33,14 +33,14 @@ #include "error.h" using namespace LAMMPS_NS; -int PreAllocate_Space( reax_system*, control_params*, storage*, MPI_Comm ); +int PreAllocate_Space( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, storage*, MPI_Comm ); int Allocate_System( reax_system*, int, int, char* ); -void DeAllocate_System( reax_system* ); +void DeAllocate_System( LAMMPS_NS::LAMMPS*, reax_system* ); -int Allocate_Workspace( reax_system*, control_params*, storage*, +int Allocate_Workspace( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, storage*, int, int, MPI_Comm, char* ); -void DeAllocate_Workspace( control_params*, storage* ); +void DeAllocate_Workspace( LAMMPS_NS::LAMMPS*, control_params*, storage* ); void ReAllocate( LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, reax_list**, mpi_datatypes* ); diff --git a/src/USER-REAXC/reaxc_bond_orders.cpp b/src/USER-REAXC/reaxc_bond_orders.cpp index 1ed58a0bfd..924be8809d 100644 --- a/src/USER-REAXC/reaxc_bond_orders.cpp +++ b/src/USER-REAXC/reaxc_bond_orders.cpp @@ -360,7 +360,8 @@ int BOp( storage *workspace, reax_list *bonds, double bo_cut, void BO( reax_system *system, control_params * /*control*/, simulation_data * /*data*/, - storage *workspace, reax_list **lists, output_controls * /*out_control*/ ) + storage *workspace, reax_list **lists, output_controls * /*out_control*/, + LAMMPS_NS::LAMMPS* lmp ) { int i, j, pj, type_i, type_j; int start_i, end_i, sym_index; diff --git a/src/USER-REAXC/reaxc_bond_orders.h b/src/USER-REAXC/reaxc_bond_orders.h index 3631d90c89..8de60ba2f2 100644 --- a/src/USER-REAXC/reaxc_bond_orders.h +++ b/src/USER-REAXC/reaxc_bond_orders.h @@ -42,5 +42,5 @@ void Add_dBond_to_Forces_NPT( int, int, simulation_data*, int BOp(storage*, reax_list*, double, int, int, far_neighbor_data*, single_body_parameters*, single_body_parameters*, two_body_parameters*); void BO( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls* ); + storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); #endif diff --git a/src/USER-REAXC/reaxc_bonds.cpp b/src/USER-REAXC/reaxc_bonds.cpp index 48fb872324..d5ac4f1ed4 100644 --- a/src/USER-REAXC/reaxc_bonds.cpp +++ b/src/USER-REAXC/reaxc_bonds.cpp @@ -33,7 +33,7 @@ void Bonds( reax_system *system, control_params * /*control*/, simulation_data *data, storage *workspace, reax_list **lists, - output_controls * /*out_control*/ ) + output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp ) { int i, j, pj, natoms; int start_i, end_i; diff --git a/src/USER-REAXC/reaxc_bonds.h b/src/USER-REAXC/reaxc_bonds.h index a4a1fb0b44..b425598b42 100644 --- a/src/USER-REAXC/reaxc_bonds.h +++ b/src/USER-REAXC/reaxc_bonds.h @@ -30,5 +30,5 @@ #include "reaxc_types.h" void Bonds( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls* ); + storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); #endif diff --git a/src/USER-REAXC/reaxc_control.cpp b/src/USER-REAXC/reaxc_control.cpp index dd2b5a32ad..bf221a6266 100644 --- a/src/USER-REAXC/reaxc_control.cpp +++ b/src/USER-REAXC/reaxc_control.cpp @@ -28,7 +28,9 @@ #include "reaxc_control.h" #include "reaxc_tool_box.h" -char Read_Control_File( char *control_file, control_params* control, +using namespace LAMMPS_NS; + +char Read_Control_File( LAMMPS *lmp, char *control_file, control_params* control, output_controls *out_control ) { FILE *fp; @@ -38,8 +40,7 @@ char Read_Control_File( char *control_file, control_params* control, /* open control file */ if ( (fp = fopen( control_file, "r" ) ) == NULL ) { - fprintf( stderr, "error opening the control file! terminating...\n" ); - MPI_Abort( MPI_COMM_WORLD, FILE_NOT_FOUND ); + lmp->error->all(FLERR, "The control file cannot be opened"); } /* assign default values */ @@ -364,8 +365,9 @@ char Read_Control_File( char *control_file, control_params* control, control->restrict_type = ival; } else { - fprintf( stderr, "WARNING: unknown parameter %s\n", tmp[0] ); - MPI_Abort( MPI_COMM_WORLD, 15 ); + char errmsg[128]; + snprintf(errmsg,128,"Unknown parameter %s in the control file", tmp[0]); + lmp->error->all(FLERR, errmsg); } } diff --git a/src/USER-REAXC/reaxc_control.h b/src/USER-REAXC/reaxc_control.h index b2b455d6b8..4546a894f6 100644 --- a/src/USER-REAXC/reaxc_control.h +++ b/src/USER-REAXC/reaxc_control.h @@ -29,6 +29,9 @@ #include "reaxc_types.h" -char Read_Control_File( char*, control_params*, output_controls* ); +#include "lammps.h" +#include "error.h" + +char Read_Control_File( LAMMPS_NS::LAMMPS *lmp, char*, control_params*, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_ffield.cpp b/src/USER-REAXC/reaxc_ffield.cpp index dd8f12f9d2..6096e3e614 100644 --- a/src/USER-REAXC/reaxc_ffield.cpp +++ b/src/USER-REAXC/reaxc_ffield.cpp @@ -29,7 +29,10 @@ #include "reaxc_ffield.h" #include "reaxc_tool_box.h" -char Read_Force_Field( FILE *fp, reax_interaction *reax, +#include "lammps.h" +#include "error.h" + +char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, control_params *control ) { char *s; @@ -41,7 +44,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, double val; MPI_Comm comm; int me; - + comm = MPI_COMM_WORLD; MPI_Comm_rank(comm, &me); @@ -61,7 +64,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, n = atoi(tmp[0]); if (n < 1) { if (me == 0) - fprintf( stderr, "WARNING: number of globals in ffield file is 0!\n" ); + lmp->error->warning( FLERR, "Number of globals in ffield file is 0" ); fclose(fp); free(s); free(tmp); @@ -96,54 +99,54 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Allocating structures in reax_interaction */ reax->sbp = (single_body_parameters*) - scalloc( reax->num_atom_types, sizeof(single_body_parameters), "sbp", + scalloc(lmp, reax->num_atom_types, sizeof(single_body_parameters), "sbp", comm ); reax->tbp = (two_body_parameters**) - scalloc( reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); reax->thbp= (three_body_header***) - scalloc( reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); reax->hbp = (hbond_parameters***) - scalloc( reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); reax->fbp = (four_body_header****) - scalloc( reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); tor_flag = (char****) - scalloc( reax->num_atom_types, sizeof(char***), "tor_flag", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(char***), "tor_flag", comm ); for( i = 0; i < reax->num_atom_types; i++ ) { reax->tbp[i] = (two_body_parameters*) - scalloc( reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", + scalloc(lmp, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", comm ); reax->thbp[i]= (three_body_header**) - scalloc( reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", + scalloc(lmp, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", comm ); reax->hbp[i] = (hbond_parameters**) - scalloc( reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", + scalloc(lmp, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", comm ); reax->fbp[i] = (four_body_header***) - scalloc( reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", + scalloc(lmp, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", comm ); tor_flag[i] = (char***) - scalloc( reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); for( j = 0; j < reax->num_atom_types; j++ ) { reax->thbp[i][j]= (three_body_header*) - scalloc( reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", + scalloc(lmp, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", comm ); reax->hbp[i][j] = (hbond_parameters*) - scalloc( reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", + scalloc(lmp, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", comm ); reax->fbp[i][j] = (four_body_header**) - scalloc( reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", + scalloc(lmp, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", comm ); tor_flag[i][j] = (char**) - scalloc( reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); + scalloc(lmp, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); for (k=0; k < reax->num_atom_types; k++) { reax->fbp[i][j][k] = (four_body_header*) - scalloc( reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", + scalloc(lmp, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", comm ); tor_flag[i][j][k] = (char*) - scalloc( reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", + scalloc(lmp, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", comm ); } } @@ -158,15 +161,9 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, c = Tokenize( s, &tmp ); /* Sanity checks */ - if (c == 2 && !lgflag) { - if (me == 0) - fprintf(stderr, "Force field file requires using 'lgvdw yes'\n"); - MPI_Abort( comm, FILE_NOT_FOUND ); - } + if (c < 9) { - if (me == 0) - fprintf(stderr, "Inconsistent ffield file (reaxc_ffield.cpp) \n"); - MPI_Abort( comm, FILE_NOT_FOUND ); + lmp->error->one(FLERR,"Inconsistent ffield file"); } for( j = 0; j < (int)(strlen(tmp[0])); ++j ) @@ -188,9 +185,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - if (me == 0) - fprintf(stderr, "Inconsistent ffield file (reaxc_ffield.cpp) \n"); - MPI_Abort( comm, FILE_NOT_FOUND ); + lmp->error->one(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].alpha = val; @@ -208,9 +203,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - if (me == 0) - fprintf(stderr, "Inconsistent ffield file (reaxc_ffield.cpp) \n"); - MPI_Abort( comm, FILE_NOT_FOUND ); + lmp->error->one(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].r_pi_pi = val; @@ -228,9 +221,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - if (me == 0) - fprintf(stderr, "Inconsistent ffield file (reaxc_ffield.cpp) \n"); - MPI_Abort( comm, FILE_NOT_FOUND ); + lmp->error->one(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].p_ovun2 = val; @@ -249,9 +240,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c > 2) { - if (me == 0) - fprintf(stderr, "Force field file incompatible with 'lgvdw yes'\n"); - MPI_Abort( comm, FILE_NOT_FOUND ); + lmp->error->one(FLERR,"Force field file incompatible with 'lgvdw yes'"); } val = atof(tmp[0]); reax->sbp[i].lgcij = val; @@ -261,28 +250,32 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, if (reax->sbp[i].rcore2>0.01 && reax->sbp[i].acore2>0.01) { // Inner-wall if (reax->sbp[i].gamma_w>0.5) { // Shielding vdWaals if (reax->gp.vdw_type != 0 && reax->gp.vdw_type != 3) { - if (errorflag && (me == 0)) - fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ - "Force field parameters for element %s\n" \ - "indicate inner wall+shielding, but earlier\n" \ - "atoms indicate different vdWaals-method.\n" \ - "This may cause division-by-zero errors.\n" \ - "Keeping vdWaals-setting for earlier atoms.\n", - reax->sbp[i].name ); + if (errorflag && (me == 0)) { + char errmsg[512]; + snprintf(errmsg, 512, "VdWaals-parameters for element %s " + "indicate inner wall+shielding, but earlier " + "atoms indicate different vdWaals-method. " + "This may cause division-by-zero errors. " + "Keeping vdWaals-setting for earlier atoms.", + reax->sbp[i].name); + lmp->error->warning(FLERR,errmsg); + } errorflag = 0; } else { reax->gp.vdw_type = 3; } } else { // No shielding vdWaals parameters present if (reax->gp.vdw_type != 0 && reax->gp.vdw_type != 2) { - if (me == 0) - fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ - "Force field parameters for element %s\n" \ - "indicate inner wall without shielding, but earlier\n" \ - "atoms indicate different vdWaals-method.\n" \ - "This may cause division-by-zero errors.\n" \ - "Keeping vdWaals-setting for earlier atoms.\n", - reax->sbp[i].name ); + if (me == 0) { + char errmsg[512]; + snprintf(errmsg, 512, "VdWaals-parameters for element %s " + "indicate inner wall without shielding, but earlier " + "atoms indicate different vdWaals-method. " + "This may cause division-by-zero errors. " + "Keeping vdWaals-setting for earlier atoms.", + reax->sbp[i].name); + lmp->error->warning(FLERR,errmsg); + } } else { reax->gp.vdw_type = 2; } @@ -290,23 +283,25 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, } else { // No Inner wall parameters present if (reax->sbp[i].gamma_w>0.5) { // Shielding vdWaals if (reax->gp.vdw_type != 0 && reax->gp.vdw_type != 1) { - if (me == 0) - fprintf( stderr, "Warning: inconsistent vdWaals-parameters\n" \ - "Force field parameters for element %s\n" \ - "indicate shielding without inner wall, but earlier\n" \ - "atoms indicate different vdWaals-method.\n" \ - "This may cause division-by-zero errors.\n" \ - "Keeping vdWaals-setting for earlier atoms.\n", - reax->sbp[i].name ); + if (me == 0) { + char errmsg[512]; + snprintf(errmsg, 512, "VdWaals parameters for element %s " + "indicate shielding without inner wall, but earlier " + "elements indicate different vdWaals-method. " + "This may cause division-by-zero errors. " + "Keeping vdWaals-setting for earlier atoms.", + reax->sbp[i].name); + lmp->error->warning(FLERR,errmsg); + } } else { reax->gp.vdw_type = 1; } } else { - if (me == 0) - fprintf( stderr, "Error: inconsistent vdWaals-parameters\n" \ - "No shielding or inner-wall set for element %s\n", - reax->sbp[i].name ); - MPI_Abort( comm, INVALID_INPUT ); + char errmsg[256]; + snprintf(errmsg, 256, "Inconsistent vdWaals-parameters " + "No shielding or inner-wall set for element %s", + reax->sbp[i].name); + lmp->error->all(FLERR, errmsg); } } } @@ -315,15 +310,23 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, for( i = 0; i < reax->num_atom_types; i++ ) if( reax->sbp[i].mass < 21 && reax->sbp[i].valency_val != reax->sbp[i].valency_boc ) { - if (me == 0) - fprintf(stderr,"Warning: changed valency_val to valency_boc for %s\n", - reax->sbp[i].name ); + if (me == 0) { + char errmsg[256]; + snprintf(errmsg, 256, "Changed valency_val to valency_boc for %s", + reax->sbp[i].name); + lmp->error->warning(FLERR,errmsg); + } reax->sbp[i].valency_val = reax->sbp[i].valency_boc; } /* next line is number of two body combination and some comments */ fgets(s,MAX_LINE,fp); c=Tokenize(s,&tmp); + + if (c == 2 && !lgflag) { + lmp->error->all(FLERR, "Force field file requires using 'lgvdw yes'"); + } + l = atoi(tmp[0]); /* a line of comments */ @@ -334,6 +337,8 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, fgets(s,MAX_LINE,fp); c=Tokenize(s,&tmp); + + j = atoi(tmp[0]) - 1; k = atoi(tmp[1]) - 1; diff --git a/src/USER-REAXC/reaxc_ffield.h b/src/USER-REAXC/reaxc_ffield.h index 7cef730f91..225f207de9 100644 --- a/src/USER-REAXC/reaxc_ffield.h +++ b/src/USER-REAXC/reaxc_ffield.h @@ -29,6 +29,6 @@ #include "reaxc_types.h" -char Read_Force_Field( FILE*, reax_interaction*, control_params* ); +char Read_Force_Field( LAMMPS_NS::LAMMPS*, FILE*, reax_interaction*, control_params* ); #endif diff --git a/src/USER-REAXC/reaxc_forces.cpp b/src/USER-REAXC/reaxc_forces.cpp index 848c03f5a1..4adec04f0c 100644 --- a/src/USER-REAXC/reaxc_forces.cpp +++ b/src/USER-REAXC/reaxc_forces.cpp @@ -39,15 +39,12 @@ #include "reaxc_valence_angles.h" #include "reaxc_vector.h" -#include "lammps.h" -#include "error.h" interaction_function Interaction_Functions[NUM_INTRS]; -using namespace LAMMPS_NS; void Dummy_Interaction( reax_system * /*system*/, control_params * /*control*/, simulation_data * /*data*/, storage * /*workspace*/, - reax_list **/*lists*/, output_controls * /*out_control*/ ) + reax_list ** /*lists*/, output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* = NULL ) { } @@ -79,7 +76,7 @@ void Compute_Bonded_Forces( reax_system *system, control_params *control, /* Implement all force calls as function pointers */ for( i = 0; i < NUM_INTRS; i++ ) { (Interaction_Functions[i])( system, control, data, workspace, - lists, out_control ); + lists, out_control, NULL ); } } @@ -118,7 +115,7 @@ void Compute_Total_Force( reax_system *system, control_params *control, } -void Validate_Lists( LAMMPS *lmp, reax_system *system, storage * /*workspace*/, reax_list **lists, +void Validate_Lists( LAMMPS_NS::LAMMPS *lmp, reax_system *system, storage * /*workspace*/, reax_list **lists, int step, int /*n*/, int N, int numH, MPI_Comm comm ) { int i, comp, Hindex; @@ -138,9 +135,10 @@ void Validate_Lists( LAMMPS *lmp, reax_system *system, storage * /*workspace*/, else comp = bonds->num_intrs; if (End_Index(i, bonds) > comp) { - fprintf( stderr, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", + char errmsg[256]; + snprintf(errmsg, 256, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, i, End_Index(i,bonds), comp ); - lmp->error->all(FLERR,"Failure in bond list."); + lmp->error->all(FLERR,errmsg); } } } @@ -165,9 +163,10 @@ void Validate_Lists( LAMMPS *lmp, reax_system *system, storage * /*workspace*/, else comp = hbonds->num_intrs; if (End_Index(Hindex, hbonds) > comp) { - fprintf(stderr,"step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", + char errmsg[256]; + snprintf(errmsg, 256, "step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", step, Hindex, End_Index(Hindex,hbonds), comp ); - lmp->error->all(FLERR, "Failure in hydrogen bonds."); + lmp->error->all(FLERR, errmsg); } } } @@ -175,7 +174,7 @@ void Validate_Lists( LAMMPS *lmp, reax_system *system, storage * /*workspace*/, } -void Init_Forces_noQEq( LAMMPS *lmp, reax_system *system, control_params *control, +void Init_Forces_noQEq( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls * /*out_control*/, MPI_Comm comm ) { @@ -435,7 +434,7 @@ void Estimate_Storages( reax_system *system, control_params *control, } -void Compute_Forces( LAMMPS *lmp, reax_system *system, control_params *control, +void Compute_Forces( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp index be34df7571..489a43cfc1 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp @@ -33,7 +33,7 @@ void Hydrogen_Bonds( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls * /*out_control*/ ) + reax_list **lists, output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp ) { int i, j, k, pi, pk; int type_i, type_j, type_k; diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.h b/src/USER-REAXC/reaxc_hydrogen_bonds.h index 04d3d26d5c..2a448439ea 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.h +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.h @@ -30,6 +30,6 @@ #include "reaxc_types.h" void Hydrogen_Bonds( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls* ); + storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); #endif diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index 4565fd067d..6ee68d6c46 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -82,7 +82,7 @@ int Init_Simulation_Data( reax_system *system, control_params *control, return SUCCESS; } -void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) +void Init_Taper( LAMMPS_NS::LAMMPS* lmp, control_params *control, storage *workspace, MPI_Comm comm ) { double d1, d7; double swa, swa2, swa3; @@ -92,14 +92,16 @@ void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) swb = control->nonb_cut; if (fabs( swa ) > 0.01) - fprintf( stderr, "Warning: non-zero lower Taper-radius cutoff\n" ); + lmp->error->warning( FLERR, "Non-zero lower Taper-radius cutoff" ); if (swb < 0) { - fprintf( stderr, "Negative upper Taper-radius cutoff\n" ); - MPI_Abort( comm, INVALID_INPUT ); + lmp->error->all(FLERR,"Negative upper Taper-radius cutoff"); + } + else if( swb < 5 ) { + char errmsg[256]; + snprintf(errmsg, 256, "Very low Taper-radius cutoff: %f", swb ); + lmp->error->warning( FLERR, errmsg ); } - else if( swb < 5 ) - fprintf( stderr, "Warning: very low Taper-radius cutoff: %f\n", swb ); d1 = swb - swa; d7 = pow( d1, 7.0 ); @@ -120,12 +122,12 @@ void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) } -int Init_Workspace( reax_system *system, control_params *control, +int Init_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, storage *workspace, MPI_Comm comm, char *msg ) { int ret; - ret = Allocate_Workspace( system, control, workspace, + ret = Allocate_Workspace( lmp, system, control, workspace, system->local_cap, system->total_cap, comm, msg ); if (ret != SUCCESS) return ret; @@ -134,7 +136,7 @@ int Init_Workspace( reax_system *system, control_params *control, Reset_Workspace( system, workspace ); /* Initialize the Taper function */ - Init_Taper( control, workspace, comm ); + Init_Taper( lmp, control, workspace, comm ); return SUCCESS; } @@ -179,10 +181,9 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, } total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS )); - if( !Make_List( system->Hcap, total_hbonds, TYP_HBOND, + if( !Make_List( lmp, system->Hcap, total_hbonds, TYP_HBOND, *lists+HBONDS, comm ) ) { - fprintf( stderr, "not enough space for hbonds list. terminating!\n" ); - lmp->error->all(FLERR, "Can't allocate space for hbonds."); + lmp->error->one(FLERR, "Not enough space for hbonds list."); } } @@ -193,18 +194,16 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, } bond_cap = (int)(MAX( total_bonds*safezone, mincap*MIN_BONDS )); - if( !Make_List( system->total_cap, bond_cap, TYP_BOND, + if( !Make_List( lmp, system->total_cap, bond_cap, TYP_BOND, *lists+BONDS, comm ) ) { - fprintf( stderr, "not enough space for bonds list. terminating!\n" ); - lmp->error->all(FLERR, "Can't allocate space for hbonds."); + lmp->error->one(FLERR, "Not enough space for bonds list."); } /* 3bodies list */ cap_3body = (int)(MAX( num_3body*safezone, MIN_3BODIES )); - if( !Make_List( bond_cap, cap_3body, TYP_THREE_BODY, + if( !Make_List( lmp, bond_cap, cap_3body, TYP_THREE_BODY, *lists+THREE_BODIES, comm ) ){ - fprintf( stderr, "Problem in initializing angles list. Terminating!\n" ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + lmp->error->one(FLERR,"Problem in initializing angles list."); } free( hb_top ); @@ -219,60 +218,53 @@ void Initialize( LAMMPS *lmp, reax_system *system, control_params *control, mpi_datatypes *mpi_data, MPI_Comm comm ) { char msg[MAX_STR]; + char errmsg[128]; if (Init_MPI_Datatypes(system, workspace, mpi_data, comm, msg) == FAILURE) { - fprintf( stderr, "p%d: init_mpi_datatypes: could not create datatypes\n", - system->my_rank ); - fprintf( stderr, "p%d: mpi_data couldn't be initialized! terminating.\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + + snprintf(errmsg, 128, "Could not create datatypes on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } if (Init_System(system, control, msg) == FAILURE) { - fprintf( stderr, "p%d: %s\n", system->my_rank, msg ); - fprintf( stderr, "p%d: system could not be initialized! terminating.\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + snprintf(errmsg, 128, "System could not be initialized on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } if (Init_Simulation_Data( system, control, data, msg ) == FAILURE) { - fprintf( stderr, "p%d: %s\n", system->my_rank, msg ); - fprintf( stderr, "p%d: sim_data couldn't be initialized! terminating.\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + snprintf(errmsg, 128, "Sim_data could not be initialized on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } - if (Init_Workspace( system, control, workspace, mpi_data->world, msg ) == + if (Init_Workspace( lmp, system, control, workspace, mpi_data->world, msg ) == FAILURE) { - fprintf( stderr, "p%d:init_workspace: not enough memory\n", - system->my_rank ); - fprintf( stderr, "p%d:workspace couldn't be initialized! terminating.\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + snprintf(errmsg, 128, "Workspace could not be initialized on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } if (Init_Lists( lmp, system, control, data, workspace, lists, mpi_data, msg ) == FAILURE) { - fprintf( stderr, "p%d: %s\n", system->my_rank, msg ); - fprintf( stderr, "p%d: system could not be initialized! terminating.\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + snprintf(errmsg, 128, "System could not be initialized on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } - if (Init_Output_Files(system,control,out_control,mpi_data,msg)== FAILURE) { - fprintf( stderr, "p%d: %s\n", system->my_rank, msg ); - fprintf( stderr, "p%d: could not open output files! terminating...\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + if (Init_Output_Files(lmp, system,control,out_control,mpi_data,msg)== FAILURE) { + snprintf(errmsg, 128, "Could not open output files on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } if (control->tabulate) { - if (Init_Lookup_Tables( system, control, workspace, mpi_data, msg ) == FAILURE) { - fprintf( stderr, "p%d: %s\n", system->my_rank, msg ); - fprintf( stderr, "p%d: couldn't create lookup table! terminating.\n", - system->my_rank ); - MPI_Abort( mpi_data->world, CANNOT_INITIALIZE ); + if (Init_Lookup_Tables( lmp, system, control, workspace, mpi_data, msg ) == FAILURE) { + snprintf(errmsg, 128, "Lookup table could not be created on thread %d", + system->my_rank); + lmp->error->one(FLERR,errmsg); } } diff --git a/src/USER-REAXC/reaxc_io_tools.cpp b/src/USER-REAXC/reaxc_io_tools.cpp index f71fcbec8e..aa7e7fcea7 100644 --- a/src/USER-REAXC/reaxc_io_tools.cpp +++ b/src/USER-REAXC/reaxc_io_tools.cpp @@ -34,7 +34,7 @@ #include "reaxc_traj.h" #include "reaxc_vector.h" -int Init_Output_Files( reax_system *system, control_params *control, +int Init_Output_Files( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, output_controls *out_control, mpi_datatypes *mpi_data, char *msg ) { @@ -42,7 +42,7 @@ int Init_Output_Files( reax_system *system, control_params *control, int ret; if (out_control->write_steps > 0) { - ret = Init_Traj( system, control, out_control, mpi_data, msg ); + ret = Init_Traj( lmp, system, control, out_control, mpi_data, msg ); if (ret == FAILURE) return ret; } @@ -107,7 +107,7 @@ int Close_Output_Files( reax_system *system, control_params *control, } -void Output_Results( reax_system *system, control_params *control, +void Output_Results( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, simulation_data *data, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -146,7 +146,7 @@ void Output_Results( reax_system *system, control_params *control, /* write current frame */ if( out_control->write_steps > 0 && (data->step-data->prev_steps) % out_control->write_steps == 0 ) { - Append_Frame( system, control, data, lists, out_control, mpi_data ); + Append_Frame( lmp, system, control, data, lists, out_control, mpi_data ); } } diff --git a/src/USER-REAXC/reaxc_io_tools.h b/src/USER-REAXC/reaxc_io_tools.h index a3f22fccc2..80202d5c83 100644 --- a/src/USER-REAXC/reaxc_io_tools.h +++ b/src/USER-REAXC/reaxc_io_tools.h @@ -29,10 +29,10 @@ #include "reaxc_types.h" -int Init_Output_Files( reax_system*, control_params*, +int Init_Output_Files( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, output_controls*, mpi_datatypes*, char* ); int Close_Output_Files( reax_system*, control_params*, output_controls*, mpi_datatypes* ); -void Output_Results( reax_system*, control_params*, simulation_data*, +void Output_Results( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, simulation_data*, reax_list**, output_controls*, mpi_datatypes* ); #endif diff --git a/src/USER-REAXC/reaxc_list.cpp b/src/USER-REAXC/reaxc_list.cpp index 8a3bb9d322..5d4ab2f3c8 100644 --- a/src/USER-REAXC/reaxc_list.cpp +++ b/src/USER-REAXC/reaxc_list.cpp @@ -29,116 +29,118 @@ #include "reaxc_tool_box.h" /************* allocate list space ******************/ -int Make_List(int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) +int Make_List( LAMMPS_NS::LAMMPS *lmp, int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) { l->allocated = 1; l->n = n; l->num_intrs = num_intrs; - if (l->index) sfree(l->index, "list:index"); - if (l->end_index) sfree(l->end_index, "list:end_index"); - l->index = (int*) smalloc( n * sizeof(int), "list:index", comm ); - l->end_index = (int*) smalloc( n * sizeof(int), "list:end_index", comm ); + if (l->index) sfree(lmp, l->index, "list:index"); + if (l->end_index) sfree(lmp, l->end_index, "list:end_index"); + l->index = (int*) smalloc(lmp, n * sizeof(int), "list:index", comm ); + l->end_index = (int*) smalloc(lmp, n * sizeof(int), "list:end_index", comm ); l->type = type; switch(l->type) { case TYP_VOID: - if (l->select.v) sfree(l->select.v, "list:v"); - l->select.v = (void*) smalloc(l->num_intrs * sizeof(void*), "list:v", comm); + if (l->select.v) sfree(lmp, l->select.v, "list:v"); + l->select.v = (void*) smalloc(lmp, l->num_intrs * sizeof(void*), "list:v", comm); break; case TYP_THREE_BODY: - if (l->select.three_body_list) sfree(l->select.three_body_list,"list:three_bodies"); + if (l->select.three_body_list) sfree(lmp, l->select.three_body_list,"list:three_bodies"); l->select.three_body_list = (three_body_interaction_data*) - smalloc( l->num_intrs * sizeof(three_body_interaction_data), + smalloc(lmp, l->num_intrs * sizeof(three_body_interaction_data), "list:three_bodies", comm ); break; case TYP_BOND: - if (l->select.bond_list) sfree(l->select.bond_list,"list:bonds"); + if (l->select.bond_list) sfree(lmp, l->select.bond_list,"list:bonds"); l->select.bond_list = (bond_data*) - smalloc( l->num_intrs * sizeof(bond_data), "list:bonds", comm ); + smalloc(lmp, l->num_intrs * sizeof(bond_data), "list:bonds", comm ); break; case TYP_DBO: - if (l->select.dbo_list) sfree(l->select.dbo_list,"list:dbonds"); + if (l->select.dbo_list) sfree(lmp, l->select.dbo_list,"list:dbonds"); l->select.dbo_list = (dbond_data*) - smalloc( l->num_intrs * sizeof(dbond_data), "list:dbonds", comm ); + smalloc(lmp, l->num_intrs * sizeof(dbond_data), "list:dbonds", comm ); break; case TYP_DDELTA: - if (l->select.dDelta_list) sfree(l->select.dDelta_list,"list:dDeltas"); + if (l->select.dDelta_list) sfree(lmp, l->select.dDelta_list,"list:dDeltas"); l->select.dDelta_list = (dDelta_data*) - smalloc( l->num_intrs * sizeof(dDelta_data), "list:dDeltas", comm ); + smalloc(lmp, l->num_intrs * sizeof(dDelta_data), "list:dDeltas", comm ); break; case TYP_FAR_NEIGHBOR: - if (l->select.far_nbr_list) sfree(l->select.far_nbr_list,"list:far_nbrs"); + if (l->select.far_nbr_list) sfree(lmp, l->select.far_nbr_list,"list:far_nbrs"); l->select.far_nbr_list = (far_neighbor_data*) - smalloc(l->num_intrs * sizeof(far_neighbor_data), "list:far_nbrs", comm); + smalloc(lmp, l->num_intrs * sizeof(far_neighbor_data), "list:far_nbrs", comm); break; case TYP_HBOND: - if (l->select.hbond_list) sfree(l->select.hbond_list,"list:hbonds"); + if (l->select.hbond_list) sfree(lmp, l->select.hbond_list,"list:hbonds"); l->select.hbond_list = (hbond_data*) - smalloc( l->num_intrs * sizeof(hbond_data), "list:hbonds", comm ); + smalloc(lmp, l->num_intrs * sizeof(hbond_data), "list:hbonds", comm ); break; default: - fprintf( stderr, "ERROR: no %d list type defined!\n", l->type ); - MPI_Abort( comm, INVALID_INPUT ); + char errmsg[128]; + snprintf(errmsg, 128, "No %d list type defined", l->type); + lmp->error->all(FLERR,errmsg); } return SUCCESS; } -void Delete_List( reax_list *l, MPI_Comm comm ) +void Delete_List( LAMMPS_NS::LAMMPS *lmp, reax_list *l, MPI_Comm comm ) { if (l->allocated == 0) return; l->allocated = 0; - sfree( l->index, "list:index" ); - sfree( l->end_index, "list:end_index" ); + sfree(lmp, l->index, "list:index" ); + sfree(lmp, l->end_index, "list:end_index" ); l->index = NULL; l->end_index = NULL; switch(l->type) { case TYP_VOID: - sfree( l->select.v, "list:v" ); + sfree(lmp, l->select.v, "list:v" ); l->select.v = NULL; break; case TYP_HBOND: - sfree( l->select.hbond_list, "list:hbonds" ); + sfree(lmp, l->select.hbond_list, "list:hbonds" ); l->select.hbond_list = NULL; break; case TYP_FAR_NEIGHBOR: - sfree( l->select.far_nbr_list, "list:far_nbrs" ); + sfree(lmp, l->select.far_nbr_list, "list:far_nbrs" ); l->select.far_nbr_list = NULL; break; case TYP_BOND: - sfree( l->select.bond_list, "list:bonds" ); + sfree(lmp, l->select.bond_list, "list:bonds" ); l->select.bond_list = NULL; break; case TYP_DBO: - sfree( l->select.dbo_list, "list:dbos" ); + sfree(lmp, l->select.dbo_list, "list:dbos" ); l->select.dbo_list = NULL; break; case TYP_DDELTA: - sfree( l->select.dDelta_list, "list:dDeltas" ); + sfree(lmp, l->select.dDelta_list, "list:dDeltas" ); l->select.dDelta_list = NULL; break; case TYP_THREE_BODY: - sfree( l->select.three_body_list, "list:three_bodies" ); + sfree(lmp, l->select.three_body_list, "list:three_bodies" ); l->select.three_body_list = NULL; break; default: - fprintf( stderr, "ERROR: no %d list type defined!\n", l->type ); - MPI_Abort( comm, INVALID_INPUT ); + char errmsg[128]; + snprintf(errmsg, 128, "No %d list type defined", l->type); + lmp->error->all(FLERR,errmsg); } } diff --git a/src/USER-REAXC/reaxc_list.h b/src/USER-REAXC/reaxc_list.h index ab7fbce19c..1df2338b0f 100644 --- a/src/USER-REAXC/reaxc_list.h +++ b/src/USER-REAXC/reaxc_list.h @@ -29,8 +29,8 @@ #include "reaxc_types.h" -int Make_List( int, int, int, reax_list*, MPI_Comm ); -void Delete_List( reax_list*, MPI_Comm ); +int Make_List( LAMMPS_NS::LAMMPS*, int, int, int, reax_list*, MPI_Comm ); +void Delete_List( LAMMPS_NS::LAMMPS*, reax_list*, MPI_Comm ); inline int Num_Entries(int,reax_list*); inline int Start_Index( int, reax_list* ); diff --git a/src/USER-REAXC/reaxc_lookup.cpp b/src/USER-REAXC/reaxc_lookup.cpp index 92945ebdb5..41ad5e99d4 100644 --- a/src/USER-REAXC/reaxc_lookup.cpp +++ b/src/USER-REAXC/reaxc_lookup.cpp @@ -50,7 +50,7 @@ void Tridiagonal_Solve( const double *a, const double *b, } -void Natural_Cubic_Spline( const double *h, const double *f, +void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double *f, cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ) { @@ -58,11 +58,11 @@ void Natural_Cubic_Spline( const double *h, const double *f, double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + b = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + c = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + d = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + v = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); /* build the linear system */ a[0] = a[1] = a[n-1] = 0; @@ -92,16 +92,16 @@ void Natural_Cubic_Spline( const double *h, const double *f, coef[i-1].a = f[i]; } - sfree( a, "cubic_spline:a" ); - sfree( b, "cubic_spline:b" ); - sfree( c, "cubic_spline:c" ); - sfree( d, "cubic_spline:d" ); - sfree( v, "cubic_spline:v" ); + sfree(lmp, a, "cubic_spline:a" ); + sfree(lmp, b, "cubic_spline:b" ); + sfree(lmp, c, "cubic_spline:c" ); + sfree(lmp, d, "cubic_spline:d" ); + sfree(lmp, v, "cubic_spline:v" ); } -void Complete_Cubic_Spline( const double *h, const double *f, double v0, double vlast, +void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double *f, double v0, double vlast, cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ) { @@ -109,11 +109,11 @@ void Complete_Cubic_Spline( const double *h, const double *f, double v0, double double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc( n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + b = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + c = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + d = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + v = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); /* build the linear system */ a[0] = 0; @@ -142,15 +142,15 @@ void Complete_Cubic_Spline( const double *h, const double *f, double v0, double coef[i-1].a = f[i]; } - sfree( a, "cubic_spline:a" ); - sfree( b, "cubic_spline:b" ); - sfree( c, "cubic_spline:c" ); - sfree( d, "cubic_spline:d" ); - sfree( v, "cubic_spline:v" ); + sfree(lmp, a, "cubic_spline:a" ); + sfree(lmp, b, "cubic_spline:b" ); + sfree(lmp, c, "cubic_spline:c" ); + sfree(lmp, d, "cubic_spline:d" ); + sfree(lmp, v, "cubic_spline:v" ); } -int Init_Lookup_Tables( reax_system *system, control_params *control, +int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, storage *workspace, mpi_datatypes *mpi_data, char * /*msg*/ ) { int i, j, r; @@ -171,23 +171,23 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, num_atom_types = system->reax_param.num_atom_types; dr = control->nonb_cut / control->tabulate; h = (double*) - smalloc( (control->tabulate+2) * sizeof(double), "lookup:h", comm ); + smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:h", comm ); fh = (double*) - smalloc( (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); + smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); fvdw = (double*) - smalloc( (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); + smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); fCEvd = (double*) - smalloc( (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); + smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); fele = (double*) - smalloc( (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); + smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); fCEclmb = (double*) - smalloc( (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); + smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); LR = (LR_lookup_table**) - scalloc( num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); + scalloc(lmp, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); for( i = 0; i < num_atom_types; ++i ) LR[i] = (LR_lookup_table*) - scalloc( num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); + scalloc(lmp, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); for( i = 0; i < MAX_ATOM_TYPES; ++i ) existing_types[i] = 0; @@ -207,21 +207,21 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, LR[i][j].dx = dr; LR[i][j].inv_dx = control->tabulate / control->nonb_cut; LR[i][j].y = (LR_data*) - smalloc( LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); + smalloc(lmp, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); LR[i][j].H = (cubic_spline_coef*) - smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , + smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , comm ); LR[i][j].vdW = (cubic_spline_coef*) - smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", + smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", comm); LR[i][j].CEvd = (cubic_spline_coef*) - smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", + smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", comm); LR[i][j].ele = (cubic_spline_coef*) - smalloc( LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", + smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", comm ); LR[i][j].CEclmb = (cubic_spline_coef*) - smalloc( LR[i][j].n*sizeof(cubic_spline_coef), + smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef), "lookup:LR[i,j].CEclmb", comm ); for( r = 1; r <= control->tabulate; ++r ) { @@ -246,22 +246,22 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, vlast_vdw = fCEvd[r-1]; vlast_ele = fele[r-1]; - Natural_Cubic_Spline( &h[1], &fh[1], + Natural_Cubic_Spline( lmp, &h[1], &fh[1], &(LR[i][j].H[1]), control->tabulate+1, comm ); - Complete_Cubic_Spline( &h[1], &fvdw[1], v0_vdw, vlast_vdw, + Complete_Cubic_Spline( lmp, &h[1], &fvdw[1], v0_vdw, vlast_vdw, &(LR[i][j].vdW[1]), control->tabulate+1, comm ); - Natural_Cubic_Spline( &h[1], &fCEvd[1], + Natural_Cubic_Spline( lmp, &h[1], &fCEvd[1], &(LR[i][j].CEvd[1]), control->tabulate+1, comm ); - Complete_Cubic_Spline( &h[1], &fele[1], v0_ele, vlast_ele, + Complete_Cubic_Spline( lmp, &h[1], &fele[1], v0_ele, vlast_ele, &(LR[i][j].ele[1]), control->tabulate+1, comm ); - Natural_Cubic_Spline( &h[1], &fCEclmb[1], + Natural_Cubic_Spline( lmp, &h[1], &fCEclmb[1], &(LR[i][j].CEclmb[1]), control->tabulate+1, comm ); } else { @@ -281,7 +281,7 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, } -void Deallocate_Lookup_Tables( reax_system *system ) +void Deallocate_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system ) { int i, j; int ntypes; @@ -291,14 +291,14 @@ void Deallocate_Lookup_Tables( reax_system *system ) for( i = 0; i < ntypes; ++i ) { for( j = i; j < ntypes; ++j ) if (LR[i][j].n) { - sfree( LR[i][j].y, "LR[i,j].y" ); - sfree( LR[i][j].H, "LR[i,j].H" ); - sfree( LR[i][j].vdW, "LR[i,j].vdW" ); - sfree( LR[i][j].CEvd, "LR[i,j].CEvd" ); - sfree( LR[i][j].ele, "LR[i,j].ele" ); - sfree( LR[i][j].CEclmb, "LR[i,j].CEclmb" ); + sfree(lmp, LR[i][j].y, "LR[i,j].y" ); + sfree(lmp, LR[i][j].H, "LR[i,j].H" ); + sfree(lmp, LR[i][j].vdW, "LR[i,j].vdW" ); + sfree(lmp, LR[i][j].CEvd, "LR[i,j].CEvd" ); + sfree(lmp, LR[i][j].ele, "LR[i,j].ele" ); + sfree(lmp, LR[i][j].CEclmb, "LR[i,j].CEclmb" ); } - sfree( LR[i], "LR[i]" ); + sfree(lmp, LR[i], "LR[i]" ); } - sfree( LR, "LR" ); + sfree(lmp, LR, "LR" ); } diff --git a/src/USER-REAXC/reaxc_lookup.h b/src/USER-REAXC/reaxc_lookup.h index 66fa3c407c..2d33ad82de 100644 --- a/src/USER-REAXC/reaxc_lookup.h +++ b/src/USER-REAXC/reaxc_lookup.h @@ -32,17 +32,17 @@ void Tridiagonal_Solve( const double *a, const double *b, double *c, double *d, double *x, unsigned int n); -void Natural_Cubic_Spline( const double *h, const double *f, +void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS*, const double *h, const double *f, cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ); -void Complete_Cubic_Spline( const double *h, const double *f, double v0, double vlast, +void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS*, const double *h, const double *f, double v0, double vlast, cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ); -int Init_Lookup_Tables( reax_system*, control_params*, storage*, +int Init_Lookup_Tables( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, storage*, mpi_datatypes*, char* ); -void Deallocate_Lookup_Tables( reax_system* ); +void Deallocate_Lookup_Tables( LAMMPS_NS::LAMMPS*, reax_system* ); #endif diff --git a/src/USER-REAXC/reaxc_multi_body.cpp b/src/USER-REAXC/reaxc_multi_body.cpp index f7d72a2678..a16c4eb42b 100644 --- a/src/USER-REAXC/reaxc_multi_body.cpp +++ b/src/USER-REAXC/reaxc_multi_body.cpp @@ -32,7 +32,7 @@ void Atom_Energy( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, - output_controls * /*out_control*/ ) + output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp ) { int i, j, pj, type_i, type_j; double Delta_lpcorr, dfvl; diff --git a/src/USER-REAXC/reaxc_multi_body.h b/src/USER-REAXC/reaxc_multi_body.h index a17c9f484e..dc2c1040eb 100644 --- a/src/USER-REAXC/reaxc_multi_body.h +++ b/src/USER-REAXC/reaxc_multi_body.h @@ -30,6 +30,6 @@ #include "reaxc_types.h" void Atom_Energy( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls* ); + storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); #endif diff --git a/src/USER-REAXC/reaxc_reset_tools.cpp b/src/USER-REAXC/reaxc_reset_tools.cpp index d9cb5f22fe..49a9f096dd 100644 --- a/src/USER-REAXC/reaxc_reset_tools.cpp +++ b/src/USER-REAXC/reaxc_reset_tools.cpp @@ -144,10 +144,10 @@ void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system *system, control_params *con if (total_bonds >= bonds->num_intrs * DANGER_ZONE) { workspace->realloc.bonds = 1; if (total_bonds >= bonds->num_intrs) { - fprintf(stderr, - "p%d: not enough space for bonds! total=%d allocated=%d\n", - system->my_rank, total_bonds, bonds->num_intrs ); - lmp->error->all(FLERR, "Can't allocate space for hbonds."); + char errmsg[256]; + snprintf(errmsg, 256, "p%d: not enough space for bonds! total=%d allocated=%d\n", + system->my_rank, total_bonds, bonds->num_intrs); + lmp->error->one(FLERR, errmsg); } } } @@ -170,10 +170,10 @@ void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system *system, control_params *con if (total_hbonds >= hbonds->num_intrs * 0.90/*DANGER_ZONE*/) { workspace->realloc.hbonds = 1; if (total_hbonds >= hbonds->num_intrs) { - fprintf(stderr, - "p%d: not enough space for hbonds! total=%d allocated=%d\n", - system->my_rank, total_hbonds, hbonds->num_intrs ); - lmp->error->all(FLERR, "Can't allocate space for hbonds."); + char errmsg[256]; + snprintf(errmsg, 256, "p%d: not enough space for hbonds! total=%d allocated=%d\n", + system->my_rank, total_hbonds, hbonds->num_intrs); + lmp->error->one(FLERR, errmsg); } } } diff --git a/src/USER-REAXC/reaxc_tool_box.cpp b/src/USER-REAXC/reaxc_tool_box.cpp index 9e662e7a45..eaa6765f36 100644 --- a/src/USER-REAXC/reaxc_tool_box.cpp +++ b/src/USER-REAXC/reaxc_tool_box.cpp @@ -53,23 +53,25 @@ int Tokenize( char* s, char*** tok ) return count; } + + /* safe malloc */ -void *smalloc( rc_bigint n, const char *name, MPI_Comm comm ) +void *smalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, const char *name, MPI_Comm comm ) { void *ptr; + char errmsg[256]; if (n <= 0) { - fprintf( stderr, "WARNING: trying to allocate %ld bytes for array %s. ", - n, name ); - fprintf( stderr, "returning NULL.\n" ); + snprintf(errmsg, 256, "Trying to allocate %ld bytes for array %s. " + "returning NULL.", n, name); + lmp->error->warning(FLERR,errmsg); return NULL; } ptr = malloc( n ); if (ptr == NULL) { - fprintf( stderr, "ERROR: failed to allocate %ld bytes for array %s", - n, name ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n, name); + lmp->error->one(FLERR,errmsg); } return ptr; @@ -77,29 +79,30 @@ void *smalloc( rc_bigint n, const char *name, MPI_Comm comm ) /* safe calloc */ -void *scalloc( rc_bigint n, rc_bigint size, const char *name, MPI_Comm comm ) +void *scalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, rc_bigint size, const char *name, MPI_Comm comm ) { void *ptr; + char errmsg[256]; if (n <= 0) { - fprintf( stderr, "WARNING: trying to allocate %ld elements for array %s. ", - n, name ); - fprintf( stderr, "returning NULL.\n" ); + snprintf(errmsg, 256, "Trying to allocate %ld elements for array %s. " + "returning NULL.\n", n, name ); + lmp->error->warning(FLERR,errmsg); return NULL; } if (size <= 0) { - fprintf( stderr, "WARNING: elements size for array %s is %ld. ", - name, size ); - fprintf( stderr, "returning NULL.\n" ); + snprintf(errmsg, 256, "Elements size for array %s is %ld. " + "returning NULL", name, size ); + lmp->error->warning(FLERR,errmsg); return NULL; } ptr = calloc( n, size ); if (ptr == NULL) { - fprintf( stderr, "ERROR: failed to allocate %ld bytes for array %s", - n*size, name ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + char errmsg[256]; + snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n*size, name); + lmp->error->one(FLERR,errmsg); } return ptr; @@ -107,11 +110,12 @@ void *scalloc( rc_bigint n, rc_bigint size, const char *name, MPI_Comm comm ) /* safe free */ -void sfree( void *ptr, const char *name ) +void sfree( LAMMPS_NS::LAMMPS* lmp, void *ptr, const char *name ) { if (ptr == NULL) { - fprintf( stderr, "WARNING: trying to free the already NULL pointer %s!\n", - name ); + char errmsg[256]; + snprintf(errmsg, 256, "Trying to free the already NULL pointer %s", name ); + lmp->error->one(FLERR,errmsg); return; } diff --git a/src/USER-REAXC/reaxc_tool_box.h b/src/USER-REAXC/reaxc_tool_box.h index 7f8dd455ca..7c5ab12587 100644 --- a/src/USER-REAXC/reaxc_tool_box.h +++ b/src/USER-REAXC/reaxc_tool_box.h @@ -37,7 +37,7 @@ double Get_Time( ); int Tokenize( char*, char*** ); /* from lammps */ -void *smalloc( rc_bigint, const char*, MPI_Comm ); -void *scalloc( rc_bigint, rc_bigint, const char*, MPI_Comm ); -void sfree( void*, const char* ); +void *smalloc( LAMMPS_NS::LAMMPS*, rc_bigint, const char*, MPI_Comm ); +void *scalloc( LAMMPS_NS::LAMMPS*, rc_bigint, rc_bigint, const char*, MPI_Comm ); +void sfree( LAMMPS_NS::LAMMPS*, void*, const char* ); #endif diff --git a/src/USER-REAXC/reaxc_torsion_angles.cpp b/src/USER-REAXC/reaxc_torsion_angles.cpp index ed76368d68..50c3412928 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.cpp +++ b/src/USER-REAXC/reaxc_torsion_angles.cpp @@ -120,7 +120,8 @@ double Calculate_Omega( rvec dvec_ij, double r_ij, void Torsion_Angles( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls *out_control ) + reax_list **lists, output_controls *out_control, + LAMMPS_NS::LAMMPS* lmp ) { int i, j, k, l, pi, pj, pk, pl, pij, plk, natoms; int type_i, type_j, type_k, type_l; diff --git a/src/USER-REAXC/reaxc_torsion_angles.h b/src/USER-REAXC/reaxc_torsion_angles.h index 755e8c6532..38236cb7dc 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.h +++ b/src/USER-REAXC/reaxc_torsion_angles.h @@ -30,6 +30,7 @@ #include "reaxc_types.h" void Torsion_Angles( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls* ); + storage*, reax_list**, output_controls*, + LAMMPS_NS::LAMMPS* = NULL ); #endif diff --git a/src/USER-REAXC/reaxc_traj.cpp b/src/USER-REAXC/reaxc_traj.cpp index 54d8b3219c..ee2939d662 100644 --- a/src/USER-REAXC/reaxc_traj.cpp +++ b/src/USER-REAXC/reaxc_traj.cpp @@ -29,7 +29,7 @@ #include "reaxc_list.h" #include "reaxc_tool_box.h" -int Reallocate_Output_Buffer( output_controls *out_control, int req_space, +int Reallocate_Output_Buffer( LAMMPS_NS::LAMMPS *lmp, output_controls *out_control, int req_space, MPI_Comm comm ) { if (out_control->buffer_len > 0) @@ -38,10 +38,9 @@ int Reallocate_Output_Buffer( output_controls *out_control, int req_space, out_control->buffer_len = (int)(req_space*SAFE_ZONE); out_control->buffer = (char*) malloc(out_control->buffer_len*sizeof(char)); if (out_control->buffer == NULL) { - fprintf( stderr, - "insufficient memory for required buffer size %d. terminating!\n", - (int) (req_space*SAFE_ZONE) ); - MPI_Abort( comm, INSUFFICIENT_MEMORY ); + char errmsg[256]; + snprintf(errmsg, 256, "Insufficient memory for required buffer size %d", (int) (req_space*SAFE_ZONE)); + lmp->error->one(FLERR,errmsg); } return SUCCESS; @@ -57,7 +56,7 @@ void Write_Skip_Line( output_controls *out_control, mpi_datatypes * /*mpi_data*/ } -int Write_Header( reax_system *system, control_params *control, +int Write_Header( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, output_controls *out_control, mpi_datatypes *mpi_data ) { int num_hdr_lines, my_hdr_lines, buffer_req; @@ -83,7 +82,7 @@ int Write_Header( reax_system *system, control_params *control, my_hdr_lines = num_hdr_lines * ( system->my_rank == MASTER_NODE ); buffer_req = my_hdr_lines * HEADER_LINE_LEN; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); /* only the master node writes into trajectory header */ if (system->my_rank == MASTER_NODE) { @@ -259,7 +258,7 @@ int Write_Header( reax_system *system, control_params *control, } -int Write_Init_Desc( reax_system *system, control_params * /*control*/, +int Write_Init_Desc( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params * /*control*/, output_controls *out_control, mpi_datatypes *mpi_data ) { int i, me, np, cnt, buffer_len, buffer_req; @@ -278,7 +277,7 @@ int Write_Init_Desc( reax_system *system, control_params * /*control*/, else buffer_req = system->n * INIT_DESC_LEN + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); out_control->line[0] = 0; out_control->buffer[0] = 0; @@ -311,7 +310,7 @@ int Write_Init_Desc( reax_system *system, control_params * /*control*/, } -int Init_Traj( reax_system *system, control_params *control, +int Init_Traj( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, output_controls *out_control, mpi_datatypes *mpi_data, char *msg ) { @@ -348,14 +347,14 @@ int Init_Traj( reax_system *system, control_params *control, strcpy( msg, "init_traj: unknown trajectory option" ); return FAILURE; } - Write_Header( system, control, out_control, mpi_data ); - Write_Init_Desc( system, control, out_control, mpi_data ); + Write_Header( lmp, system, control, out_control, mpi_data ); + Write_Init_Desc( lmp, system, control, out_control, mpi_data ); return SUCCESS; } -int Write_Frame_Header( reax_system *system, control_params *control, +int Write_Frame_Header( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -367,7 +366,7 @@ int Write_Frame_Header( reax_system *system, control_params *control, my_frm_hdr_lines = num_frm_hdr_lines * ( me == MASTER_NODE ); buffer_req = my_frm_hdr_lines * HEADER_LINE_LEN; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); /* only the master node writes into trajectory header */ if (me == MASTER_NODE) { @@ -481,7 +480,7 @@ int Write_Frame_Header( reax_system *system, control_params *control, -int Write_Atoms( reax_system *system, control_params * /*control*/, +int Write_Atoms( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * /*control*/, output_controls *out_control, mpi_datatypes *mpi_data ) { int i, me, np, line_len, buffer_len, buffer_req, cnt; @@ -500,7 +499,7 @@ int Write_Atoms( reax_system *system, control_params * /*control*/, else buffer_req = system->n * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); /* fill in buffer */ out_control->line[0] = 0; @@ -531,9 +530,7 @@ int Write_Atoms( reax_system *system, control_params * /*control*/, p_atom->f[0], p_atom->f[1], p_atom->f[2], p_atom->q ); break; default: - fprintf( stderr, - "write_traj_atoms: unknown atom trajectroy format!\n"); - MPI_Abort( mpi_data->world, UNKNOWN_OPTION ); + lmp->error->all(FLERR,"Write_traj_atoms: unknown atom trajectory format"); } strncpy( out_control->buffer + i*line_len, out_control->line, line_len+1 ); @@ -559,7 +556,7 @@ int Write_Atoms( reax_system *system, control_params * /*control*/, } -int Write_Bonds(reax_system *system, control_params *control, reax_list *bonds, +int Write_Bonds( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, reax_list *bonds, output_controls *out_control, mpi_datatypes *mpi_data) { int i, j, pj, me, np; @@ -592,7 +589,7 @@ int Write_Bonds(reax_system *system, control_params *control, reax_list *bonds, else buffer_req = my_bonds * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); /* fill in the buffer */ out_control->line[0] = 0; @@ -619,8 +616,7 @@ int Write_Bonds(reax_system *system, control_params *control, reax_list *bonds, bo_ij->bo_data.BO_pi, bo_ij->bo_data.BO_pi2 ); break; default: - fprintf(stderr, "write_traj_bonds: FATAL! invalid bond_info option"); - MPI_Abort( mpi_data->world, UNKNOWN_OPTION ); + lmp->error->all(FLERR, "Write_traj_bonds: FATAL! invalid bond_info option"); } strncpy( out_control->buffer + my_bonds*line_len, out_control->line, line_len+1 ); @@ -649,7 +645,7 @@ int Write_Bonds(reax_system *system, control_params *control, reax_list *bonds, } -int Write_Angles( reax_system *system, control_params *control, +int Write_Angles( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, reax_list *bonds, reax_list *thb_intrs, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -693,7 +689,7 @@ int Write_Angles( reax_system *system, control_params *control, else buffer_req = my_angles * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); /* fill in the buffer */ my_angles = 0; @@ -744,20 +740,20 @@ int Write_Angles( reax_system *system, control_params *control, } -int Append_Frame( reax_system *system, control_params *control, +int Append_Frame( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, simulation_data *data, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { - Write_Frame_Header( system, control, data, out_control, mpi_data ); + Write_Frame_Header( lmp, system, control, data, out_control, mpi_data ); if (out_control->write_atoms) - Write_Atoms( system, control, out_control, mpi_data ); + Write_Atoms( lmp, system, control, out_control, mpi_data ); if (out_control->write_bonds) - Write_Bonds( system, control, (*lists + BONDS), out_control, mpi_data ); + Write_Bonds( lmp, system, control, (*lists + BONDS), out_control, mpi_data ); if (out_control->write_angles) - Write_Angles( system, control, (*lists + BONDS), (*lists + THREE_BODIES), + Write_Angles( lmp, system, control, (*lists + BONDS), (*lists + THREE_BODIES), out_control, mpi_data ); return SUCCESS; diff --git a/src/USER-REAXC/reaxc_traj.h b/src/USER-REAXC/reaxc_traj.h index 72c56637eb..5508d27cdb 100644 --- a/src/USER-REAXC/reaxc_traj.h +++ b/src/USER-REAXC/reaxc_traj.h @@ -73,11 +73,11 @@ enum BOND_LINE_OPTS { OPT_NOBOND, OPT_BOND_BASIC, OPT_BOND_FULL, NR_OPT_BOND }; enum ANGLE_LINE_OPTS { OPT_NOANGLE, OPT_ANGLE_BASIC, NR_OPT_ANGLE }; -int Init_Traj( reax_system*, control_params*, output_controls*, +int Init_Traj( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, output_controls*, mpi_datatypes*, char* ); int End_Traj( int, output_controls* ); -int Append_Frame( reax_system*, control_params*, simulation_data*, +int Append_Frame( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, simulation_data*, reax_list**, output_controls*, mpi_datatypes* ); #endif diff --git a/src/USER-REAXC/reaxc_types.h b/src/USER-REAXC/reaxc_types.h index 2666fcf85c..cf6d5dcddc 100644 --- a/src/USER-REAXC/reaxc_types.h +++ b/src/USER-REAXC/reaxc_types.h @@ -39,6 +39,9 @@ #include #include "accelerator_kokkos.h" +#include "lammps.h" +#include "error.h" + #if defined LMP_USER_OMP #define OMP_TIMING 0 @@ -899,9 +902,9 @@ typedef void (*evolve_function)(reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes* ); -typedef void (*interaction_function) (reax_system*, control_params*, +typedef void (*interaction_function) ( reax_system*, control_params*, simulation_data*, storage*, - reax_list**, output_controls*); + reax_list**, output_controls*, LAMMPS_NS::LAMMPS*); typedef void (*print_interaction)(reax_system*, control_params*, simulation_data*, storage*, diff --git a/src/USER-REAXC/reaxc_valence_angles.cpp b/src/USER-REAXC/reaxc_valence_angles.cpp index af1f1f8003..d762dc1611 100644 --- a/src/USER-REAXC/reaxc_valence_angles.cpp +++ b/src/USER-REAXC/reaxc_valence_angles.cpp @@ -76,7 +76,7 @@ void Calculate_dCos_Theta( rvec dvec_ji, double d_ji, rvec dvec_jk, double d_jk, void Valence_Angles( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls * /*out_control*/ ) + reax_list **lists, output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp) { int i, j, pi, k, pk, t; int type_i, type_j, type_k; @@ -405,9 +405,10 @@ void Valence_Angles( reax_system *system, control_params *control, if (num_thb_intrs >= thb_intrs->num_intrs * DANGER_ZONE) { workspace->realloc.num_3body = num_thb_intrs; if (num_thb_intrs > thb_intrs->num_intrs) { - fprintf( stderr, "step%d-ran out of space on angle_list: top=%d, max=%d", - data->step, num_thb_intrs, thb_intrs->num_intrs ); - MPI_Abort( MPI_COMM_WORLD, INSUFFICIENT_MEMORY ); + char errmsg[128]; + snprintf(errmsg, 128, "step%d-ran out of space on angle_list: top=%d, max=%d", + data->step, num_thb_intrs, thb_intrs->num_intrs); + lmp->error->one(FLERR, errmsg); } } diff --git a/src/USER-REAXC/reaxc_valence_angles.h b/src/USER-REAXC/reaxc_valence_angles.h index 31936ba190..27bda3ba09 100644 --- a/src/USER-REAXC/reaxc_valence_angles.h +++ b/src/USER-REAXC/reaxc_valence_angles.h @@ -30,7 +30,7 @@ #include "reaxc_types.h" void Valence_Angles( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls* ); + storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL); void Calculate_Theta( rvec, double, rvec, double, double*, double* ); -- GitLab From 75ddde438c13cf32564a9271c03d6867c5db92bc Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 12 Mar 2019 14:38:49 -0600 Subject: [PATCH 0221/1243] Commit JT 031219 - correct errors in fix_prec_spin - clean version of spinmin --- src/REPLICA/fix_neb_spin.cpp | 3 +- src/SPIN/fix_precession_spin.cpp | 10 +- src/SPIN/min_spinmin.cpp | 240 +++++++++---------------------- src/SPIN/min_spinmin.h | 4 +- src/min.cpp | 8 ++ src/min.h | 5 + 6 files changed, 85 insertions(+), 185 deletions(-) diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index 42450c2f0f..7a72936200 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -337,7 +337,8 @@ void FixNEB_spin::min_post_force(int /*vflag*/) //printf("test veng: %g / %g / %g \n",veng,vprev,vnext); //error->universe_all(FLERR,"End test"); - if (FreeEndFinal && ireplica == nreplica-1 && (update->ntimestep == 0)) EFinalIni = veng; + if (FreeEndFinal && ireplica == nreplica-1 && (update->ntimestep == 0)) + EFinalIni = veng; if (ireplica == 0) vIni=veng; diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index 08e4fd5a63..433a260e83 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -173,8 +173,6 @@ void FixPrecessionSpin::setup(int vflag) void FixPrecessionSpin::post_force(int /*vflag*/) { - printf("test inside post force (precession) \n"); - // update mag field with time (potential improvement) if (varflag != CONSTANT) { @@ -204,7 +202,7 @@ void FixPrecessionSpin::post_force(int /*vflag*/) if (aniso_flag) { // compute magnetic anisotropy compute_anisotropy(spi,fmi); - emag -= (spi[0]*fmi[0] + spi[1]*fmi[1] + spi[2]*fmi[2]); + emag -= 0.5*(spi[0]*fmi[0] + spi[1]*fmi[1] + spi[2]*fmi[2]); } fm[i][0] += fmi[0]; @@ -232,9 +230,9 @@ void FixPrecessionSpin::compute_single_precession(int i, double spi[3], double f void FixPrecessionSpin::compute_zeeman(int i, double fmi[3]) { double **sp = atom->sp; - fmi[0] -= sp[i][3]*hx; - fmi[1] -= sp[i][3]*hy; - fmi[2] -= sp[i][3]*hz; + fmi[0] += sp[i][0]*hx; + fmi[1] += sp[i][1]*hy; + fmi[2] += sp[i][3]*hz; } /* ---------------------------------------------------------------------- */ diff --git a/src/SPIN/min_spinmin.cpp b/src/SPIN/min_spinmin.cpp index 2e03086bf0..cdd0d45287 100644 --- a/src/SPIN/min_spinmin.cpp +++ b/src/SPIN/min_spinmin.cpp @@ -46,14 +46,13 @@ MinSpinMin::MinSpinMin(LAMMPS *lmp) : Min(lmp) {} void MinSpinMin::init() { + alpha_damp = 1.0; + discret_factor = 10.0; + Min::init(); - dt = update->dt; + dts = dt = update->dt; last_negative = update->ntimestep; - - // test dts - dts = dt; - } /* ---------------------------------------------------------------------- */ @@ -94,8 +93,7 @@ void MinSpinMin::reset_vectors() int MinSpinMin::iterate(int maxiter) { bigint ntimestep; - //double vmax,vdotf,vdotfall,fdotf,fdotfall,scale; - //double dtvone,dtv,dtf,dtfm; + double fmdotfm,fmdotfmall; int flag,flagall; for (int iter = 0; iter < maxiter; iter++) { @@ -114,106 +112,6 @@ int MinSpinMin::iterate(int maxiter) advance_spins(dts); - - //// zero velocity if anti-parallel to force - //// else project velocity in direction of force - - //double **v = atom->v; - //double **f = atom->f; - //int nlocal = atom->nlocal; - - //vdotf = 0.0; - //for (int i = 0; i < nlocal; i++) - // vdotf += v[i][0]*f[i][0] + v[i][1]*f[i][1] + v[i][2]*f[i][2]; - //MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,world); - - // sum vdotf over replicas, if necessary - // this communicator would be invalid for multiprocess replicas - - //if (update->multireplica == 1) { - // vdotf = vdotfall; - // MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld); - //} - - //if (vdotfall < 0.0) { - // last_negative = ntimestep; - // for (int i = 0; i < nlocal; i++) - // v[i][0] = v[i][1] = v[i][2] = 0.0; - - //} else { - // fdotf = 0.0; - // for (int i = 0; i < nlocal; i++) - // fdotf += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; - // MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,world); - - // // sum fdotf over replicas, if necessary - // // this communicator would be invalid for multiprocess replicas - - // if (update->multireplica == 1) { - // fdotf = fdotfall; - // MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld); - // } - - // if (fdotfall == 0.0) scale = 0.0; - // else scale = vdotfall/fdotfall; - // for (int i = 0; i < nlocal; i++) { - // v[i][0] = scale * f[i][0]; - // v[i][1] = scale * f[i][1]; - // v[i][2] = scale * f[i][2]; - // } - //} - - //// limit timestep so no particle moves further than dmax - - //double *rmass = atom->rmass; - //double *mass = atom->mass; - //int *type = atom->type; - - //dtvone = dt; - - //for (int i = 0; i < nlocal; i++) { - // vmax = MAX(fabs(v[i][0]),fabs(v[i][1])); - // vmax = MAX(vmax,fabs(v[i][2])); - // if (dtvone*vmax > dmax) dtvone = dmax/vmax; - //} - //MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,world); - - //// min dtv over replicas, if necessary - //// this communicator would be invalid for multiprocess replicas - - //if (update->multireplica == 1) { - // dtvone = dtv; - // MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,universe->uworld); - //} - - //dtf = dtv * force->ftm2v; - - //// Euler integration step - - //double **x = atom->x; - - //if (rmass) { - // for (int i = 0; i < nlocal; i++) { - // dtfm = dtf / rmass[i]; - // x[i][0] += dtv * v[i][0]; - // x[i][1] += dtv * v[i][1]; - // x[i][2] += dtv * v[i][2]; - // v[i][0] += dtfm * f[i][0]; - // v[i][1] += dtfm * f[i][1]; - // v[i][2] += dtfm * f[i][2]; - // } - //} else { - // for (int i = 0; i < nlocal; i++) { - // dtfm = dtf / mass[type[i]]; - // x[i][0] += dtv * v[i][0]; - // x[i][1] += dtv * v[i][1]; - // x[i][2] += dtv * v[i][2]; - // v[i][0] += dtfm * f[i][0]; - // v[i][1] += dtfm * f[i][1]; - // v[i][2] += dtfm * f[i][2]; - // } - //} - eprevious = ecurrent; ecurrent = energy_force(0); neval++; @@ -237,37 +135,22 @@ int MinSpinMin::iterate(int maxiter) } } - //// magnetic force tolerance criterion - //// sync across replicas if running multi-replica minimization + // magnetic torque tolerance criterion + // sync across replicas if running multi-replica minimization - //if (update->fmtol > 0.0) { - // fmdotfm = fmnorm_sqr(); - // if (update->multireplica == 0) { - // if (fmdotfm < update->fmtol*update->fmtol) return FTOL; - // } else { - // if (fmdotfm < update->fmtol*update->fmtol) flag = 0; - // else flag = 1; - // MPI_Allreduce(&fmlag,&fmlagall,1,MPI_INT,MPI_SUM,universe->uworld); - // if (fmlagall == 0) return FTOL; - // } - //} - - //// force tolerance criterion - //// sync across replicas if running multi-replica minimization - - //if (update->ftol > 0.0) { - // fdotf = fnorm_sqr(); - // if (update->multireplica == 0) { - // if (fdotf < update->ftol*update->ftol) return FTOL; - // } else { - // if (fdotf < update->ftol*update->ftol) flag = 0; - // else flag = 1; - // MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); - // if (flagall == 0) return FTOL; - // } - //} + if (update->ftol > 0.0) { + fmdotfm = fmnorm_sqr(); + if (update->multireplica == 0) { + if (fmdotfm < update->ftol*update->ftol) return FTOL; + } else { + if (fmdotfm < update->ftol*update->ftol) flag = 0; + else flag = 1; + MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld); + if (flagall == 0) return FTOL; + } + } - //// output for thermo, dump, restart files + // output for thermo, dump, restart files if (output->next == ntimestep) { timer->stamp(); @@ -299,12 +182,6 @@ double MinSpinMin::evaluate_dt() fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; fmaxsqone = MAX(fmaxsqone,fmsq); } - //printf("test inside evaluate dt, fmaxsqone = %g \n",fmaxsqone); - //for (int i = 0; i < nlocal; i++) - // if (mask[i] & groupbit) { - // fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; - // fmaxsqone = MAX(fmaxsqone,fmsq); - // } // finding max fm on this replica @@ -320,15 +197,13 @@ double MinSpinMin::evaluate_dt() MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); } - //if (fmaxsqall < fmaxsqloc) - // error->all(FLERR,"Incorrect fmaxall calc."); + if (fmaxsqall == 0.0) + error->all(FLERR,"Incorrect fmaxsqall calculation"); - // define max timestep - // dividing by 10 the inverse of max frequency - //printf("test inside evaluate dt, fmaxsqall = %g \n",fmaxsqall); + // define max timestep by dividing by the + // inverse of max frequency by discret_factor - dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); - //printf("test inside evaluate dt, dtmax = %g \n",dtmax); + dtmax = MY_2PI/(discret_factor*sqrt(fmaxsqall)); return dtmax; } @@ -345,28 +220,19 @@ void MinSpinMin::advance_spins(double dts) double **fm = atom->fm; double tdampx,tdampy,tdampz; double msq,scale,fm2,energy,dts2; - double alpha; double cp[3],g[3]; dts2 = dts*dts; - // fictitious Gilbert damping of 1 - - alpha = 1.0; - - // loop on all spins on proc. - //if (ireplica != nreplica-1 && ireplica != 0) - // for (int i = 0; i < nlocal; i++) - // if (mask[i] & groupbit) { for (int i = 0; i < nlocal; i++) { // calc. damping torque - tdampx = -alpha*(fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1]); - tdampy = -alpha*(fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); - tdampz = -alpha*(fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); + tdampx = -alpha_damp*(fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1]); + tdampy = -alpha_damp*(fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); + tdampz = -alpha_damp*(fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); // apply advance algorithm (geometric, norm preserving) @@ -401,22 +267,44 @@ void MinSpinMin::advance_spins(double dts) sp[i][1] *= scale; sp[i][2] *= scale; - // comm. sp[i] to atoms with same tag (for serial algo) - - // no need for simplecticity - //if (sector_flag == 0) { - // if (sametag[i] >= 0) { - // j = sametag[i]; - // while (j >= 0) { - // sp[j][0] = sp[i][0]; - // sp[j][1] = sp[i][1]; - // sp[j][2] = sp[i][2]; - // j = sametag[j]; - // } - // } - //} - // + // no comm. to atoms with same tag + // because no need for simplecticity } +} + +/* ---------------------------------------------------------------------- + compute and return ||mag. torque||_2^2 +------------------------------------------------------------------------- */ + +double MinSpinMin::fmnorm_sqr() +{ + int i,n; + double *fmatom; + + int nlocal = atom->nlocal; + double tx,ty,tz; + double **sp = atom->sp; + double **fm = atom->fm; + + // calc. magnetic torques + + double local_norm2_sqr = 0.0; + for (int i = 0; i < nlocal; i++) { + tx = (fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1]); + ty = (fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); + tz = (fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); + + local_norm2_sqr += tx*tx + ty*ty + tz*tz; + } + + // no extra atom calc. for spins + + if (nextra_atom) + error->all(FLERR,"extra atom option not available yet"); + + double norm2_sqr = 0.0; + MPI_Allreduce(&local_norm2_sqr,&norm2_sqr,1,MPI_DOUBLE,MPI_SUM,world); + return norm2_sqr; } diff --git a/src/SPIN/min_spinmin.h b/src/SPIN/min_spinmin.h index 943b2d2749..abc532a3d5 100644 --- a/src/SPIN/min_spinmin.h +++ b/src/SPIN/min_spinmin.h @@ -34,12 +34,12 @@ class MinSpinMin : public Min { int iterate(int); double evaluate_dt(); void advance_spins(double); - - class FixNEB_spin *fneb; + double fmnorm_sqr(); private: // global and spin timesteps + double dt; double dts; diff --git a/src/min.cpp b/src/min.cpp index cd9253f8d3..c75db6e2b0 100644 --- a/src/min.cpp +++ b/src/min.cpp @@ -655,6 +655,14 @@ void Min::modify_params(int narg, char **arg) else if (strcmp(arg[iarg+1],"forcezero") == 0) linestyle = 2; else error->all(FLERR,"Illegal min_modify command"); iarg += 2; + } else if (strcmp(arg[iarg],"alpha_damp") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); + alpha_damp = force->numeric(FLERR,arg[iarg+1]); + iarg += 2; + } else if (strcmp(arg[iarg],"discret_factor") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); + discret_factor = force->numeric(FLERR,arg[iarg+1]); + iarg += 2; } else error->all(FLERR,"Illegal min_modify command"); } } diff --git a/src/min.h b/src/min.h index 92da97c664..ba1885671e 100644 --- a/src/min.h +++ b/src/min.h @@ -58,6 +58,11 @@ class Min : protected Pointers { double dmax; // max dist to move any atom in one step int linestyle; // 0 = backtrack, 1 = quadratic, 2 = forcezero + // spinmin quantities + + double alpha_damp; // damping for spin minimization + double discret_factor; // factor for spin timestep evaluation + int nelist_global,nelist_atom; // # of PE,virial computes to check int nvlist_global,nvlist_atom; class Compute **elist_global; // lists of PE,virial Computes -- GitLab From b51d06b3ea598eab8114337e136b3591a2e01582 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 12 Mar 2019 15:33:28 -0600 Subject: [PATCH 0222/1243] Change default binsize for Kokkos if running on GPUs --- src/KOKKOS/neighbor_kokkos.cpp | 9 +++++++++ src/KOKKOS/neighbor_kokkos.h | 1 + src/neighbor.cpp | 3 +++ src/neighbor.h | 1 + 4 files changed, 14 insertions(+) diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index 6cd5c4e6e5..7aaeda4b37 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -30,6 +30,7 @@ #include "style_nstencil.h" #include "style_npair.h" #include "style_ntopo.h" +#include "comm.h" using namespace LAMMPS_NS; @@ -359,6 +360,14 @@ void NeighborKokkos::modify_mol_intra_grow_kokkos(){ k_ex_mol_intra.modify(); } +/* ---------------------------------------------------------------------- */ +void NeighborKokkos::set_binsize_kokkos() { + if (!binsizeflag && lmp->kokkos->ngpu > 0) { + binsize_user = cutneighmax; + binsizeflag = 1; + } +} + /* ---------------------------------------------------------------------- */ void NeighborKokkos::init_topology() { diff --git a/src/KOKKOS/neighbor_kokkos.h b/src/KOKKOS/neighbor_kokkos.h index 5c98c4d26d..3829502c0d 100644 --- a/src/KOKKOS/neighbor_kokkos.h +++ b/src/KOKKOS/neighbor_kokkos.h @@ -87,6 +87,7 @@ class NeighborKokkos : public Neighbor { void modify_ex_group_grow_kokkos(); void modify_mol_group_grow_kokkos(); void modify_mol_intra_grow_kokkos(); + void set_binsize_kokkos(); }; } diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 84494bfbc5..2dc65541e4 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -471,6 +471,9 @@ void Neighbor::init() error->warning(FLERR,"Neighbor exclusions used with KSpace solver " "may give inconsistent Coulombic energies"); + if (lmp->kokkos) + set_binsize_kokkos(); + // ------------------------------------------------------------------ // create pairwise lists // one-time call to init_styles() to scan style files and setup diff --git a/src/neighbor.h b/src/neighbor.h index 751beeae4b..ffe181313b 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -233,6 +233,7 @@ class Neighbor : protected Pointers { virtual void init_ex_bit_kokkos() {} virtual void init_ex_mol_bit_kokkos() {} virtual void grow_ex_mol_intra_kokkos() {} + virtual void set_binsize_kokkos() {} }; namespace NeighConst { -- GitLab From 0d73fe99fd94c35a3c894c4ab1d4c26ec51aea5b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 12 Mar 2019 15:34:12 -0600 Subject: [PATCH 0223/1243] Update Kokkos docs --- doc/src/Speed_kokkos.txt | 4 ++-- doc/src/package.txt | 44 ++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/src/Speed_kokkos.txt b/doc/src/Speed_kokkos.txt index ef193d7401..d04f8ac6f1 100644 --- a/doc/src/Speed_kokkos.txt +++ b/doc/src/Speed_kokkos.txt @@ -242,13 +242,13 @@ pairwise and bonded interactions, along with threaded communication. When running on Maxwell or Kepler GPUs, this will typically be best. For Pascal GPUs, using "half" neighbor lists and setting the Newton flag to "on" may be faster. For many pair styles, setting the -neighbor binsize equal to the ghost atom cutoff will give speedup. +neighbor binsize equal to twice the CPU default value will give speedup, +which is the default when running on GPUs. Use the "-pk kokkos" "command-line switch"_Run_options.html to change the default "package kokkos"_package.html options. See its doc page for details and default settings. Experimenting with its options can provide a speed-up for specific calculations. For example: -mpirun -np 2 lmp_kokkos_cuda_openmpi -k on g 2 -sf kk -pk kokkos binsize 2.8 -in in.lj # Set binsize = neighbor ghost cutoff mpirun -np 2 lmp_kokkos_cuda_openmpi -k on g 2 -sf kk -pk kokkos newton on neigh half binsize 2.8 -in in.lj # Newton on, half neighbor list, set binsize = neighbor ghost cutoff :pre NOTE: For good performance of the KOKKOS package on GPUs, you must diff --git a/doc/src/package.txt b/doc/src/package.txt index c226d7942f..89cfd03f5f 100644 --- a/doc/src/package.txt +++ b/doc/src/package.txt @@ -450,20 +450,20 @@ computation is done, but less communication. However, when running in MPI-only mode with 1 thread per MPI task, a value of {on} will typically be faster, just as it is for non-accelerated pair styles. -The {binsize} keyword sets the size of bins used to bin atoms in -neighbor list builds. The same value can be set by the "neigh_modify -binsize"_neigh_modify.html command. Making it an option in the -package kokkos command allows it to be set from the command line. The -default value is 0.0, which means the LAMMPS default will be used, -which is bins = 1/2 the size of the pairwise cutoff + neighbor skin -distance. This is fine when neighbor lists are built on the CPU. For -GPU builds, a 2x larger binsize equal to the pairwise cutoff + -neighbor skin, is often faster, which can be set by this keyword. -Note that if you use a longer-than-usual pairwise cutoff, e.g. to -allow for a smaller fraction of KSpace work with a "long-range -Coulombic solver"_kspace_style.html because the GPU is faster at -performing pairwise interactions, then this rule of thumb may give too -large a binsize. +The {binsize} keyword sets the size of bins used to bin atoms in +neighbor list builds. The same value can be set by the "neigh_modify +binsize"_neigh_modify.html command. Making it an option in the package +kokkos command allows it to be set from the command line. The default +value for CPUs is 0.0, which means the LAMMPS default will be used, +which is bins = 1/2 the size of the pairwise cutoff + neighbor skin +distance. This is fine when neighbor lists are built on the CPU. For GPU +builds, a 2x larger binsize equal to the pairwise cutoff + neighbor skin +is often faster, which is the default. Note that if you use a +longer-than-usual pairwise cutoff, e.g. to allow for a smaller fraction +of KSpace work with a "long-range Coulombic solver"_kspace_style.html +because the GPU is faster at performing pairwise interactions, then this +rule of thumb may give too large a binsize and the default should be +overridden with a smaller value. The {comm} and {comm/exchange} and {comm/forward} and {comm/reverse} keywords determine whether the host or device performs the packing and unpacking of data @@ -623,14 +623,14 @@ not used, you must invoke the package intel command in your input script or or via the "-pk intel" "command-line switch"_Run_options.html. -For the KOKKOS package, the option defaults neigh = full, neigh/qeq = -full, newton = off, binsize = 0.0, and comm = device, gpu/direct = on. -When LAMMPS can safely detect, that GPU-direct is not available, the -default value of gpu/direct becomes "off". -These settings are made automatically by the required "-k on" -"command-line switch"_Run_options.html. You can change them by -using the package kokkos command in your input script or via the -"-pk kokkos command-line switch"_Run_options.html. +For the KOKKOS package, the option defaults neigh = full, neigh/qeq = +full, newton = off, binsize for CPUs = 0.0, binsize for GPUs = 2x LAMMPS +default value, and comm = device, gpu/direct = on. When LAMMPS can +safely detect, that GPU-direct is not available, the default value of +gpu/direct becomes "off". These settings are made automatically by the +required "-k on" "command-line switch"_Run_options.html. You can change +them by using the package kokkos command in your input script or via the +"-pk kokkos command-line switch"_Run_options.html. For the OMP package, the default is Nthreads = 0 and the option defaults are neigh = yes. These settings are made automatically if -- GitLab From f6fb8b220d3b436d8ae003a62aa094f80f166d2e Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 12 Mar 2019 16:59:13 -0600 Subject: [PATCH 0224/1243] Commit 2 JT 031219 - modified examples (gneb and spinmin now distinct) - started documention for spinmin --- doc/src/min_modify.txt | 11 +- doc/src/min_style.txt | 15 +- examples/SPIN/{gneb_bfo => gneb}/README | 0 .../SPIN/{gneb_bfo => gneb}/final.iron_spin | 0 examples/SPIN/{gneb_bfo => gneb}/in.gneb.iron | 0 .../SPIN/{gneb_bfo => gneb}/initial.iron_spin | 0 .../SPIN/{gneb_bfo => spinmin}/in.spinmin.bfo | 14 +- .../{gneb_bfo => spinmin}/in.spinmin.iron | 21 +-- src/REPLICA/fix_neb_spin.cpp | 144 ------------------ 9 files changed, 42 insertions(+), 163 deletions(-) rename examples/SPIN/{gneb_bfo => gneb}/README (100%) rename examples/SPIN/{gneb_bfo => gneb}/final.iron_spin (100%) rename examples/SPIN/{gneb_bfo => gneb}/in.gneb.iron (100%) rename examples/SPIN/{gneb_bfo => gneb}/initial.iron_spin (100%) rename examples/SPIN/{gneb_bfo => spinmin}/in.spinmin.bfo (78%) rename examples/SPIN/{gneb_bfo => spinmin}/in.spinmin.iron (62%) diff --git a/doc/src/min_modify.txt b/doc/src/min_modify.txt index 9408eea167..bb5ad513c1 100644 --- a/doc/src/min_modify.txt +++ b/doc/src/min_modify.txt @@ -13,11 +13,15 @@ min_modify command :h3 min_modify keyword values ... :pre one or more keyword/value pairs may be listed :ulb,l -keyword = {dmax} or {line} +keyword = {dmax} or {line} or {alpha_damp} or {discret_factor} {dmax} value = max max = maximum distance for line search to move (distance units) {line} value = {backtrack} or {quadratic} or {forcezero} - backtrack,quadratic,forcezero = style of linesearch to use :pre + backtrack,quadratic,forcezero = style of linesearch to use + {alpha_damp} value = damping + damping = fictitious Gilbert damping for spin minimization (adim) + {discret_factor} value = factor + factor = defines a dividing factor for adaptive spin timestep (adim) :pre :ule [Examples:] @@ -65,6 +69,9 @@ difference of two large values (energy before and energy after) and that difference may be smaller than machine epsilon even if atoms could move in the gradient direction to reduce forces further. +Keywords {alpha_damp} and {discret_factor} only make sense when +a {spinmin} minimization style is declared. + [Restrictions:] none [Related commands:] diff --git a/doc/src/min_style.txt b/doc/src/min_style.txt index 4948a34864..b1a9da997d 100644 --- a/doc/src/min_style.txt +++ b/doc/src/min_style.txt @@ -11,11 +11,12 @@ min_style command :h3 min_style style :pre -style = {cg} or {hftn} or {sd} or {quickmin} or {fire} :ul +style = {cg} or {hftn} or {sd} or {quickmin} or {fire} or {spinmin} :ul [Examples:] min_style cg +min_style spinmin min_style fire :pre [Description:] @@ -61,9 +62,21 @@ the velocity non-parallel to the current force vector. The velocity of each atom is initialized to 0.0 by this style, at the beginning of a minimization. +Style {spinmin} is a damped spin dynamics with a variable +timestep as described in "(Tranchida)"_#Tranchida. +The value of the fictitious Gilbert damping and of the dividing +factor for the adaptive timestep can be modified by the +{alpha_damp} and {discret_factor} options respectively. +Those options can be defined using the "min_modify"_min_modify.html +command. + Either the {quickmin} and {fire} styles are useful in the context of nudged elastic band (NEB) calculations via the "neb"_neb.html command. +The {spinmin} style is useful in the context of geodesic nudged +elastic band (GNEB) calculations via the "neb/spin"_neb_spin.html +command. + NOTE: The damped dynamic minimizers use whatever timestep you have defined via the "timestep"_timestep.html command. Often they will converge more quickly if you use a timestep about 10x larger than you diff --git a/examples/SPIN/gneb_bfo/README b/examples/SPIN/gneb/README similarity index 100% rename from examples/SPIN/gneb_bfo/README rename to examples/SPIN/gneb/README diff --git a/examples/SPIN/gneb_bfo/final.iron_spin b/examples/SPIN/gneb/final.iron_spin similarity index 100% rename from examples/SPIN/gneb_bfo/final.iron_spin rename to examples/SPIN/gneb/final.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.gneb.iron b/examples/SPIN/gneb/in.gneb.iron similarity index 100% rename from examples/SPIN/gneb_bfo/in.gneb.iron rename to examples/SPIN/gneb/in.gneb.iron diff --git a/examples/SPIN/gneb_bfo/initial.iron_spin b/examples/SPIN/gneb/initial.iron_spin similarity index 100% rename from examples/SPIN/gneb_bfo/initial.iron_spin rename to examples/SPIN/gneb/initial.iron_spin diff --git a/examples/SPIN/gneb_bfo/in.spinmin.bfo b/examples/SPIN/spinmin/in.spinmin.bfo similarity index 78% rename from examples/SPIN/gneb_bfo/in.spinmin.bfo rename to examples/SPIN/spinmin/in.spinmin.bfo index 15a4d6e0f9..a00af8833c 100644 --- a/examples/SPIN/gneb_bfo/in.spinmin.bfo +++ b/examples/SPIN/spinmin/in.spinmin.bfo @@ -1,4 +1,4 @@ -# bcc iron in a 3d periodic box +# bfo in a 3d periodic box units metal dimension 3 @@ -9,7 +9,7 @@ atom_style spin atom_modify map array lattice sc 3.96 -region box block 0.0 68.0 0.0 68.0 0.0 1.0 +region box block 0.0 34.0 0.0 34.0 0.0 1.0 create_box 1 box create_atoms 1 box @@ -17,7 +17,6 @@ create_atoms 1 box mass 1 1.0 set group all spin/random 11 2.50 -#set group all spin 2.5 -1.0 0.0 0.0 pair_style hybrid/overlay spin/exchange 6.0 spin/magelec 4.5 spin/dmi 4.5 pair_coeff * * spin/exchange exchange 6.0 -0.01575 0.0 1.965 @@ -30,7 +29,8 @@ neigh_modify every 10 check yes delay 20 #fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 fix 1 all precession/spin anisotropy 0.0000033 0.0 0.0 1.0 -fix 2 all langevin/spin 0.1 0.0 21 +fix_modify 1 energy yes +fix 2 all langevin/spin 0.0 0.1 21 fix 3 all nve/spin lattice no timestep 0.0001 @@ -50,8 +50,8 @@ thermo_style custom step time v_magnorm v_emag v_tmag temp etotal thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 200 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] +dump 1 all custom 50 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] min_style spinmin -minimize 1.0e-6 1.0e-6 10000 10000 -#minimize 1.0e-8 1.0e-8 10000 1000 +min_modify alpha_damp 1.0 discret_factor 10.0 +minimize 0.0 0.0 10000 1000 diff --git a/examples/SPIN/gneb_bfo/in.spinmin.iron b/examples/SPIN/spinmin/in.spinmin.iron similarity index 62% rename from examples/SPIN/gneb_bfo/in.spinmin.iron rename to examples/SPIN/spinmin/in.spinmin.iron index 67d8095c06..5a15082122 100644 --- a/examples/SPIN/gneb_bfo/in.spinmin.iron +++ b/examples/SPIN/spinmin/in.spinmin.iron @@ -9,7 +9,7 @@ atom_style spin atom_modify map array lattice bcc 2.8665 -region box block 0.0 4.0 0.0 4.0 0.0 1.0 +region box block 0.0 4.0 0.0 4.0 0.0 4.0 create_box 1 box create_atoms 1 box @@ -17,7 +17,7 @@ create_atoms 1 box mass 1 55.845 set group all spin/random 31 2.2 -#set group all spin 2.2 -1.0 0.0 0.0 +#set group all spin 2.2 1.0 1.0 -1.0 pair_style spin/exchange 3.5 pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 @@ -26,8 +26,9 @@ neighbor 0.1 bin neigh_modify every 10 check yes delay 20 #fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 -fix 1 all precession/spin anisotropy 0.001 0.0 0.0 1.0 -fix 2 all langevin/spin 0.1 0.0 21 +fix 1 all precession/spin anisotropy 0.0001 0.0 0.0 1.0 +fix_modify 1 energy yes +fix 2 all langevin/spin 0.0 0.1 21 fix 3 all nve/spin lattice no timestep 0.0001 @@ -37,18 +38,20 @@ compute out_pe all pe compute out_ke all ke compute out_temp all temp +variable magx equal c_out_mag[1] +variable magy equal c_out_mag[2] variable magz equal c_out_mag[3] variable magnorm equal c_out_mag[4] variable emag equal c_out_mag[5] variable tmag equal c_out_mag[6] -thermo 1 -thermo_style custom step time v_magnorm v_emag v_tmag temp etotal +thermo 100 +thermo_style custom step time v_magx v_magz v_magnorm v_tmag etotal thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz -dump 1 all custom 1 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] +dump 1 all custom 100 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] min_style spinmin -minimize 1.0e-6 1.0e-6 1000 10000 -#minimize 1.0e-8 1.0e-6 1000 10000 +min_modify alpha_damp 1.0 discret_factor 10.0 +minimize 1.0e-10 1.0e-10 100000 1000 diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index 7a72936200..d8f9e655fd 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -843,156 +843,12 @@ double FixNEB_spin::geodesic_distance(double spi[3], double spj[3]) return dist; } -/* ---------------------------------------------------------------------- - geometric damped advance os spins ----------------------------------------------------------------------- */ - -//void FixNEB_spin::advance_spins(double dts) -//{ -// //int j=0; -// //int *sametag = atom->sametag; -// int nlocal = atom->nlocal; -// int *mask = atom->mask; -// double **sp = atom->sp; -// double **fm = atom->fm; -// double tdampx,tdampy,tdampz; -// double msq,scale,fm2,energy,dts2; -// double alpha; -// double spi[3],fmi[3]; -// double cp[3],g[3]; -// -// //cp[0] = cp[1] = cp[2] = 0.0; -// //g[0] = g[1] = g[2] = 0.0; -// dts2 = dts*dts; -// -// // fictitious Gilbert damping of 1 -// alpha = 1.0; -// -// // loop on all spins on proc. -// -// if (ireplica != nreplica-1 && ireplica != 0) -// for (int i = 0; i < nlocal; i++) -// if (mask[i] & groupbit) { -// -// spi[0] = sp[i][0]; -// spi[1] = sp[i][1]; -// spi[2] = sp[i][2]; -// -// fmi[0] = fm[i][0]; -// fmi[1] = fm[i][1]; -// fmi[2] = fm[i][2]; -// -// // calc. damping torque -// -// tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); -// tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); -// tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); -// -// // apply advance algorithm (geometric, norm preserving) -// -// fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); -// energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); -// -// cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; -// cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; -// cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; -// -// g[0] = sp[i][0]+cp[0]*dts; -// g[1] = sp[i][1]+cp[1]*dts; -// g[2] = sp[i][2]+cp[2]*dts; -// -// g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; -// g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; -// g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; -// -// g[0] /= (1+0.25*fm2*dts2); -// g[1] /= (1+0.25*fm2*dts2); -// g[2] /= (1+0.25*fm2*dts2); -// -// sp[i][0] = g[0]; -// sp[i][1] = g[1]; -// sp[i][2] = g[2]; -// -// // renormalization (check if necessary) -// -// msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; -// scale = 1.0/sqrt(msq); -// sp[i][0] *= scale; -// sp[i][1] *= scale; -// sp[i][2] *= scale; -// -// // comm. sp[i] to atoms with same tag (for serial algo) -// -// // no need for simplecticity -// //if (sector_flag == 0) { -// // if (sametag[i] >= 0) { -// // j = sametag[i]; -// // while (j >= 0) { -// // sp[j][0] = sp[i][0]; -// // sp[j][1] = sp[i][1]; -// // sp[j][2] = sp[i][2]; -// // j = sametag[j]; -// // } -// // } -// //} -// // -// -// } -//} - -/* ---------------------------------------------------------------------- - evaluate max timestep ----------------------------------------------------------------------- */ - -//double FixNEB_spin::evaluate_dt() -//{ -// double dtmax; -// double fmsq; -// double fmaxsqone,fmaxsqloc,fmaxsqall; -// int nlocal = atom->nlocal; -// int *mask = atom->mask; -// double **fm = atom->fm; -// -// // finding max fm on this proc. -// -// fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; -// for (int i = 0; i < nlocal; i++) -// if (mask[i] & groupbit) { -// fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; -// fmaxsqone = MAX(fmaxsqone,fmsq); -// } -// -// // finding max fm on this replica -// -// fmaxsqloc = fmaxsqone; -// MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); -// -// // finding max fm over all replicas, if necessary -// // this communicator would be invalid for multiprocess replicas -// -// if (update->multireplica == 1) { -// fmaxsqall = fmaxsqloc; -// MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); -// } -// -// if (fmaxsqall < fmaxsqloc) -// error->all(FLERR,"Incorrect fmaxall calc."); -// -// // define max timestep -// // dividing by 10 the inverse of max frequency -// -// dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); -// -// return dtmax; -//} - /* ---------------------------------------------------------------------- send/recv NEB atoms to/from adjacent replicas received atoms matching my local atoms are stored in xprev,xnext replicas 0 and N-1 send but do not receive any atoms ------------------------------------------------------------------------- */ - void FixNEB_spin::inter_replica_comm() { int i,m; -- GitLab From 2cc35ee7771f9fed8be9cba1521fd198485bad04 Mon Sep 17 00:00:00 2001 From: "Dan S. Bolintineanu" Date: Wed, 13 Mar 2019 00:42:08 -0600 Subject: [PATCH 0225/1243] A few additional enhancements to pair granular and fix wall granular option: - NULL option for tangential stiffness, to set it based on shear modulus - calculation of effective shear moduli from elastic moduli and Poisson's ratio - updates to doc page example syntax --- doc/src/fix_wall_gran.txt | 4 +-- doc/src/pair_granular.txt | 39 +++++++++++++--------- src/GRANULAR/fix_wall_gran.cpp | 43 +++++++++++++++++++++--- src/GRANULAR/pair_granular.cpp | 60 ++++++++++++++++++++++++++-------- 4 files changed, 111 insertions(+), 35 deletions(-) diff --git a/doc/src/fix_wall_gran.txt b/doc/src/fix_wall_gran.txt index 096bec4920..e8c2247594 100644 --- a/doc/src/fix_wall_gran.txt +++ b/doc/src/fix_wall_gran.txt @@ -49,8 +49,8 @@ fix 1 all wall/gran hooke 200000.0 NULL 50.0 NULL 0.5 0 xplane -10.0 10.0 fix 1 all wall/gran hooke/history 200000.0 NULL 50.0 NULL 0.5 0 zplane 0.0 NULL fix 2 all wall/gran hooke 100000.0 20000.0 50.0 30.0 0.5 1 zcylinder 15.0 wiggle z 3.0 2.0 fix 3 all wall/gran granular hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 zplane 0.0 NULL -fix 4 all wall/gran granular jkr 1000.0 50.0 tangential linear_history 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall zcylinder 15.0 wiggle z 3.0 2.0 -fix 5 all wall/gran granular dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall zplane 0.0 NULL :pre +fix 4 all wall/gran granular jkr 1000.0 50.0 0.3 5.0 tangential mindlin 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall zcylinder 15.0 wiggle z 3.0 2.0 +fix 5 all wall/gran granular dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall zplane 0.0 NULL :pre [Description:] diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 8db9567692..7a58435a83 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -28,10 +28,10 @@ pair_style granular pair_coeff * * hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 :pre pair_style granular -pair_coeff * * hertz 1000.0 50.0 tangential mindlin 800.0 1.0 0.4 :pre +pair_coeff * * hertz 1000.0 50.0 tangential mindlin NULL 1.0 0.4 :pre pair_style granular -pair_coeff * * hertz 1000.0 0.3 tangential linear_history 800.0 1.0 0.4 damping tsuji :pre +pair_coeff * * hertz/material 1e8 0.3 tangential mindlin_rescale NULL 1.0 0.4 damping tsuji :pre pair_style granular pair_coeff 1 1 jkr 1000.0 50.0 tangential mindlin 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall @@ -39,8 +39,8 @@ pair_coeff 2 2 hertz 200.0 20.0 tangential linear_history 300.0 1.0 0.1 rolling pair_style granular pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 0.5 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair_coeff 2 2 dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall -pair_coeff 1 2 dmt 1000.0 50.0 0.3 10.0 tangential linear_history 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre +pair_coeff 2 2 dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall +pair_coeff 1 2 dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre [Description:] @@ -220,8 +220,8 @@ expected parameters are as follows: {linear_nohistory} : \(x_\{\gamma,t\}\), \(\mu_s\) {linear_history} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) -{mindlin} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) -{mindlin_rescale} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) :ol +{mindlin} : \(k_t\) or NULL, \(x_\{\gamma,t\}\), \(\mu_s\) +{mindlin_rescale} : \(k_t\) or NULL, \(x_\{\gamma,t\}\), \(\mu_s\) :ol Here, \(x_\{\gamma,t\}\) is a dimensionless multiplier for the normal damping \(\eta_n\) that determines the magnitude of the @@ -337,7 +337,7 @@ to induce a torque on each particle according to: \mathbf\{\tau\}_j = -(R_j - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t \end\{equation\} -For {tangential mindlin}, the Mindlin no-slip solution is used, which differs from the {linear_history} +For {tangential mindlin}, the "Mindlin"_#Mindlin1949 no-slip solution is used, which differs from the {linear_history} option by an additional factor of {a}, the radius of the contact region. The tangential force is given by: \begin\{equation\} @@ -346,18 +346,27 @@ option by an additional factor of {a}, the radius of the contact region. The tan Here, {a} is the radius of the contact region, given by \(a = \delta R\) for all normal contact models, except for {jkr}, where it is given implicitly by \(\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\), -see discussion above. +see discussion above. To match the Mindlin solution, one should set \(k_t = 8G\), where +\(G\) is the shear modulus, related to Young's modulus \(E\) by \(G = E/(2(1+\nu))\), where \(\nu\) +is Poisson's ratio. This can also be achieved by specifying {NULL} for \(k_t\), in which case +a normal contact model that specifies material parameters \(E\) and \(\nu\) is required (e.g. {hertz/material}, +{dmt} or {jkr}). In this case, mixing of shear moduli for different particle types {i} and {j} is done according +to: +\begin\{equation\} +1/G = 2(2-\nu_i)(1+\nu_i)/E_i + 2(2-\nu_j)(1+\nu_j)/E_j +\end\{equation\} The {mindlin_rescale} option uses the same form as {mindlin}, but the magnitude of the tangential -displacement is re-scaled as the contact unloads, i.e. if \(a < a_\{t_n-1\}\): +displacement is re-scaled as the contact unloads, i.e. if \(a < a_\{t_\{n-1\}\}\): \begin\{equation\} -\mathbf\{\xi\} = \mathbf\{xi_\{t_n-1\}\} \frac\{a\}\{a_\{t_n-1\}\} +\mathbf\{\xi\} = \mathbf\{\xi_\{t_\{n-1\}\}\} \frac\{a\}\{a_\{t_\{n-1\}\}\} \end\{equation\} -This accounts for the fact that a decrease in the contact area upon unloading leads to the contact +Here, \(t_\{n-1\}\) indicates the value at the previous time step. This rescaling +accounts for the fact that a decrease in the contact area upon unloading leads to the contact being unable to support the previous tangential loading, and spurious energy is created -without the rescaling above ("Walton"_#WaltonPC). See also discussion in "Thornton et al, 2013"_#Thornton2013, -particularly equation 18(b) of that work and associated discussion. +without the rescaling above ("Walton"_#WaltonPC ). See also discussion in "Thornton et al, 2013"_#Thornton2013 +, particularly equation 18(b) of that work and associated discussion. :line @@ -649,10 +658,10 @@ J. Phys. D: Appl. Phys. 24 1942 [(Mindlin, 1949)] Mindlin, R. D. (1949). Compliance of elastic bodies in contact. J. Appl. Mech., ASME 16, 259-268. -:line(Thornton2013) +:link(Thornton2013) [(Thornton et al, 2013)] Thornton, C., Cummins, S. J., & Cleary, P. W. (2013). An investigation of the comparative behaviour of alternative contact force models during inelastic collisions. Powder Technology, 233, 30-46. -:line(WaltonPC) +:link(WaltonPC) [(Otis R. Walton)] Walton, O.R., Personal Communication diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 3b959e1a01..3a929771e9 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -54,7 +54,7 @@ enum{NONE,CONSTANT,EQUAL}; enum {NORMAL_HOOKE, NORMAL_HERTZ, HERTZ_MATERIAL, DMT, JKR}; enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN, TANGENTIAL_MINDLIN_RESCALE}; enum {TWIST_NONE, TWIST_SDS, TWIST_MARSHALL}; enum {ROLL_NONE, ROLL_SDS}; @@ -198,11 +198,24 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : tangential_coeffs[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; } - else if (strcmp(arg[iarg+1], "linear_history") == 0){ + else if ((strcmp(arg[iarg+1], "linear_history") == 0) || + (strcmp(arg[iarg+1], "mindlin") == 0) || + (strcmp(arg[iarg+1], "mindlin_rescale") == 0)){ if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); - tangential_model = TANGENTIAL_HISTORY; + if (strcmp(arg[iarg+1], "linear_history") == 0) tangential_model = TANGENTIAL_HISTORY; + else if (strcmp(arg[iarg+1], "mindlin") == 0) tangential_model = TANGENTIAL_MINDLIN; + else if (strcmp(arg[iarg+1], "mindlin_rescale") == 0) tangential_model = TANGENTIAL_MINDLIN_RESCALE; + if ((tangential_model == TANGENTIAL_MINDLIN || tangential_model == TANGENTIAL_MINDLIN_RESCALE) && + (strcmp(arg[iarg+2], "NULL") == 0)){ + if (normal_model == NORMAL_HERTZ || normal_model == NORMAL_HOOKE){ + error->all(FLERR, "NULL setting for Mindlin tangential stiffness requires a normal contact model that specifies material properties"); + } + tangential_coeffs[0] = 4*(2-poiss)*(1+poiss)/Emod; + } + else{ + tangential_coeffs[0] = force->numeric(FLERR,arg[iarg+2]); //kt + } tangential_history = 1; - tangential_coeffs[0] = force->numeric(FLERR,arg[iarg+2]); //kt tangential_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammat tangential_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; @@ -265,7 +278,9 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR, "Illegal fix wall/gran command"); } } - size_history = (normal_model == JKR) + 3*tangential_history + 3*roll_history + twist_history; + size_history = 3*tangential_history + 3*roll_history + twist_history; + if (normal_model == JKR) size_history += 1; + if (tangential_model == TANGENTIAL_MINDLIN_RESCALE) size_history += 1; } // wallstyle args @@ -466,6 +481,10 @@ void FixWallGran::init() roll_history_index += 1; twist_history_index += 1; } + if (tangential_model == TANGENTIAL_MINDLIN_RESCALE){ + roll_history_index += 1; + twist_history_index += 1; + } if (damping_model == TSUJI){ double cor = normal_coeffs[1]; @@ -473,6 +492,8 @@ void FixWallGran::init() 27.467*pow(cor,4)-18.022*pow(cor,5)+ 4.8218*pow(cor,6); } + + } /* ---------------------------------------------------------------------- */ @@ -1177,6 +1198,18 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, int thist2 = thist1 + 1; if (tangential_history){ + if (tangential_model == TANGENTIAL_MINDLIN){ + k_tangential *= a; + } + else if (tangential_model == TANGENTIAL_MINDLIN_RESCALE){ + k_tangential *= a; + if (a < history[3]){ //On unloading, rescale the shear displacements + double factor = a/history[thist2+1]; + history[thist0] *= factor; + history[thist1] *= factor; + history[thist2] *= factor; + } + } shrmag = sqrt(history[thist0]*history[thist0] + history[thist1]*history[thist1] + history[thist2]*history[thist2]); diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 19633a96c2..97cf02676f 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -211,8 +211,10 @@ void PairGranular::compute(int eflag, int vflag) ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; - firsttouch = fix_history->firstflag; - firsthistory = fix_history->firstvalue; + if (use_history){ + firsttouch = fix_history->firstflag; + firsthistory = fix_history->firstvalue; + } for (ii = 0; ii < inum; ii++) { i = ilist[ii]; @@ -222,8 +224,10 @@ void PairGranular::compute(int eflag, int vflag) ztmp = x[i][2]; itype = type[i]; radi = radius[i]; - touch = firsttouch[i]; - allhistory = firsthistory[i]; + if (use_history){ + touch = firsttouch[i]; + allhistory = firsthistory[i]; + } jlist = firstneigh[i]; jnum = numneigh[i]; @@ -263,9 +267,11 @@ void PairGranular::compute(int eflag, int vflag) if (!touchflag){ // unset non-touching neighbors - touch[jj] = 0; - history = &allhistory[size_history*jj]; - for (int k = 0; k < size_history; k++) history[k] = 0.0; + if (use_history){ + touch[jj] = 0; + history = &allhistory[size_history*jj]; + for (int k = 0; k < size_history; k++) history[k] = 0.0; + } } else{ r = sqrt(rsq); @@ -788,7 +794,16 @@ void PairGranular::coeff(int narg, char **arg) else if (strcmp(arg[iarg+1], "mindlin") == 0) tangential_model_one = TANGENTIAL_MINDLIN; else if (strcmp(arg[iarg+1], "mindlin_rescale") == 0) tangential_model_one = TANGENTIAL_MINDLIN_RESCALE; tangential_history = 1; - tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt + if ((tangential_model_one == TANGENTIAL_MINDLIN || tangential_model_one == TANGENTIAL_MINDLIN_RESCALE) && + (strcmp(arg[iarg+2], "NULL") == 0)){ + if (normal_model_one == HERTZ || normal_model_one == HOOKE){ + error->all(FLERR, "NULL setting for Mindlin tangential stiffness requires a normal contact model that specifies material properties"); + } + tangential_coeffs_one[0] = -1; + } + else{ + tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt + } tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; @@ -879,7 +894,13 @@ void PairGranular::coeff(int narg, char **arg) damping_model[i][j] = damping_model[j][i] = damping_model_one; tangential_model[i][j] = tangential_model[j][i] = tangential_model_one; - for (int k = 0; k < 3; k++) + if (tangential_coeffs_one[0] == -1){ + tangential_coeffs[i][j][0] = tangential_coeffs[j][i][0] = 8*mix_stiffnessG(Emod[i][j], Emod[i][j], poiss[i][j], poiss[i][j]); + } + else{ + tangential_coeffs[i][j][0] = tangential_coeffs[j][i][0] = tangential_coeffs_one[0]; + } + for (int k = 1; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = tangential_coeffs_one[k]; roll_model[i][j] = roll_model[j][i] = roll_model_one; @@ -1276,7 +1297,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, touchflag = (rsq <= radsum*radsum); } - if (touchflag){ + if (!touchflag){ fforce = 0.0; for (int m = 0; m < single_extra; m++) svector[m] = 0.0; return 0.0; @@ -1373,8 +1394,8 @@ double PairGranular::single(int i, int j, int itype, int jtype, } else{ knfac = E; - a = sqrt(dR); Fne = knfac*delta; + a = sqrt(dR); if (normal_model[itype][jtype] != HOOKE){ Fne *= a; knfac *= a; @@ -1451,6 +1472,19 @@ double PairGranular::single(int i, int j, int itype, int jtype, damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor; if (tangential_history){ + if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN){ + k_tangential *= a; + } + else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE){ + k_tangential *= a; + if (a < history[3]){ //On unloading, rescale the shear displacements + double factor = a/history[3]; + history[0] *= factor; + history[1] *= factor; + history[2] *= factor; + } + } + shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); @@ -1617,9 +1651,9 @@ double PairGranular::mix_stiffnessE(double Eii, double Ejj, double poisii, doubl mixing of shear modulus (G) ------------------------------------------------------------------------ */ -double PairGranular::mix_stiffnessG(double Gii, double Gjj, double poisii, double poisjj) +double PairGranular::mix_stiffnessG(double Eii, double Ejj, double poisii, double poisjj) { - return 1/((2.0 -poisii)/Gii+(2.0-poisjj)/Gjj); + return 1/((2*(2-poisii)*(1+poisii)/Eii) + (2*(2-poisjj)*(1+poisjj)/Ejj)); } /* ---------------------------------------------------------------------- -- GitLab From 3b234c167ff723805ba30dd0e6b222782f39b676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 13:46:15 +0100 Subject: [PATCH 0226/1243] USER-MEAMC: fix incomplete clearing of ev variables --- src/USER-MEAMC/pair_meamc.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/USER-MEAMC/pair_meamc.cpp b/src/USER-MEAMC/pair_meamc.cpp index b74416a46d..d0d97740b3 100644 --- a/src/USER-MEAMC/pair_meamc.cpp +++ b/src/USER-MEAMC/pair_meamc.cpp @@ -94,8 +94,7 @@ void PairMEAMC::compute(int eflag, int vflag) int *numneigh_full,**firstneigh_full; if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + else ev_unset(); // neighbor list info -- GitLab From adcd46da55303428ba26ee1846ad12b577c8bc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 6 Mar 2019 12:59:37 +0100 Subject: [PATCH 0227/1243] require an atom map for dynamical_matrix --- src/USER-PHONON/dynamical_matrix.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index 372f4e4e31..c12bf6873e 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -138,6 +138,9 @@ void DynamicalMatrix::command(int narg, char **arg) else if (style == ESKM) options(narg-3,&arg[3]); //COME BACK else if (comm->me == 0 && screen) fprintf(screen,"Illegal Dynamical Matrix command\n"); + if (atom->map_style == 0) + error->all(FLERR,"Dynamical_matrix command requires an atom map, see atom_modify"); + // move atoms by 3-vector or specified variable(s) if (style == REGULAR) { -- GitLab From d30e69e87123c1c5f24d7ba4d488066b217d5bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 6 Mar 2019 13:28:44 +0100 Subject: [PATCH 0228/1243] fix writing binary dynmat file --- src/USER-PHONON/dynamical_matrix.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index c12bf6873e..5b571213c7 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -337,7 +337,8 @@ void DynamicalMatrix::writeMatrix(double **dynmat) if (binaryflag && fp) { clearerr(fp); - fwrite(&dynmat[0], sizeof(double), 3 * dynlen, fp); + for (int i=0; i<3; i++) + fwrite(dynmat[i], sizeof(double), dynlen, fp); if (ferror(fp)) error->one(FLERR, "Error writing to binary file"); } -- GitLab From bb8398b22b966d617c4ce339081547026db4b8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 6 Mar 2019 13:49:25 +0100 Subject: [PATCH 0229/1243] streamline writeMatrix function --- src/USER-PHONON/dynamical_matrix.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index 5b571213c7..7b08e826a4 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -319,28 +319,24 @@ void DynamicalMatrix::calculateMatrix() void DynamicalMatrix::writeMatrix(double **dynmat) { - if (me != 0 || fp == NULL) return; + if (me != 0 || !fp) + return; - // print file comment lines - - if (!binaryflag && fp) { - clearerr(fp); + clearerr(fp); + if (binaryflag) { + for (int i=0; i<3; i++) + fwrite(dynmat[i], sizeof(double), dynlen, fp); + if (ferror(fp)) + error->one(FLERR, "Error writing to binary file"); + } else { for (int i = 0; i < 3; i++) { for (bigint j = 0; j < dynlen; j++) { if ((j+1)%3==0) fprintf(fp, "%4.8f\n", dynmat[i][j]); else fprintf(fp, "%4.8f ",dynmat[i][j]); } } - } - if (ferror(fp)) - error->one(FLERR,"Error writing to file"); - - if (binaryflag && fp) { - clearerr(fp); - for (int i=0; i<3; i++) - fwrite(dynmat[i], sizeof(double), dynlen, fp); if (ferror(fp)) - error->one(FLERR, "Error writing to binary file"); + error->one(FLERR,"Error writing to file"); } } -- GitLab From e8efa01006d574c44ca2e379f78eb7645c2132ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 6 Mar 2019 14:28:58 +0100 Subject: [PATCH 0230/1243] dynamical_matrix progress indicator --- src/USER-PHONON/dynamical_matrix.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index 7b08e826a4..b4a676b4db 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -262,6 +262,7 @@ void DynamicalMatrix::calculateMatrix() if (comm->me == 0 && screen) fprintf(screen,"Calculating Dynamical Matrix...\n"); update->nsteps = 0; + int prog = 0; for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); for (bigint alpha=0; alpha<3; alpha++){ @@ -300,7 +301,16 @@ void DynamicalMatrix::calculateMatrix() if (me == 0) writeMatrix(fdynmat); dynmat_clear(dynmat); + if (comm->me == 0 && screen) { + int p = 10 * i / natoms; + if (p > prog) { + prog = p; + fprintf(screen," %d%%",p*10); + fflush(screen); + } + } } + if (comm->me == 0 && screen) fprintf(screen,"\n"); for (int i=0; i < 3; i++) delete [] dynmat[i]; -- GitLab From 7fe1cceb7656351697f0b931b6cd7131d4706bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Thu, 7 Mar 2019 16:22:04 +0100 Subject: [PATCH 0231/1243] fix some leftover bigint conversions, groupmap construction --- src/USER-PHONON/dynamical_matrix.cpp | 46 ++++++++++++++++++---------- src/USER-PHONON/dynamical_matrix.h | 2 +- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/USER-PHONON/dynamical_matrix.cpp b/src/USER-PHONON/dynamical_matrix.cpp index b4a676b4db..d94bd11a80 100644 --- a/src/USER-PHONON/dynamical_matrix.cpp +++ b/src/USER-PHONON/dynamical_matrix.cpp @@ -243,7 +243,7 @@ void DynamicalMatrix::calculateMatrix() int nlocal = atom->nlocal; bigint natoms = atom->natoms; int *type = atom->type; - int *gm = groupmap; + bigint *gm = groupmap; double imass; // dynamical matrix element double *m = atom->mass; double **f = atom->f; @@ -259,21 +259,30 @@ void DynamicalMatrix::calculateMatrix() //initialize dynmat to all zeros dynmat_clear(dynmat); - if (comm->me == 0 && screen) fprintf(screen,"Calculating Dynamical Matrix...\n"); + if (comm->me == 0 && screen) { + fprintf(screen,"Calculating Dynamical Matrix ...\n"); + fprintf(screen," Total # of atoms = " BIGINT_FORMAT "\n", natoms); + fprintf(screen," Atoms in group = " BIGINT_FORMAT "\n", gcount); + fprintf(screen," Total dynamical matrix elements = " BIGINT_FORMAT "\n", (dynlen*dynlen) ); + } + + // emit dynlen rows of dimalpha*dynlen*dimbeta elements update->nsteps = 0; int prog = 0; for (bigint i=1; i<=natoms; i++){ local_idx = atom->map(i); + if (gm[i-1] < 0) + continue; for (bigint alpha=0; alpha<3; alpha++){ displace_atom(local_idx, alpha, 1); update_force(); for (bigint j=1; j<=natoms; j++){ local_jdx = atom->map(j); if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal - && gm[i-1] >= 0 && gm[j-1] >= 0){ + && gm[j-1] >= 0){ for (int beta=0; beta<3; beta++){ - dynmat[alpha][(gm[j-1])*3+beta] -= f[local_jdx][beta]; + dynmat[alpha][gm[j-1]*3+beta] -= f[local_jdx][beta]; } } } @@ -282,15 +291,15 @@ void DynamicalMatrix::calculateMatrix() for (bigint j=1; j<=natoms; j++){ local_jdx = atom->map(j); if (local_idx >= 0 && local_jdx >= 0 && local_jdx < nlocal - && gm[i-1] >= 0 && gm[j-1] >= 0){ + && gm[j-1] >= 0){ for (bigint beta=0; beta<3; beta++){ if (atom->rmass_flag == 1) imass = sqrt(m[local_idx] * m[local_jdx]); else imass = sqrt(m[type[local_idx]] * m[type[local_jdx]]); - dynmat[alpha][(gm[j-1])*3+beta] -= -f[local_jdx][beta]; - dynmat[alpha][(gm[j-1])*3+beta] /= (2 * del * imass); - dynmat[alpha][(gm[j-1])*3+beta] *= conversion; + dynmat[alpha][gm[j-1]*3+beta] -= -f[local_jdx][beta]; + dynmat[alpha][gm[j-1]*3+beta] /= (2 * del * imass); + dynmat[alpha][gm[j-1]*3+beta] *= conversion; } } } @@ -302,7 +311,7 @@ void DynamicalMatrix::calculateMatrix() writeMatrix(fdynmat); dynmat_clear(dynmat); if (comm->me == 0 && screen) { - int p = 10 * i / natoms; + int p = 10 * gm[i-1] / gcount; if (p > prog) { prog = p; fprintf(screen," %d%%",p*10); @@ -500,6 +509,7 @@ void DynamicalMatrix::convert_units(const char *style) void DynamicalMatrix::create_groupmap() { //Create a group map which maps atom order onto group + // groupmap[global atom index-1] = output column/row int local_idx; // local index int gid = 0; //group index @@ -508,7 +518,7 @@ void DynamicalMatrix::create_groupmap() bigint natoms = atom->natoms; int *recv = new int[comm->nprocs]; int *displs = new int[comm->nprocs]; - int *temp_groupmap = new int[natoms]; + bigint *temp_groupmap = new bigint[natoms]; //find number of local atoms in the group (final_gid) for (bigint i=1; i<=natoms; i++){ @@ -517,7 +527,7 @@ void DynamicalMatrix::create_groupmap() gid += 1; // gid at the end of loop is final_Gid } //create an array of length final_gid - int *sub_groupmap = new int[gid]; + bigint *sub_groupmap = new bigint[gid]; gid = 0; //create a map between global atom id and group atom id for each proc @@ -534,7 +544,7 @@ void DynamicalMatrix::create_groupmap() recv[i] = 0; } recv[comm->me] = gid; - MPI_Allreduce(recv,displs,4,MPI_INT,MPI_SUM,world); + MPI_Allreduce(recv,displs,comm->nprocs,MPI_INT,MPI_SUM,world); for (int i=0; inprocs; i++){ recv[i]=displs[i]; if (i>0) displs[i] = displs[i-1]+recv[i-1]; @@ -542,15 +552,17 @@ void DynamicalMatrix::create_groupmap() } //combine subgroup maps into total temporary groupmap - MPI_Allgatherv(sub_groupmap,gid,MPI_INT,temp_groupmap,recv,displs,MPI_INT,world); + MPI_Allgatherv(sub_groupmap,gid,MPI_LMP_BIGINT,temp_groupmap,recv,displs,MPI_LMP_BIGINT,world); std::sort(temp_groupmap,temp_groupmap+gcount); //populate member groupmap based on temp groupmap - for (bigint i=0; i Date: Wed, 13 Mar 2019 16:34:15 +0100 Subject: [PATCH 0232/1243] use ev_unset for all pair styles --- src/ASPHERE/pair_gayberne.cpp | 3 +-- src/ASPHERE/pair_line_lj.cpp | 3 +-- src/ASPHERE/pair_resquared.cpp | 3 +-- src/ASPHERE/pair_tri_lj.cpp | 3 +-- src/BODY/pair_body_nparticle.cpp | 3 +-- src/BODY/pair_body_rounded_polygon.cpp | 3 +-- src/BODY/pair_body_rounded_polyhedron.cpp | 3 +-- src/CLASS2/pair_lj_class2.cpp | 3 +-- src/CLASS2/pair_lj_class2_coul_cut.cpp | 3 +-- src/CLASS2/pair_lj_class2_coul_long.cpp | 3 +-- src/COLLOID/pair_brownian.cpp | 3 +-- src/COLLOID/pair_brownian_poly.cpp | 3 +-- src/COLLOID/pair_colloid.cpp | 3 +-- src/COLLOID/pair_lubricate.cpp | 3 +-- src/COLLOID/pair_lubricateU.cpp | 3 +-- src/COLLOID/pair_lubricateU_poly.cpp | 3 +-- src/COLLOID/pair_lubricate_poly.cpp | 3 +-- src/COLLOID/pair_yukawa_colloid.cpp | 3 +-- src/CORESHELL/pair_born_coul_dsf_cs.cpp | 3 +-- src/CORESHELL/pair_born_coul_long_cs.cpp | 3 +-- src/CORESHELL/pair_born_coul_wolf_cs.cpp | 3 +-- src/CORESHELL/pair_buck_coul_long_cs.cpp | 3 +-- src/CORESHELL/pair_coul_long_cs.cpp | 3 +-- src/CORESHELL/pair_coul_wolf_cs.cpp | 3 +-- src/CORESHELL/pair_lj_cut_coul_long_cs.cpp | 6 ++---- src/DIPOLE/pair_lj_cut_dipole_cut.cpp | 3 +-- src/DIPOLE/pair_lj_cut_dipole_long.cpp | 3 +-- src/DIPOLE/pair_lj_long_dipole_long.cpp | 3 +-- src/GPU/pair_beck_gpu.cpp | 3 +-- src/GPU/pair_born_coul_long_cs_gpu.cpp | 3 +-- src/GPU/pair_born_coul_long_gpu.cpp | 3 +-- src/GPU/pair_born_coul_wolf_cs_gpu.cpp | 3 +-- src/GPU/pair_born_coul_wolf_gpu.cpp | 3 +-- src/GPU/pair_born_gpu.cpp | 3 +-- src/GPU/pair_buck_coul_cut_gpu.cpp | 3 +-- src/GPU/pair_buck_coul_long_gpu.cpp | 3 +-- src/GPU/pair_buck_gpu.cpp | 3 +-- src/GPU/pair_colloid_gpu.cpp | 3 +-- src/GPU/pair_coul_cut_gpu.cpp | 3 +-- src/GPU/pair_coul_debye_gpu.cpp | 3 +-- src/GPU/pair_coul_dsf_gpu.cpp | 3 +-- src/GPU/pair_coul_long_cs_gpu.cpp | 3 +-- src/GPU/pair_coul_long_gpu.cpp | 3 +-- src/GPU/pair_dpd_gpu.cpp | 3 +-- src/GPU/pair_dpd_tstat_gpu.cpp | 3 +-- src/GPU/pair_eam_alloy_gpu.cpp | 3 +-- src/GPU/pair_eam_fs_gpu.cpp | 3 +-- src/GPU/pair_eam_gpu.cpp | 3 +-- src/GPU/pair_gauss_gpu.cpp | 3 +-- src/GPU/pair_gayberne_gpu.cpp | 3 +-- src/GPU/pair_lj96_cut_gpu.cpp | 3 +-- src/GPU/pair_lj_charmm_coul_long_gpu.cpp | 3 +-- src/GPU/pair_lj_class2_coul_long_gpu.cpp | 3 +-- src/GPU/pair_lj_class2_gpu.cpp | 3 +-- src/GPU/pair_lj_cubic_gpu.cpp | 3 +-- src/GPU/pair_lj_cut_coul_cut_gpu.cpp | 3 +-- src/GPU/pair_lj_cut_coul_debye_gpu.cpp | 3 +-- src/GPU/pair_lj_cut_coul_dsf_gpu.cpp | 3 +-- src/GPU/pair_lj_cut_coul_long_gpu.cpp | 3 +-- src/GPU/pair_lj_cut_coul_msm_gpu.cpp | 3 +-- src/GPU/pair_lj_cut_dipole_cut_gpu.cpp | 6 ++---- src/GPU/pair_lj_cut_dipole_long_gpu.cpp | 6 ++---- src/GPU/pair_lj_cut_gpu.cpp | 3 +-- src/GPU/pair_lj_expand_coul_long_gpu.cpp | 3 +-- src/GPU/pair_lj_expand_gpu.cpp | 3 +-- src/GPU/pair_lj_gromacs_gpu.cpp | 3 +-- src/GPU/pair_lj_sdk_coul_long_gpu.cpp | 3 +-- src/GPU/pair_lj_sdk_gpu.cpp | 3 +-- src/GPU/pair_lj_sf_dipole_sf_gpu.cpp | 6 ++---- src/GPU/pair_mie_cut_gpu.cpp | 3 +-- src/GPU/pair_morse_gpu.cpp | 3 +-- src/GPU/pair_resquared_gpu.cpp | 3 +-- src/GPU/pair_soft_gpu.cpp | 3 +-- src/GPU/pair_sw_gpu.cpp | 3 +-- src/GPU/pair_table_gpu.cpp | 3 +-- src/GPU/pair_tersoff_gpu.cpp | 3 +-- src/GPU/pair_tersoff_mod_gpu.cpp | 3 +-- src/GPU/pair_tersoff_zbl_gpu.cpp | 3 +-- src/GPU/pair_ufm_gpu.cpp | 3 +-- src/GPU/pair_vashishta_gpu.cpp | 3 +-- src/GPU/pair_yukawa_colloid_gpu.cpp | 3 +-- src/GPU/pair_yukawa_gpu.cpp | 3 +-- src/GPU/pair_zbl_gpu.cpp | 3 +-- src/GRANULAR/pair_gran_hertz_history.cpp | 3 +-- src/GRANULAR/pair_gran_hooke.cpp | 3 +-- src/GRANULAR/pair_gran_hooke_history.cpp | 3 +-- src/KIM/pair_kim.cpp | 5 +---- src/KOKKOS/pair_buck_coul_cut_kokkos.cpp | 3 +-- src/KOKKOS/pair_buck_coul_long_kokkos.cpp | 3 +-- src/KOKKOS/pair_buck_kokkos.cpp | 3 +-- src/KOKKOS/pair_coul_cut_kokkos.cpp | 3 +-- src/KOKKOS/pair_coul_debye_kokkos.cpp | 3 +-- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 3 +-- src/KOKKOS/pair_coul_long_kokkos.cpp | 3 +-- src/KOKKOS/pair_coul_wolf_kokkos.cpp | 3 +-- src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp | 3 +-- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 3 +-- src/KOKKOS/pair_eam_fs_kokkos.cpp | 3 +-- src/KOKKOS/pair_eam_kokkos.cpp | 3 +-- src/KOKKOS/pair_exp6_rx_kokkos.cpp | 3 +-- src/KOKKOS/pair_gran_hooke_history_kokkos.cpp | 3 +-- src/KOKKOS/pair_hybrid_kokkos.cpp | 4 +--- src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_class2_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_cut_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_expand_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_gromacs_kokkos.cpp | 3 +-- src/KOKKOS/pair_lj_sdk_kokkos.cpp | 3 +-- src/KOKKOS/pair_morse_kokkos.cpp | 3 +-- src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp | 3 +-- src/KOKKOS/pair_reaxc_kokkos.cpp | 3 +-- src/KOKKOS/pair_snap_kokkos_impl.h | 3 +-- src/KOKKOS/pair_sw_kokkos.cpp | 3 +-- src/KOKKOS/pair_table_kokkos.cpp | 3 +-- src/KOKKOS/pair_table_rx_kokkos.cpp | 3 +-- src/KOKKOS/pair_tersoff_kokkos.cpp | 3 +-- src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 3 +-- src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 3 +-- src/KOKKOS/pair_vashishta_kokkos.cpp | 3 +-- src/KOKKOS/pair_yukawa_kokkos.cpp | 3 +-- src/KOKKOS/pair_zbl_kokkos.cpp | 3 +-- src/KSPACE/pair_born_coul_long.cpp | 3 +-- src/KSPACE/pair_born_coul_msm.cpp | 3 +-- src/KSPACE/pair_buck_coul_long.cpp | 3 +-- src/KSPACE/pair_buck_coul_msm.cpp | 3 +-- src/KSPACE/pair_buck_long_coul_long.cpp | 6 ++---- src/KSPACE/pair_coul_long.cpp | 3 +-- src/KSPACE/pair_coul_msm.cpp | 3 +-- src/KSPACE/pair_lj_charmm_coul_long.cpp | 6 ++---- src/KSPACE/pair_lj_charmm_coul_msm.cpp | 6 ++---- src/KSPACE/pair_lj_charmmfsw_coul_long.cpp | 6 ++---- src/KSPACE/pair_lj_cut_coul_long.cpp | 6 ++---- src/KSPACE/pair_lj_cut_coul_msm.cpp | 6 ++---- src/KSPACE/pair_lj_cut_tip4p_long.cpp | 3 +-- src/KSPACE/pair_lj_long_coul_long.cpp | 6 ++---- src/KSPACE/pair_lj_long_tip4p_long.cpp | 6 ++---- src/KSPACE/pair_tip4p_long.cpp | 3 +-- src/MANYBODY/pair_adp.cpp | 3 +-- src/MANYBODY/pair_airebo.cpp | 3 +-- src/MANYBODY/pair_atm.cpp | 3 +-- src/MANYBODY/pair_bop.cpp | 3 +-- src/MANYBODY/pair_comb.cpp | 3 +-- src/MANYBODY/pair_comb3.cpp | 3 +-- src/MANYBODY/pair_eam.cpp | 3 +-- src/MANYBODY/pair_eam_cd.cpp | 3 +-- src/MANYBODY/pair_eim.cpp | 3 +-- src/MANYBODY/pair_gw.cpp | 3 +-- src/MANYBODY/pair_lcbop.cpp | 3 +-- src/MANYBODY/pair_nb3b_harmonic.cpp | 3 +-- src/MANYBODY/pair_polymorphic.cpp | 3 +-- src/MANYBODY/pair_sw.cpp | 3 +-- src/MANYBODY/pair_tersoff.cpp | 3 +-- src/MANYBODY/pair_vashishta.cpp | 3 +-- src/MANYBODY/pair_vashishta_table.cpp | 3 +-- src/MISC/pair_nm_cut.cpp | 3 +-- src/MISC/pair_nm_cut_coul_cut.cpp | 3 +-- src/MISC/pair_nm_cut_coul_long.cpp | 3 +-- src/MOLECULE/pair_hbond_dreiding_lj.cpp | 3 +-- src/MOLECULE/pair_hbond_dreiding_morse.cpp | 3 +-- src/MOLECULE/pair_lj_charmm_coul_charmm.cpp | 3 +-- src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp | 3 +-- src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp | 3 +-- src/MOLECULE/pair_lj_cut_tip4p_cut.cpp | 3 +-- src/MOLECULE/pair_tip4p_cut.cpp | 3 +-- src/OPT/pair_eam_opt.cpp | 3 +-- src/OPT/pair_lj_charmm_coul_long_opt.cpp | 3 +-- src/OPT/pair_lj_cut_coul_long_opt.cpp | 3 +-- src/OPT/pair_lj_cut_opt.cpp | 3 +-- src/OPT/pair_lj_cut_tip4p_long_opt.cpp | 3 +-- src/OPT/pair_lj_long_coul_long_opt.cpp | 6 ++---- src/OPT/pair_morse_opt.cpp | 3 +-- src/OPT/pair_ufm_opt.cpp | 3 +-- src/PERI/pair_peri_eps.cpp | 3 +-- src/PERI/pair_peri_lps.cpp | 3 +-- src/PERI/pair_peri_pmb.cpp | 3 +-- src/PERI/pair_peri_ves.cpp | 3 +-- src/PYTHON/pair_python.cpp | 3 +-- src/SNAP/pair_snap.cpp | 6 ++---- src/SPIN/pair_spin_dmi.cpp | 3 +-- src/SPIN/pair_spin_exchange.cpp | 3 +-- src/SPIN/pair_spin_magelec.cpp | 3 +-- src/SPIN/pair_spin_neel.cpp | 3 +-- src/USER-AWPMD/pair_awpmd_cut.cpp | 5 +---- src/USER-CGDNA/pair_oxdna2_coaxstk.cpp | 3 +-- src/USER-CGDNA/pair_oxdna2_dh.cpp | 3 +-- src/USER-CGDNA/pair_oxdna_coaxstk.cpp | 3 +-- src/USER-CGDNA/pair_oxdna_excv.cpp | 3 +-- src/USER-CGDNA/pair_oxdna_hbond.cpp | 3 +-- src/USER-CGDNA/pair_oxdna_stk.cpp | 3 +-- src/USER-CGDNA/pair_oxdna_xstk.cpp | 3 +-- src/USER-CGSDK/pair_lj_sdk.cpp | 4 +--- src/USER-CGSDK/pair_lj_sdk_coul_long.cpp | 4 +--- src/USER-CGSDK/pair_lj_sdk_coul_msm.cpp | 4 +--- src/USER-DPD/pair_dpd_fdt.cpp | 3 +-- src/USER-DPD/pair_dpd_fdt_energy.cpp | 3 +-- src/USER-DPD/pair_exp6_rx.cpp | 3 +-- src/USER-DPD/pair_multi_lucy.cpp | 3 +-- src/USER-DPD/pair_multi_lucy_rx.cpp | 3 +-- src/USER-DPD/pair_table_rx.cpp | 3 +-- src/USER-DRUDE/pair_lj_cut_thole_long.cpp | 3 +-- src/USER-DRUDE/pair_thole.cpp | 3 +-- src/USER-EFF/pair_eff_cut.cpp | 3 +-- src/USER-FEP/pair_coul_cut_soft.cpp | 3 +-- src/USER-FEP/pair_coul_long_soft.cpp | 3 +-- src/USER-FEP/pair_lj_charmm_coul_long_soft.cpp | 6 ++---- src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp | 3 +-- src/USER-FEP/pair_lj_class2_coul_long_soft.cpp | 3 +-- src/USER-FEP/pair_lj_class2_soft.cpp | 3 +-- src/USER-FEP/pair_lj_cut_coul_cut_soft.cpp | 3 +-- src/USER-FEP/pair_lj_cut_coul_long_soft.cpp | 6 ++---- src/USER-FEP/pair_lj_cut_soft.cpp | 6 ++---- src/USER-FEP/pair_lj_cut_tip4p_long_soft.cpp | 3 +-- src/USER-FEP/pair_morse_soft.cpp | 3 +-- src/USER-FEP/pair_tip4p_long_soft.cpp | 3 +-- src/USER-INTEL/pair_airebo_intel.cpp | 3 +-- src/USER-INTEL/pair_buck_coul_cut_intel.cpp | 4 +--- src/USER-INTEL/pair_buck_coul_long_intel.cpp | 4 +--- src/USER-INTEL/pair_buck_intel.cpp | 4 +--- src/USER-INTEL/pair_dpd_intel.cpp | 4 +--- src/USER-INTEL/pair_eam_intel.cpp | 4 +--- src/USER-INTEL/pair_gayberne_intel.cpp | 4 +--- src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp | 4 +--- src/USER-INTEL/pair_lj_charmm_coul_long_intel.cpp | 4 +--- src/USER-INTEL/pair_lj_cut_coul_long_intel.cpp | 4 +--- src/USER-INTEL/pair_lj_cut_intel.cpp | 4 +--- src/USER-INTEL/pair_sw_intel.cpp | 4 +--- src/USER-INTEL/pair_tersoff_intel.cpp | 4 +--- src/USER-MEAMC/pair_meamc.cpp | 3 +-- src/USER-MESO/pair_edpd.cpp | 3 +-- src/USER-MESO/pair_mdpd.cpp | 3 +-- src/USER-MESO/pair_mdpd_rhosum.cpp | 5 +---- src/USER-MESO/pair_tdpd.cpp | 3 +-- src/USER-MGPT/pair_mgpt.cpp | 3 +-- src/USER-MISC/pair_agni.cpp | 3 +-- src/USER-MISC/pair_buck_mdf.cpp | 3 +-- src/USER-MISC/pair_coul_diel.cpp | 3 +-- src/USER-MISC/pair_coul_shield.cpp | 3 +-- src/USER-MISC/pair_edip.cpp | 3 +-- src/USER-MISC/pair_edip_multi.cpp | 3 +-- src/USER-MISC/pair_extep.cpp | 3 +-- src/USER-MISC/pair_gauss_cut.cpp | 3 +-- src/USER-MISC/pair_ilp_graphene_hbn.cpp | 3 +-- src/USER-MISC/pair_kolmogorov_crespi_full.cpp | 3 +-- src/USER-MISC/pair_kolmogorov_crespi_z.cpp | 3 +-- src/USER-MISC/pair_lebedeva_z.cpp | 3 +-- src/USER-MISC/pair_lennard_mdf.cpp | 3 +-- src/USER-MISC/pair_list.cpp | 4 +--- src/USER-MISC/pair_lj_expand_coul_long.cpp | 6 ++---- src/USER-MISC/pair_lj_mdf.cpp | 3 +-- src/USER-MISC/pair_lj_sf_dipole_sf.cpp | 3 +-- src/USER-MISC/pair_meam_spline.cpp | 7 +------ src/USER-MISC/pair_meam_sw_spline.cpp | 4 +--- src/USER-MISC/pair_momb.cpp | 3 +-- src/USER-MISC/pair_morse_smooth_linear.cpp | 3 +-- src/USER-MISC/pair_srp.cpp | 5 +---- src/USER-MISC/pair_tersoff_table.cpp | 3 +-- src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp | 3 +-- src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp | 3 +-- src/USER-OMP/pair_adp_omp.cpp | 4 +--- src/USER-OMP/pair_agni_omp.cpp | 4 +--- src/USER-OMP/pair_airebo_omp.cpp | 4 +--- src/USER-OMP/pair_beck_omp.cpp | 4 +--- src/USER-OMP/pair_born_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_born_coul_msm_omp.cpp | 4 +--- src/USER-OMP/pair_born_coul_wolf_omp.cpp | 4 +--- src/USER-OMP/pair_born_omp.cpp | 4 +--- src/USER-OMP/pair_brownian_omp.cpp | 4 +--- src/USER-OMP/pair_brownian_poly_omp.cpp | 4 +--- src/USER-OMP/pair_buck_coul_cut_omp.cpp | 4 +--- src/USER-OMP/pair_buck_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_buck_coul_msm_omp.cpp | 4 +--- src/USER-OMP/pair_buck_long_coul_long_omp.cpp | 5 ++--- src/USER-OMP/pair_buck_omp.cpp | 4 +--- src/USER-OMP/pair_colloid_omp.cpp | 4 +--- src/USER-OMP/pair_comb_omp.cpp | 4 +--- src/USER-OMP/pair_coul_cut_omp.cpp | 4 +--- src/USER-OMP/pair_coul_cut_soft_omp.cpp | 4 +--- src/USER-OMP/pair_coul_debye_omp.cpp | 4 +--- src/USER-OMP/pair_coul_diel_omp.cpp | 4 +--- src/USER-OMP/pair_coul_dsf_omp.cpp | 4 +--- src/USER-OMP/pair_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_coul_long_soft_omp.cpp | 4 +--- src/USER-OMP/pair_coul_msm_omp.cpp | 4 +--- src/USER-OMP/pair_coul_wolf_omp.cpp | 4 +--- src/USER-OMP/pair_dpd_omp.cpp | 4 +--- src/USER-OMP/pair_dpd_tstat_omp.cpp | 4 +--- src/USER-OMP/pair_eam_cd_omp.cpp | 4 +--- src/USER-OMP/pair_eam_omp.cpp | 4 +--- src/USER-OMP/pair_edip_omp.cpp | 4 +--- src/USER-OMP/pair_eim_omp.cpp | 4 +--- src/USER-OMP/pair_gauss_cut_omp.cpp | 4 +--- src/USER-OMP/pair_gauss_omp.cpp | 4 +--- src/USER-OMP/pair_gayberne_omp.cpp | 4 +--- src/USER-OMP/pair_gran_hertz_history_omp.cpp | 4 +--- src/USER-OMP/pair_gran_hooke_history_omp.cpp | 4 +--- src/USER-OMP/pair_gran_hooke_omp.cpp | 4 +--- src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp | 4 +--- src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp | 4 +--- src/USER-OMP/pair_lj96_cut_omp.cpp | 4 +--- src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp | 4 +--- src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp | 4 +--- src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_lj_charmm_coul_long_soft_omp.cpp | 4 +--- src/USER-OMP/pair_lj_charmm_coul_msm_omp.cpp | 4 +--- src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp | 4 +--- src/USER-OMP/pair_lj_class2_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_lj_class2_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cubic_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_cut_soft_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_dsf_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_long_soft_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_msm_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_coul_wolf_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_dipole_cut_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_soft_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_thole_long_omp.cpp | 4 +--- src/USER-OMP/pair_lj_cut_tip4p_cut_omp.cpp | 3 +-- src/USER-OMP/pair_lj_cut_tip4p_long_omp.cpp | 3 +-- src/USER-OMP/pair_lj_cut_tip4p_long_soft_omp.cpp | 3 +-- src/USER-OMP/pair_lj_expand_omp.cpp | 4 +--- src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp | 4 +--- src/USER-OMP/pair_lj_gromacs_omp.cpp | 4 +--- src/USER-OMP/pair_lj_long_coul_long_omp.cpp | 5 ++--- src/USER-OMP/pair_lj_long_tip4p_long_omp.cpp | 4 +--- src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_lj_sdk_coul_msm_omp.cpp | 4 +--- src/USER-OMP/pair_lj_sdk_omp.cpp | 4 +--- src/USER-OMP/pair_lj_sf_dipole_sf_omp.cpp | 4 +--- src/USER-OMP/pair_lj_smooth_linear_omp.cpp | 4 +--- src/USER-OMP/pair_lj_smooth_omp.cpp | 4 +--- src/USER-OMP/pair_lubricate_omp.cpp | 4 +--- src/USER-OMP/pair_lubricate_poly_omp.cpp | 4 +--- src/USER-OMP/pair_meam_spline_omp.cpp | 4 +--- src/USER-OMP/pair_morse_omp.cpp | 4 +--- src/USER-OMP/pair_morse_smooth_linear_omp.cpp | 4 +--- src/USER-OMP/pair_nm_cut_coul_cut_omp.cpp | 4 +--- src/USER-OMP/pair_nm_cut_coul_long_omp.cpp | 4 +--- src/USER-OMP/pair_nm_cut_omp.cpp | 4 +--- src/USER-OMP/pair_peri_lps_omp.cpp | 4 +--- src/USER-OMP/pair_peri_pmb_omp.cpp | 4 +--- src/USER-OMP/pair_reaxc_omp.cpp | 3 +-- src/USER-OMP/pair_resquared_omp.cpp | 4 +--- src/USER-OMP/pair_soft_omp.cpp | 4 +--- src/USER-OMP/pair_sw_omp.cpp | 4 +--- src/USER-OMP/pair_table_omp.cpp | 4 +--- src/USER-OMP/pair_tersoff_mod_c_omp.cpp | 4 +--- src/USER-OMP/pair_tersoff_mod_omp.cpp | 4 +--- src/USER-OMP/pair_tersoff_omp.cpp | 4 +--- src/USER-OMP/pair_tersoff_table_omp.cpp | 4 +--- src/USER-OMP/pair_tip4p_cut_omp.cpp | 3 +-- src/USER-OMP/pair_tip4p_long_omp.cpp | 3 +-- src/USER-OMP/pair_tip4p_long_soft_omp.cpp | 3 +-- src/USER-OMP/pair_ufm_omp.cpp | 4 +--- src/USER-OMP/pair_vashishta_omp.cpp | 4 +--- src/USER-OMP/pair_vashishta_table_omp.cpp | 4 +--- src/USER-OMP/pair_yukawa_colloid_omp.cpp | 4 +--- src/USER-OMP/pair_yukawa_omp.cpp | 4 +--- src/USER-OMP/pair_zbl_omp.cpp | 4 +--- src/USER-QUIP/pair_quip.cpp | 3 +-- src/USER-REAXC/pair_reaxc.cpp | 3 +-- src/USER-SDPD/pair_sdpd_taitwater_isothermal.cpp | 3 +-- src/USER-SMD/pair_smd_hertz.cpp | 5 +---- src/USER-SMD/pair_smd_tlsph.cpp | 5 +---- src/USER-SMD/pair_smd_triangulated_surface.cpp | 5 +---- src/USER-SMD/pair_smd_ulsph.cpp | 5 +---- src/USER-SMTBQ/pair_smtbq.cpp | 3 +-- 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 | 5 +---- src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp | 3 +-- src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp | 3 +-- src/pair.cpp | 3 +-- src/pair.h | 4 ++++ src/pair_beck.cpp | 3 +-- src/pair_born.cpp | 3 +-- src/pair_born_coul_dsf.cpp | 3 +-- src/pair_born_coul_wolf.cpp | 3 +-- src/pair_buck.cpp | 3 +-- src/pair_buck_coul_cut.cpp | 3 +-- src/pair_coul_cut.cpp | 3 +-- src/pair_coul_debye.cpp | 3 +-- src/pair_coul_dsf.cpp | 3 +-- src/pair_coul_streitz.cpp | 3 +-- src/pair_coul_wolf.cpp | 3 +-- src/pair_dpd.cpp | 3 +-- src/pair_dpd_tstat.cpp | 3 +-- src/pair_gauss.cpp | 3 +-- src/pair_hybrid.cpp | 5 ++--- src/pair_lj96_cut.cpp | 6 ++---- src/pair_lj_cubic.cpp | 3 +-- src/pair_lj_cut.cpp | 6 ++---- src/pair_lj_cut_coul_cut.cpp | 3 +-- src/pair_lj_cut_coul_debye.cpp | 3 +-- src/pair_lj_cut_coul_dsf.cpp | 3 +-- src/pair_lj_cut_coul_wolf.cpp | 3 +-- src/pair_lj_expand.cpp | 3 +-- src/pair_lj_gromacs.cpp | 3 +-- src/pair_lj_gromacs_coul_gromacs.cpp | 3 +-- src/pair_lj_smooth.cpp | 3 +-- src/pair_lj_smooth_linear.cpp | 3 +-- src/pair_mie_cut.cpp | 6 ++---- src/pair_morse.cpp | 3 +-- src/pair_soft.cpp | 3 +-- src/pair_table.cpp | 3 +-- src/pair_ufm.cpp | 3 +-- src/pair_yukawa.cpp | 3 +-- src/pair_zbl.cpp | 3 +-- src/pair_zero.cpp | 3 +-- 424 files changed, 451 insertions(+), 1036 deletions(-) diff --git a/src/ASPHERE/pair_gayberne.cpp b/src/ASPHERE/pair_gayberne.cpp index 857541957e..3d4ed3f183 100644 --- a/src/ASPHERE/pair_gayberne.cpp +++ b/src/ASPHERE/pair_gayberne.cpp @@ -94,8 +94,7 @@ void PairGayBerne::compute(int eflag, int vflag) double *iquat,*jquat; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); AtomVecEllipsoid::Bonus *bonus = avec->bonus; int *ellipsoid = atom->ellipsoid; diff --git a/src/ASPHERE/pair_line_lj.cpp b/src/ASPHERE/pair_line_lj.cpp index 963ff985c4..4873b44dc4 100644 --- a/src/ASPHERE/pair_line_lj.cpp +++ b/src/ASPHERE/pair_line_lj.cpp @@ -77,8 +77,7 @@ void PairLineLJ::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/ASPHERE/pair_resquared.cpp b/src/ASPHERE/pair_resquared.cpp index c477b1b8cf..b100a5f184 100644 --- a/src/ASPHERE/pair_resquared.cpp +++ b/src/ASPHERE/pair_resquared.cpp @@ -85,8 +85,7 @@ void PairRESquared::compute(int eflag, int vflag) RE2Vars wi,wj; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/ASPHERE/pair_tri_lj.cpp b/src/ASPHERE/pair_tri_lj.cpp index 142caf3764..cefd73f976 100644 --- a/src/ASPHERE/pair_tri_lj.cpp +++ b/src/ASPHERE/pair_tri_lj.cpp @@ -77,8 +77,7 @@ void PairTriLJ::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); AtomVecTri::Bonus *bonus = avec->bonus; double **x = atom->x; diff --git a/src/BODY/pair_body_nparticle.cpp b/src/BODY/pair_body_nparticle.cpp index 80b45beb4e..f2eb2aa520 100644 --- a/src/BODY/pair_body_nparticle.cpp +++ b/src/BODY/pair_body_nparticle.cpp @@ -77,8 +77,7 @@ void PairBodyNparticle::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/BODY/pair_body_rounded_polygon.cpp b/src/BODY/pair_body_rounded_polygon.cpp index b6dcab29ae..69495ea57f 100644 --- a/src/BODY/pair_body_rounded_polygon.cpp +++ b/src/BODY/pair_body_rounded_polygon.cpp @@ -111,8 +111,7 @@ void PairBodyRoundedPolygon::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/BODY/pair_body_rounded_polyhedron.cpp b/src/BODY/pair_body_rounded_polyhedron.cpp index 1a4653ce53..60f6df3582 100644 --- a/src/BODY/pair_body_rounded_polyhedron.cpp +++ b/src/BODY/pair_body_rounded_polyhedron.cpp @@ -127,8 +127,7 @@ void PairBodyRoundedPolyhedron::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp index e6546b1acc..b71c34d795 100644 --- a/src/CLASS2/pair_lj_class2.cpp +++ b/src/CLASS2/pair_lj_class2.cpp @@ -65,8 +65,7 @@ void PairLJClass2::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp index 49242ecb43..7fabe3c7c7 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.cpp +++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp @@ -70,8 +70,7 @@ void PairLJClass2CoulCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp index bbea2ade6e..0171350443 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.cpp +++ b/src/CLASS2/pair_lj_class2_coul_long.cpp @@ -82,8 +82,7 @@ void PairLJClass2CoulLong::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/COLLOID/pair_brownian.cpp b/src/COLLOID/pair_brownian.cpp index e532c06c86..aefa96b1fb 100644 --- a/src/COLLOID/pair_brownian.cpp +++ b/src/COLLOID/pair_brownian.cpp @@ -80,8 +80,7 @@ void PairBrownian::compute(int eflag, int vflag) double rsq,r,h_sep,radi; int *ilist,*jlist,*numneigh,**firstneigh; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/COLLOID/pair_brownian_poly.cpp b/src/COLLOID/pair_brownian_poly.cpp index c6d5def2fa..389ae084b7 100644 --- a/src/COLLOID/pair_brownian_poly.cpp +++ b/src/COLLOID/pair_brownian_poly.cpp @@ -66,8 +66,7 @@ void PairBrownianPoly::compute(int eflag, int vflag) double rsq,r,h_sep,beta0,beta1,radi,radj; int *ilist,*jlist,*numneigh,**firstneigh; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/COLLOID/pair_colloid.cpp b/src/COLLOID/pair_colloid.cpp index c16dbf41af..04c35a7c00 100644 --- a/src/COLLOID/pair_colloid.cpp +++ b/src/COLLOID/pair_colloid.cpp @@ -78,8 +78,7 @@ void PairColloid::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/COLLOID/pair_lubricate.cpp b/src/COLLOID/pair_lubricate.cpp index de53d91818..4e629bd442 100644 --- a/src/COLLOID/pair_lubricate.cpp +++ b/src/COLLOID/pair_lubricate.cpp @@ -88,8 +88,7 @@ void PairLubricate::compute(int eflag, int vflag) double vxmu2f = force->vxmu2f; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/COLLOID/pair_lubricateU.cpp b/src/COLLOID/pair_lubricateU.cpp index 35fe33c84e..3ea3d4fe4a 100644 --- a/src/COLLOID/pair_lubricateU.cpp +++ b/src/COLLOID/pair_lubricateU.cpp @@ -116,8 +116,7 @@ void PairLubricateU::compute(int eflag, int vflag) int nghost = atom->nghost; int nall = nlocal + nghost; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // skip compute() if called from integrate::setup() // this is b/c do not want compute() to update velocities twice on a restart diff --git a/src/COLLOID/pair_lubricateU_poly.cpp b/src/COLLOID/pair_lubricateU_poly.cpp index 90ac848d26..4fec95dcd8 100644 --- a/src/COLLOID/pair_lubricateU_poly.cpp +++ b/src/COLLOID/pair_lubricateU_poly.cpp @@ -78,8 +78,7 @@ void PairLubricateUPoly::compute(int eflag, int vflag) double **f = atom->f; double **torque = atom->torque; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // grow per-atom arrays if necessary // need to be atom->nmax in length diff --git a/src/COLLOID/pair_lubricate_poly.cpp b/src/COLLOID/pair_lubricate_poly.cpp index 5e52933364..ffbe7fce3c 100644 --- a/src/COLLOID/pair_lubricate_poly.cpp +++ b/src/COLLOID/pair_lubricate_poly.cpp @@ -72,8 +72,7 @@ void PairLubricatePoly::compute(int eflag, int vflag) double vxmu2f = force->vxmu2f; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/COLLOID/pair_yukawa_colloid.cpp b/src/COLLOID/pair_yukawa_colloid.cpp index d21bc43524..ab7d088508 100644 --- a/src/COLLOID/pair_yukawa_colloid.cpp +++ b/src/COLLOID/pair_yukawa_colloid.cpp @@ -46,8 +46,7 @@ void PairYukawaColloid::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_born_coul_dsf_cs.cpp b/src/CORESHELL/pair_born_coul_dsf_cs.cpp index 549c7c0348..f4d7447ade 100644 --- a/src/CORESHELL/pair_born_coul_dsf_cs.cpp +++ b/src/CORESHELL/pair_born_coul_dsf_cs.cpp @@ -57,8 +57,7 @@ void PairBornCoulDSFCS::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_born_coul_long_cs.cpp b/src/CORESHELL/pair_born_coul_long_cs.cpp index 76f6eb387d..a19f8c34a8 100644 --- a/src/CORESHELL/pair_born_coul_long_cs.cpp +++ b/src/CORESHELL/pair_born_coul_long_cs.cpp @@ -68,8 +68,7 @@ void PairBornCoulLongCS::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_born_coul_wolf_cs.cpp b/src/CORESHELL/pair_born_coul_wolf_cs.cpp index 84179ce50a..7b52c28664 100644 --- a/src/CORESHELL/pair_born_coul_wolf_cs.cpp +++ b/src/CORESHELL/pair_born_coul_wolf_cs.cpp @@ -53,8 +53,7 @@ void PairBornCoulWolfCS::compute(int eflag, int vflag) double erfcc,erfcd,v_sh,dvdrr,e_self,e_shift,f_shift,qisq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_buck_coul_long_cs.cpp b/src/CORESHELL/pair_buck_coul_long_cs.cpp index ea072d44a1..8df91f39a3 100644 --- a/src/CORESHELL/pair_buck_coul_long_cs.cpp +++ b/src/CORESHELL/pair_buck_coul_long_cs.cpp @@ -68,8 +68,7 @@ void PairBuckCoulLongCS::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_coul_long_cs.cpp b/src/CORESHELL/pair_coul_long_cs.cpp index b214653841..c8c8387d6d 100644 --- a/src/CORESHELL/pair_coul_long_cs.cpp +++ b/src/CORESHELL/pair_coul_long_cs.cpp @@ -69,8 +69,7 @@ void PairCoulLongCS::compute(int eflag, int vflag) double rsq; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_coul_wolf_cs.cpp b/src/CORESHELL/pair_coul_wolf_cs.cpp index b50f14833e..36e037bfc8 100644 --- a/src/CORESHELL/pair_coul_wolf_cs.cpp +++ b/src/CORESHELL/pair_coul_wolf_cs.cpp @@ -53,8 +53,7 @@ void PairCoulWolfCS::compute(int eflag, int vflag) double erfcc,erfcd,v_sh,dvdrr,e_self,e_shift,f_shift,qisq; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/CORESHELL/pair_lj_cut_coul_long_cs.cpp b/src/CORESHELL/pair_lj_cut_coul_long_cs.cpp index 8caefc0e66..56c75f0f5d 100644 --- a/src/CORESHELL/pair_lj_cut_coul_long_cs.cpp +++ b/src/CORESHELL/pair_lj_cut_coul_long_cs.cpp @@ -74,8 +74,7 @@ void PairLJCutCoulLongCS::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -399,8 +398,7 @@ void PairLJCutCoulLongCS::compute_outer(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/DIPOLE/pair_lj_cut_dipole_cut.cpp b/src/DIPOLE/pair_lj_cut_dipole_cut.cpp index 6af9b45724..18b78c55e0 100644 --- a/src/DIPOLE/pair_lj_cut_dipole_cut.cpp +++ b/src/DIPOLE/pair_lj_cut_dipole_cut.cpp @@ -69,8 +69,7 @@ void PairLJCutDipoleCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/DIPOLE/pair_lj_cut_dipole_long.cpp b/src/DIPOLE/pair_lj_cut_dipole_long.cpp index 817a120e3d..0806d1ee73 100644 --- a/src/DIPOLE/pair_lj_cut_dipole_long.cpp +++ b/src/DIPOLE/pair_lj_cut_dipole_long.cpp @@ -90,8 +90,7 @@ void PairLJCutDipoleLong::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/DIPOLE/pair_lj_long_dipole_long.cpp b/src/DIPOLE/pair_lj_long_dipole_long.cpp index 21fc035854..fbdc47a15b 100644 --- a/src/DIPOLE/pair_lj_long_dipole_long.cpp +++ b/src/DIPOLE/pair_lj_long_dipole_long.cpp @@ -405,8 +405,7 @@ void PairLJLongDipoleLong::compute(int eflag, int vflag) double evdwl,ecoul,fpair; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x, *x0 = x[0]; double **mu = atom->mu, *mu0 = mu[0], *imu, *jmu; diff --git a/src/GPU/pair_beck_gpu.cpp b/src/GPU/pair_beck_gpu.cpp index e65c53d194..9f76975ef1 100644 --- a/src/GPU/pair_beck_gpu.cpp +++ b/src/GPU/pair_beck_gpu.cpp @@ -84,8 +84,7 @@ PairBeckGPU::~PairBeckGPU() void PairBeckGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_born_coul_long_cs_gpu.cpp b/src/GPU/pair_born_coul_long_cs_gpu.cpp index 587c7b5215..291ad8ad1f 100644 --- a/src/GPU/pair_born_coul_long_cs_gpu.cpp +++ b/src/GPU/pair_born_coul_long_cs_gpu.cpp @@ -106,8 +106,7 @@ PairBornCoulLongCSGPU::~PairBornCoulLongCSGPU() void PairBornCoulLongCSGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_born_coul_long_gpu.cpp b/src/GPU/pair_born_coul_long_gpu.cpp index 1549ed79af..eb204691c7 100644 --- a/src/GPU/pair_born_coul_long_gpu.cpp +++ b/src/GPU/pair_born_coul_long_gpu.cpp @@ -101,8 +101,7 @@ PairBornCoulLongGPU::~PairBornCoulLongGPU() void PairBornCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_born_coul_wolf_cs_gpu.cpp b/src/GPU/pair_born_coul_wolf_cs_gpu.cpp index bf23007bca..4877a442b5 100644 --- a/src/GPU/pair_born_coul_wolf_cs_gpu.cpp +++ b/src/GPU/pair_born_coul_wolf_cs_gpu.cpp @@ -94,8 +94,7 @@ PairBornCoulWolfCSGPU::~PairBornCoulWolfCSGPU() void PairBornCoulWolfCSGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_born_coul_wolf_gpu.cpp b/src/GPU/pair_born_coul_wolf_gpu.cpp index 06a2769e10..851174988b 100644 --- a/src/GPU/pair_born_coul_wolf_gpu.cpp +++ b/src/GPU/pair_born_coul_wolf_gpu.cpp @@ -92,8 +92,7 @@ PairBornCoulWolfGPU::~PairBornCoulWolfGPU() void PairBornCoulWolfGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_born_gpu.cpp b/src/GPU/pair_born_gpu.cpp index 01e91a9c0b..253d2d7282 100644 --- a/src/GPU/pair_born_gpu.cpp +++ b/src/GPU/pair_born_gpu.cpp @@ -87,8 +87,7 @@ PairBornGPU::~PairBornGPU() void PairBornGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_buck_coul_cut_gpu.cpp b/src/GPU/pair_buck_coul_cut_gpu.cpp index ce71e9ac41..ed602f9cab 100644 --- a/src/GPU/pair_buck_coul_cut_gpu.cpp +++ b/src/GPU/pair_buck_coul_cut_gpu.cpp @@ -88,8 +88,7 @@ PairBuckCoulCutGPU::~PairBuckCoulCutGPU() void PairBuckCoulCutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_buck_coul_long_gpu.cpp b/src/GPU/pair_buck_coul_long_gpu.cpp index a2d14ea25f..d6b9e53282 100644 --- a/src/GPU/pair_buck_coul_long_gpu.cpp +++ b/src/GPU/pair_buck_coul_long_gpu.cpp @@ -97,8 +97,7 @@ PairBuckCoulLongGPU::~PairBuckCoulLongGPU() void PairBuckCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_buck_gpu.cpp b/src/GPU/pair_buck_gpu.cpp index e6479e46e8..8c85407e6e 100644 --- a/src/GPU/pair_buck_gpu.cpp +++ b/src/GPU/pair_buck_gpu.cpp @@ -85,8 +85,7 @@ PairBuckGPU::~PairBuckGPU() void PairBuckGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_colloid_gpu.cpp b/src/GPU/pair_colloid_gpu.cpp index 03e5aac5d5..0ee8708b5b 100644 --- a/src/GPU/pair_colloid_gpu.cpp +++ b/src/GPU/pair_colloid_gpu.cpp @@ -85,8 +85,7 @@ PairColloidGPU::~PairColloidGPU() void PairColloidGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_coul_cut_gpu.cpp b/src/GPU/pair_coul_cut_gpu.cpp index 436d26fb54..fb50c446b1 100644 --- a/src/GPU/pair_coul_cut_gpu.cpp +++ b/src/GPU/pair_coul_cut_gpu.cpp @@ -85,8 +85,7 @@ PairCoulCutGPU::~PairCoulCutGPU() void PairCoulCutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_coul_debye_gpu.cpp b/src/GPU/pair_coul_debye_gpu.cpp index c17e21f41f..ec771a9935 100644 --- a/src/GPU/pair_coul_debye_gpu.cpp +++ b/src/GPU/pair_coul_debye_gpu.cpp @@ -86,8 +86,7 @@ PairCoulDebyeGPU::~PairCoulDebyeGPU() void PairCoulDebyeGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_coul_dsf_gpu.cpp b/src/GPU/pair_coul_dsf_gpu.cpp index 15a15660dd..1753b8a91c 100644 --- a/src/GPU/pair_coul_dsf_gpu.cpp +++ b/src/GPU/pair_coul_dsf_gpu.cpp @@ -97,8 +97,7 @@ PairCoulDSFGPU::~PairCoulDSFGPU() void PairCoulDSFGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_coul_long_cs_gpu.cpp b/src/GPU/pair_coul_long_cs_gpu.cpp index be2a090786..6ca00d6361 100644 --- a/src/GPU/pair_coul_long_cs_gpu.cpp +++ b/src/GPU/pair_coul_long_cs_gpu.cpp @@ -99,8 +99,7 @@ PairCoulLongCSGPU::~PairCoulLongCSGPU() void PairCoulLongCSGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_coul_long_gpu.cpp b/src/GPU/pair_coul_long_gpu.cpp index 684b0049c0..f75d10b6dd 100644 --- a/src/GPU/pair_coul_long_gpu.cpp +++ b/src/GPU/pair_coul_long_gpu.cpp @@ -94,8 +94,7 @@ PairCoulLongGPU::~PairCoulLongGPU() void PairCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_dpd_gpu.cpp b/src/GPU/pair_dpd_gpu.cpp index 7d56b47fe5..b1e45fbecd 100644 --- a/src/GPU/pair_dpd_gpu.cpp +++ b/src/GPU/pair_dpd_gpu.cpp @@ -225,8 +225,7 @@ PairDPDGPU::~PairDPDGPU() void PairDPDGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_dpd_tstat_gpu.cpp b/src/GPU/pair_dpd_tstat_gpu.cpp index f093c03a2d..0693a27344 100644 --- a/src/GPU/pair_dpd_tstat_gpu.cpp +++ b/src/GPU/pair_dpd_tstat_gpu.cpp @@ -228,8 +228,7 @@ PairDPDTstatGPU::~PairDPDTstatGPU() void PairDPDTstatGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // adjust sigma if target T is changing diff --git a/src/GPU/pair_eam_alloy_gpu.cpp b/src/GPU/pair_eam_alloy_gpu.cpp index c472b91fc8..9b3412d3d1 100644 --- a/src/GPU/pair_eam_alloy_gpu.cpp +++ b/src/GPU/pair_eam_alloy_gpu.cpp @@ -94,8 +94,7 @@ double PairEAMAlloyGPU::memory_usage() void PairEAMAlloyGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); // compute density on each atom on GPU diff --git a/src/GPU/pair_eam_fs_gpu.cpp b/src/GPU/pair_eam_fs_gpu.cpp index 821bb1af1c..11ef28af3e 100644 --- a/src/GPU/pair_eam_fs_gpu.cpp +++ b/src/GPU/pair_eam_fs_gpu.cpp @@ -92,8 +92,7 @@ double PairEAMFSGPU::memory_usage() void PairEAMFSGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); // compute density on each atom on GPU diff --git a/src/GPU/pair_eam_gpu.cpp b/src/GPU/pair_eam_gpu.cpp index 515a349ad2..4788a72417 100644 --- a/src/GPU/pair_eam_gpu.cpp +++ b/src/GPU/pair_eam_gpu.cpp @@ -95,8 +95,7 @@ double PairEAMGPU::memory_usage() void PairEAMGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); // compute density on each atom on GPU diff --git a/src/GPU/pair_gauss_gpu.cpp b/src/GPU/pair_gauss_gpu.cpp index 71fb55f4d0..c596a9d644 100644 --- a/src/GPU/pair_gauss_gpu.cpp +++ b/src/GPU/pair_gauss_gpu.cpp @@ -82,8 +82,7 @@ PairGaussGPU::~PairGaussGPU() void PairGaussGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_gayberne_gpu.cpp b/src/GPU/pair_gayberne_gpu.cpp index 32b8b979cd..4ed2750e57 100644 --- a/src/GPU/pair_gayberne_gpu.cpp +++ b/src/GPU/pair_gayberne_gpu.cpp @@ -92,8 +92,7 @@ PairGayBerneGPU::~PairGayBerneGPU() void PairGayBerneGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj96_cut_gpu.cpp b/src/GPU/pair_lj96_cut_gpu.cpp index 707d632d9a..5bc30c809d 100644 --- a/src/GPU/pair_lj96_cut_gpu.cpp +++ b/src/GPU/pair_lj96_cut_gpu.cpp @@ -82,8 +82,7 @@ PairLJ96CutGPU::~PairLJ96CutGPU() void PairLJ96CutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_charmm_coul_long_gpu.cpp b/src/GPU/pair_lj_charmm_coul_long_gpu.cpp index ebc9f88943..134295c69f 100644 --- a/src/GPU/pair_lj_charmm_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_charmm_coul_long_gpu.cpp @@ -99,8 +99,7 @@ PairLJCharmmCoulLongGPU::~PairLJCharmmCoulLongGPU() void PairLJCharmmCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_class2_coul_long_gpu.cpp b/src/GPU/pair_lj_class2_coul_long_gpu.cpp index 797680c032..fdffb06a8d 100644 --- a/src/GPU/pair_lj_class2_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_class2_coul_long_gpu.cpp @@ -96,8 +96,7 @@ PairLJClass2CoulLongGPU::~PairLJClass2CoulLongGPU() void PairLJClass2CoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_class2_gpu.cpp b/src/GPU/pair_lj_class2_gpu.cpp index 8a9b2b31e8..bbb9168169 100644 --- a/src/GPU/pair_lj_class2_gpu.cpp +++ b/src/GPU/pair_lj_class2_gpu.cpp @@ -81,8 +81,7 @@ PairLJClass2GPU::~PairLJClass2GPU() void PairLJClass2GPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cubic_gpu.cpp b/src/GPU/pair_lj_cubic_gpu.cpp index 669eae4ee4..95eee6ae8f 100644 --- a/src/GPU/pair_lj_cubic_gpu.cpp +++ b/src/GPU/pair_lj_cubic_gpu.cpp @@ -86,8 +86,7 @@ PairLJCubicGPU::~PairLJCubicGPU() void PairLJCubicGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp index 99c7bb1c66..69fefbcdea 100644 --- a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp @@ -87,8 +87,7 @@ PairLJCutCoulCutGPU::~PairLJCutCoulCutGPU() void PairLJCutCoulCutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cut_coul_debye_gpu.cpp b/src/GPU/pair_lj_cut_coul_debye_gpu.cpp index 450eca5c47..de86c58647 100644 --- a/src/GPU/pair_lj_cut_coul_debye_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_debye_gpu.cpp @@ -89,8 +89,7 @@ ljcd_gpu_clear(); void PairLJCutCoulDebyeGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cut_coul_dsf_gpu.cpp b/src/GPU/pair_lj_cut_coul_dsf_gpu.cpp index abe7394a8c..87eac52749 100644 --- a/src/GPU/pair_lj_cut_coul_dsf_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_dsf_gpu.cpp @@ -98,8 +98,7 @@ PairLJCutCoulDSFGPU::~PairLJCutCoulDSFGPU() void PairLJCutCoulDSFGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cut_coul_long_gpu.cpp b/src/GPU/pair_lj_cut_coul_long_gpu.cpp index 943d12b0fe..c854dab83d 100644 --- a/src/GPU/pair_lj_cut_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_long_gpu.cpp @@ -99,8 +99,7 @@ PairLJCutCoulLongGPU::~PairLJCutCoulLongGPU() void PairLJCutCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cut_coul_msm_gpu.cpp b/src/GPU/pair_lj_cut_coul_msm_gpu.cpp index 46cf6f19bc..f87dc0ec91 100644 --- a/src/GPU/pair_lj_cut_coul_msm_gpu.cpp +++ b/src/GPU/pair_lj_cut_coul_msm_gpu.cpp @@ -88,8 +88,7 @@ PairLJCutCoulMSMGPU::~PairLJCutCoulMSMGPU() void PairLJCutCoulMSMGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_cut_dipole_cut_gpu.cpp b/src/GPU/pair_lj_cut_dipole_cut_gpu.cpp index 1f4528cb88..d2c925d950 100644 --- a/src/GPU/pair_lj_cut_dipole_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_dipole_cut_gpu.cpp @@ -89,8 +89,7 @@ PairLJCutDipoleCutGPU::~PairLJCutDipoleCutGPU() void PairLJCutDipoleCutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; @@ -199,8 +198,7 @@ void PairLJCutDipoleCutGPU::cpu_compute(int start, int inum, int eflag, int vfla int *jlist; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/GPU/pair_lj_cut_dipole_long_gpu.cpp b/src/GPU/pair_lj_cut_dipole_long_gpu.cpp index b209fa0ee7..774ff2fae4 100644 --- a/src/GPU/pair_lj_cut_dipole_long_gpu.cpp +++ b/src/GPU/pair_lj_cut_dipole_long_gpu.cpp @@ -100,8 +100,7 @@ PairLJCutDipoleLongGPU::~PairLJCutDipoleLongGPU() void PairLJCutDipoleLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; @@ -228,8 +227,7 @@ void PairLJCutDipoleLongGPU::cpu_compute(int start, int inum, int eflag, int vfl int *jlist; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/GPU/pair_lj_cut_gpu.cpp b/src/GPU/pair_lj_cut_gpu.cpp index 9a6be3aab9..6dde9689f7 100644 --- a/src/GPU/pair_lj_cut_gpu.cpp +++ b/src/GPU/pair_lj_cut_gpu.cpp @@ -86,8 +86,7 @@ PairLJCutGPU::~PairLJCutGPU() void PairLJCutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_expand_coul_long_gpu.cpp b/src/GPU/pair_lj_expand_coul_long_gpu.cpp index 4161155980..31f4fd651c 100644 --- a/src/GPU/pair_lj_expand_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_expand_coul_long_gpu.cpp @@ -99,8 +99,7 @@ PairLJExpandCoulLongGPU::~PairLJExpandCoulLongGPU() void PairLJExpandCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_expand_gpu.cpp b/src/GPU/pair_lj_expand_gpu.cpp index 36378bf10e..a2e1cf54e3 100644 --- a/src/GPU/pair_lj_expand_gpu.cpp +++ b/src/GPU/pair_lj_expand_gpu.cpp @@ -85,8 +85,7 @@ PairLJExpandGPU::~PairLJExpandGPU() void PairLJExpandGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_gromacs_gpu.cpp b/src/GPU/pair_lj_gromacs_gpu.cpp index cc7010b295..e03f4b2e50 100644 --- a/src/GPU/pair_lj_gromacs_gpu.cpp +++ b/src/GPU/pair_lj_gromacs_gpu.cpp @@ -87,8 +87,7 @@ PairLJGromacsGPU::~PairLJGromacsGPU() void PairLJGromacsGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_sdk_coul_long_gpu.cpp b/src/GPU/pair_lj_sdk_coul_long_gpu.cpp index 4dbd8874d6..f5029df5dc 100644 --- a/src/GPU/pair_lj_sdk_coul_long_gpu.cpp +++ b/src/GPU/pair_lj_sdk_coul_long_gpu.cpp @@ -102,8 +102,7 @@ PairLJSDKCoulLongGPU::~PairLJSDKCoulLongGPU() void PairLJSDKCoulLongGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_sdk_gpu.cpp b/src/GPU/pair_lj_sdk_gpu.cpp index 84d224a8c4..4797a34408 100644 --- a/src/GPU/pair_lj_sdk_gpu.cpp +++ b/src/GPU/pair_lj_sdk_gpu.cpp @@ -87,8 +87,7 @@ PairLJSDKGPU::~PairLJSDKGPU() void PairLJSDKGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_lj_sf_dipole_sf_gpu.cpp b/src/GPU/pair_lj_sf_dipole_sf_gpu.cpp index a5ebb1dbc1..dd25a70eee 100644 --- a/src/GPU/pair_lj_sf_dipole_sf_gpu.cpp +++ b/src/GPU/pair_lj_sf_dipole_sf_gpu.cpp @@ -88,8 +88,7 @@ PairLJSFDipoleSFGPU::~PairLJSFDipoleSFGPU() void PairLJSFDipoleSFGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; @@ -202,8 +201,7 @@ void PairLJSFDipoleSFGPU::cpu_compute(int start, int inum, int eflag, int vflag, int *jlist; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/GPU/pair_mie_cut_gpu.cpp b/src/GPU/pair_mie_cut_gpu.cpp index e52577ee4c..838d28033f 100644 --- a/src/GPU/pair_mie_cut_gpu.cpp +++ b/src/GPU/pair_mie_cut_gpu.cpp @@ -83,8 +83,7 @@ PairMIECutGPU::~PairMIECutGPU() void PairMIECutGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_morse_gpu.cpp b/src/GPU/pair_morse_gpu.cpp index 7abf78ff30..1f94643e3a 100644 --- a/src/GPU/pair_morse_gpu.cpp +++ b/src/GPU/pair_morse_gpu.cpp @@ -81,8 +81,7 @@ PairMorseGPU::~PairMorseGPU() void PairMorseGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_resquared_gpu.cpp b/src/GPU/pair_resquared_gpu.cpp index b6fada0897..5e90f788bf 100644 --- a/src/GPU/pair_resquared_gpu.cpp +++ b/src/GPU/pair_resquared_gpu.cpp @@ -94,8 +94,7 @@ PairRESquaredGPU::~PairRESquaredGPU() void PairRESquaredGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_soft_gpu.cpp b/src/GPU/pair_soft_gpu.cpp index eed1bd5db3..42adb02553 100644 --- a/src/GPU/pair_soft_gpu.cpp +++ b/src/GPU/pair_soft_gpu.cpp @@ -86,8 +86,7 @@ PairSoftGPU::~PairSoftGPU() void PairSoftGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_sw_gpu.cpp b/src/GPU/pair_sw_gpu.cpp index 5368bee959..0cc858e57d 100644 --- a/src/GPU/pair_sw_gpu.cpp +++ b/src/GPU/pair_sw_gpu.cpp @@ -93,8 +93,7 @@ PairSWGPU::~PairSWGPU() void PairSWGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_table_gpu.cpp b/src/GPU/pair_table_gpu.cpp index d0185b85e8..a0b6562e5e 100644 --- a/src/GPU/pair_table_gpu.cpp +++ b/src/GPU/pair_table_gpu.cpp @@ -89,8 +89,7 @@ PairTableGPU::~PairTableGPU() void PairTableGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_tersoff_gpu.cpp b/src/GPU/pair_tersoff_gpu.cpp index 535b56163e..cd0c5e6693 100644 --- a/src/GPU/pair_tersoff_gpu.cpp +++ b/src/GPU/pair_tersoff_gpu.cpp @@ -97,8 +97,7 @@ PairTersoffGPU::~PairTersoffGPU() void PairTersoffGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_tersoff_mod_gpu.cpp b/src/GPU/pair_tersoff_mod_gpu.cpp index f8b6c50db5..fd55ddc6e6 100644 --- a/src/GPU/pair_tersoff_mod_gpu.cpp +++ b/src/GPU/pair_tersoff_mod_gpu.cpp @@ -90,8 +90,7 @@ PairTersoffMODGPU::~PairTersoffMODGPU() void PairTersoffMODGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_tersoff_zbl_gpu.cpp b/src/GPU/pair_tersoff_zbl_gpu.cpp index b45503d759..d3828962e2 100644 --- a/src/GPU/pair_tersoff_zbl_gpu.cpp +++ b/src/GPU/pair_tersoff_zbl_gpu.cpp @@ -98,8 +98,7 @@ PairTersoffZBLGPU::~PairTersoffZBLGPU() void PairTersoffZBLGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_ufm_gpu.cpp b/src/GPU/pair_ufm_gpu.cpp index 688e3ef4dc..31422b0f4d 100644 --- a/src/GPU/pair_ufm_gpu.cpp +++ b/src/GPU/pair_ufm_gpu.cpp @@ -88,8 +88,7 @@ PairUFMGPU::~PairUFMGPU() void PairUFMGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_vashishta_gpu.cpp b/src/GPU/pair_vashishta_gpu.cpp index 84936f2c26..b496359b8a 100644 --- a/src/GPU/pair_vashishta_gpu.cpp +++ b/src/GPU/pair_vashishta_gpu.cpp @@ -94,8 +94,7 @@ PairVashishtaGPU::~PairVashishtaGPU() void PairVashishtaGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_yukawa_colloid_gpu.cpp b/src/GPU/pair_yukawa_colloid_gpu.cpp index 556dece7f8..3645f392a2 100644 --- a/src/GPU/pair_yukawa_colloid_gpu.cpp +++ b/src/GPU/pair_yukawa_colloid_gpu.cpp @@ -84,8 +84,7 @@ PairYukawaColloidGPU::~PairYukawaColloidGPU() void PairYukawaColloidGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_yukawa_gpu.cpp b/src/GPU/pair_yukawa_gpu.cpp index 9d3ea6f5a7..90317fea34 100644 --- a/src/GPU/pair_yukawa_gpu.cpp +++ b/src/GPU/pair_yukawa_gpu.cpp @@ -83,8 +83,7 @@ PairYukawaGPU::~PairYukawaGPU() void PairYukawaGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GPU/pair_zbl_gpu.cpp b/src/GPU/pair_zbl_gpu.cpp index c9b8dd75a1..99471cbe90 100644 --- a/src/GPU/pair_zbl_gpu.cpp +++ b/src/GPU/pair_zbl_gpu.cpp @@ -86,8 +86,7 @@ PairZBLGPU::~PairZBLGPU() void PairZBLGPU::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int nall = atom->nlocal + atom->nghost; int inum, host_start; diff --git a/src/GRANULAR/pair_gran_hertz_history.cpp b/src/GRANULAR/pair_gran_hertz_history.cpp index d1f3c7bbe1..728491c17a 100644 --- a/src/GRANULAR/pair_gran_hertz_history.cpp +++ b/src/GRANULAR/pair_gran_hertz_history.cpp @@ -55,8 +55,7 @@ void PairGranHertzHistory::compute(int eflag, int vflag) int *touch,**firsttouch; double *shear,*allshear,**firstshear; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int shearupdate = 1; if (update->setupflag) shearupdate = 0; diff --git a/src/GRANULAR/pair_gran_hooke.cpp b/src/GRANULAR/pair_gran_hooke.cpp index 5244396ead..cfcc2743ba 100644 --- a/src/GRANULAR/pair_gran_hooke.cpp +++ b/src/GRANULAR/pair_gran_hooke.cpp @@ -51,8 +51,7 @@ void PairGranHooke::compute(int eflag, int vflag) double fn,fs,ft,fs1,fs2,fs3; int *ilist,*jlist,*numneigh,**firstneigh; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // update rigid body info for owned & ghost atoms if using FixRigid masses // body[i] = which body atom I is in, -1 if none diff --git a/src/GRANULAR/pair_gran_hooke_history.cpp b/src/GRANULAR/pair_gran_hooke_history.cpp index 83f75c221d..cec825316c 100644 --- a/src/GRANULAR/pair_gran_hooke_history.cpp +++ b/src/GRANULAR/pair_gran_hooke_history.cpp @@ -98,8 +98,7 @@ void PairGranHookeHistory::compute(int eflag, int vflag) int *touch,**firsttouch; double *shear,*allshear,**firstshear; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int shearupdate = 1; if (update->setupflag) shearupdate = 0; diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index a4517b848c..84842f87cc 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -191,10 +191,7 @@ void PairKIM::compute(int eflag , int vflag) { int kimerror; - if (eflag || vflag) - ev_setup(eflag,vflag); - else - ev_unset(); + ev_init(eflag,vflag); // grow kim_particleSpecies and kim_particleContributing array if necessary // needs to be atom->nmax in length diff --git a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp index 18d09965be..57ac3a9c57 100644 --- a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp @@ -92,8 +92,7 @@ void PairBuckCoulCutKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp index 0b44a83ebb..349c4c0601 100644 --- a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp @@ -111,8 +111,7 @@ void PairBuckCoulLongKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_buck_kokkos.cpp b/src/KOKKOS/pair_buck_kokkos.cpp index 999aefe4c3..02c02c986e 100644 --- a/src/KOKKOS/pair_buck_kokkos.cpp +++ b/src/KOKKOS/pair_buck_kokkos.cpp @@ -81,8 +81,7 @@ void PairBuckKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_coul_cut_kokkos.cpp b/src/KOKKOS/pair_coul_cut_kokkos.cpp index 7d29adc625..54ba0b63ce 100644 --- a/src/KOKKOS/pair_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_coul_cut_kokkos.cpp @@ -80,8 +80,7 @@ void PairCoulCutKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_coul_debye_kokkos.cpp b/src/KOKKOS/pair_coul_debye_kokkos.cpp index 3de83b5bc4..8966e30394 100644 --- a/src/KOKKOS/pair_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_coul_debye_kokkos.cpp @@ -87,8 +87,7 @@ void PairCoulDebyeKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index 7d03ee4968..748fed71a7 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -80,8 +80,7 @@ void PairCoulDSFKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_coul_long_kokkos.cpp b/src/KOKKOS/pair_coul_long_kokkos.cpp index 73b9521da0..a21cb050ff 100644 --- a/src/KOKKOS/pair_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_coul_long_kokkos.cpp @@ -104,8 +104,7 @@ void PairCoulLongKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_kokkos.cpp index fe9c581cc1..20391d9530 100644 --- a/src/KOKKOS/pair_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_kokkos.cpp @@ -75,8 +75,7 @@ void PairCoulWolfKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp index d2fcc81ea4..a44ef1790e 100644 --- a/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp +++ b/src/KOKKOS/pair_dpd_fdt_energy_kokkos.cpp @@ -165,8 +165,7 @@ void PairDPDfdtEnergyKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index 6039282141..b580f00ed0 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -74,8 +74,7 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index 81d9ba8326..1b1ec5c31e 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -74,8 +74,7 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 22383f57c5..d423f2c927 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -68,8 +68,7 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_exp6_rx_kokkos.cpp b/src/KOKKOS/pair_exp6_rx_kokkos.cpp index df24a5f4c7..fa10c6d30f 100644 --- a/src/KOKKOS/pair_exp6_rx_kokkos.cpp +++ b/src/KOKKOS/pair_exp6_rx_kokkos.cpp @@ -147,8 +147,7 @@ void PairExp6rxKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp index 189407b541..068580b525 100644 --- a/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp +++ b/src/KOKKOS/pair_gran_hooke_history_kokkos.cpp @@ -111,8 +111,7 @@ void PairGranHookeHistoryKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); int shearupdate = 1; if (update->setupflag) shearupdate = 0; diff --git a/src/KOKKOS/pair_hybrid_kokkos.cpp b/src/KOKKOS/pair_hybrid_kokkos.cpp index 03ad77c34a..00df4a8f3c 100644 --- a/src/KOKKOS/pair_hybrid_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_kokkos.cpp @@ -78,9 +78,7 @@ void PairHybridKokkos::compute(int eflag, int vflag) if (no_virial_fdotr_compute && vflag % 4 == 2) vflag = 1 + vflag/4 * 4; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); // check if global component of incoming vflag = 2 // if so, reset vflag passed to substyle as if it were 0 diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp index ce7df2bec1..510740112a 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp @@ -112,8 +112,7 @@ void PairLJCharmmCoulCharmmImplicitKokkos::compute(int eflag_in, int if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp index b31282e595..51c96354f9 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp @@ -112,8 +112,7 @@ void PairLJCharmmCoulCharmmKokkos::compute(int eflag_in, int vflag_i if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp index 5d8a202aa4..22faa98935 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp @@ -112,8 +112,7 @@ void PairLJCharmmCoulLongKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp index 6eb3028101..60d480188b 100644 --- a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp @@ -89,8 +89,7 @@ void PairLJClass2CoulCutKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp index a388694876..4c8aea8e92 100644 --- a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp @@ -97,8 +97,7 @@ void PairLJClass2CoulLongKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_class2_kokkos.cpp b/src/KOKKOS/pair_lj_class2_kokkos.cpp index 33d1477443..dd42baa4e0 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_kokkos.cpp @@ -89,8 +89,7 @@ void PairLJClass2Kokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp index 6001fabbed..cb5ab96871 100644 --- a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp @@ -89,8 +89,7 @@ void PairLJCutCoulCutKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp index 10923bc5da..800092a09b 100644 --- a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp @@ -93,8 +93,7 @@ void PairLJCutCoulDebyeKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp index 47aa2ea7cc..f793485b47 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp @@ -101,8 +101,7 @@ void PairLJCutCoulDSFKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp index fa36cb1866..02150586f4 100644 --- a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp @@ -101,8 +101,7 @@ void PairLJCutCoulLongKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_kokkos.cpp index 9b0ff902af..4ba8c00f88 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_kokkos.cpp @@ -89,8 +89,7 @@ void PairLJCutKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_expand_kokkos.cpp b/src/KOKKOS/pair_lj_expand_kokkos.cpp index 3b8b9343d8..5ea6c9e438 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_kokkos.cpp @@ -88,8 +88,7 @@ void PairLJExpandKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp index d06ad9b44e..2421d059da 100644 --- a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp @@ -103,8 +103,7 @@ void PairLJGromacsCoulGromacsKokkos::compute(int eflag_in, int vflag if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp index d447846333..09a0261ae1 100644 --- a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp @@ -100,8 +100,7 @@ void PairLJGromacsKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_lj_sdk_kokkos.cpp b/src/KOKKOS/pair_lj_sdk_kokkos.cpp index 990e464341..c2375fa7a8 100644 --- a/src/KOKKOS/pair_lj_sdk_kokkos.cpp +++ b/src/KOKKOS/pair_lj_sdk_kokkos.cpp @@ -88,8 +88,7 @@ void PairLJSDKKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_morse_kokkos.cpp b/src/KOKKOS/pair_morse_kokkos.cpp index ab5eb817a1..b308330ead 100644 --- a/src/KOKKOS/pair_morse_kokkos.cpp +++ b/src/KOKKOS/pair_morse_kokkos.cpp @@ -93,8 +93,7 @@ void PairMorseKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp index 5f19d73dfa..7d17ac3f43 100644 --- a/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp +++ b/src/KOKKOS/pair_multi_lucy_rx_kokkos.cpp @@ -148,8 +148,7 @@ void PairMultiLucyRXKokkos::compute_style(int eflag_in, int vflag_in vflag = vflag_in; if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_reaxc_kokkos.cpp b/src/KOKKOS/pair_reaxc_kokkos.cpp index 56d2ebd8aa..c6ee50c6ac 100644 --- a/src/KOKKOS/pair_reaxc_kokkos.cpp +++ b/src/KOKKOS/pair_reaxc_kokkos.cpp @@ -677,8 +677,7 @@ void PairReaxCKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); atomKK->sync(execution_space,datamask_read); k_params_sing.template sync(); diff --git a/src/KOKKOS/pair_snap_kokkos_impl.h b/src/KOKKOS/pair_snap_kokkos_impl.h index 998e75fabe..569783f926 100644 --- a/src/KOKKOS/pair_snap_kokkos_impl.h +++ b/src/KOKKOS/pair_snap_kokkos_impl.h @@ -137,8 +137,7 @@ void PairSNAPKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index 24022475ab..da4737a2c1 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -80,8 +80,7 @@ void PairSWKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_table_kokkos.cpp b/src/KOKKOS/pair_table_kokkos.cpp index 9522e94706..737d600d1e 100644 --- a/src/KOKKOS/pair_table_kokkos.cpp +++ b/src/KOKKOS/pair_table_kokkos.cpp @@ -86,8 +86,7 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_table_rx_kokkos.cpp b/src/KOKKOS/pair_table_rx_kokkos.cpp index 376984afa2..ec7a2ffb94 100644 --- a/src/KOKKOS/pair_table_rx_kokkos.cpp +++ b/src/KOKKOS/pair_table_rx_kokkos.cpp @@ -619,8 +619,7 @@ void PairTableRXKokkos::compute_style(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); if (eflag_atom) { memoryKK->destroy_kokkos(k_eatom,eatom); diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index a6668ca064..9252e3de52 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -164,8 +164,7 @@ void PairTersoffKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 303d2bdfda..585074b128 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -164,8 +164,7 @@ void PairTersoffMODKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index ad4a2d444e..e1e2211ab5 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -178,8 +178,7 @@ void PairTersoffZBLKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_vashishta_kokkos.cpp b/src/KOKKOS/pair_vashishta_kokkos.cpp index 78ab8bfc85..4a1f291b17 100644 --- a/src/KOKKOS/pair_vashishta_kokkos.cpp +++ b/src/KOKKOS/pair_vashishta_kokkos.cpp @@ -79,8 +79,7 @@ void PairVashishtaKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_yukawa_kokkos.cpp b/src/KOKKOS/pair_yukawa_kokkos.cpp index 951613a33e..27e18533a2 100644 --- a/src/KOKKOS/pair_yukawa_kokkos.cpp +++ b/src/KOKKOS/pair_yukawa_kokkos.cpp @@ -177,8 +177,7 @@ void PairYukawaKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/pair_zbl_kokkos.cpp b/src/KOKKOS/pair_zbl_kokkos.cpp index bcf33b405d..06c84e5189 100644 --- a/src/KOKKOS/pair_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_zbl_kokkos.cpp @@ -129,8 +129,7 @@ void PairZBLKokkos::compute(int eflag_in, int vflag_in) if (neighflag == FULL) no_virial_fdotr_compute = 1; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KSPACE/pair_born_coul_long.cpp b/src/KSPACE/pair_born_coul_long.cpp index d55a5a3afe..f12f5779d9 100644 --- a/src/KSPACE/pair_born_coul_long.cpp +++ b/src/KSPACE/pair_born_coul_long.cpp @@ -87,8 +87,7 @@ void PairBornCoulLong::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_born_coul_msm.cpp b/src/KSPACE/pair_born_coul_msm.cpp index 775d26df95..eaa1c116c1 100644 --- a/src/KSPACE/pair_born_coul_msm.cpp +++ b/src/KSPACE/pair_born_coul_msm.cpp @@ -82,8 +82,7 @@ void PairBornCoulMSM::compute(int eflag, int vflag) } evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp index a37e4ab4e9..0d24ff2497 100644 --- a/src/KSPACE/pair_buck_coul_long.cpp +++ b/src/KSPACE/pair_buck_coul_long.cpp @@ -82,8 +82,7 @@ void PairBuckCoulLong::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_buck_coul_msm.cpp b/src/KSPACE/pair_buck_coul_msm.cpp index fc72f1a4d6..257d1b661f 100644 --- a/src/KSPACE/pair_buck_coul_msm.cpp +++ b/src/KSPACE/pair_buck_coul_msm.cpp @@ -79,8 +79,7 @@ void PairBuckCoulMSM::compute(int eflag, int vflag) } evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_buck_long_coul_long.cpp b/src/KSPACE/pair_buck_long_coul_long.cpp index d5bb7b6c5b..c7a4a4b2f6 100644 --- a/src/KSPACE/pair_buck_long_coul_long.cpp +++ b/src/KSPACE/pair_buck_long_coul_long.cpp @@ -445,8 +445,7 @@ void PairBuckLongCoulLong::compute(int eflag, int vflag) double evdwl,ecoul,fpair; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x, *x0 = x[0]; double **f = atom->f, *f0 = f[0], *fi = f0; @@ -785,8 +784,7 @@ void PairBuckLongCoulLong::compute_outer(int eflag, int vflag) { double evdwl,ecoul,fpair,fvirial; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x, *x0 = x[0]; double **f = atom->f, *f0 = f[0], *fi = f0; diff --git a/src/KSPACE/pair_coul_long.cpp b/src/KSPACE/pair_coul_long.cpp index 8db5979b39..7d519eee0a 100644 --- a/src/KSPACE/pair_coul_long.cpp +++ b/src/KSPACE/pair_coul_long.cpp @@ -79,8 +79,7 @@ void PairCoulLong::compute(int eflag, int vflag) double rsq; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_coul_msm.cpp b/src/KSPACE/pair_coul_msm.cpp index ab59dfa4c1..960505142c 100644 --- a/src/KSPACE/pair_coul_msm.cpp +++ b/src/KSPACE/pair_coul_msm.cpp @@ -67,8 +67,7 @@ void PairCoulMSM::compute(int eflag, int vflag) } ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_lj_charmm_coul_long.cpp b/src/KSPACE/pair_lj_charmm_coul_long.cpp index 749d9657aa..df2b943af2 100644 --- a/src/KSPACE/pair_lj_charmm_coul_long.cpp +++ b/src/KSPACE/pair_lj_charmm_coul_long.cpp @@ -96,8 +96,7 @@ void PairLJCharmmCoulLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -404,8 +403,7 @@ void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_lj_charmm_coul_msm.cpp b/src/KSPACE/pair_lj_charmm_coul_msm.cpp index aecadcf127..72a8e340bc 100644 --- a/src/KSPACE/pair_lj_charmm_coul_msm.cpp +++ b/src/KSPACE/pair_lj_charmm_coul_msm.cpp @@ -87,8 +87,7 @@ void PairLJCharmmCoulMSM::compute(int eflag, int vflag) } evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -265,8 +264,7 @@ void PairLJCharmmCoulMSM::compute_outer(int eflag, int vflag) "for rRESPA with kspace_style MSM"); evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp b/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp index 614980117e..0057197064 100644 --- a/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp +++ b/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp @@ -121,8 +121,7 @@ void PairLJCharmmfswCoulLong::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -452,8 +451,7 @@ void PairLJCharmmfswCoulLong::compute_outer(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp index c9530fe157..fde7fa8e35 100644 --- a/src/KSPACE/pair_lj_cut_coul_long.cpp +++ b/src/KSPACE/pair_lj_cut_coul_long.cpp @@ -90,8 +90,7 @@ void PairLJCutCoulLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -397,8 +396,7 @@ void PairLJCutCoulLong::compute_outer(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_lj_cut_coul_msm.cpp b/src/KSPACE/pair_lj_cut_coul_msm.cpp index 78c364bd6a..c2e566a117 100644 --- a/src/KSPACE/pair_lj_cut_coul_msm.cpp +++ b/src/KSPACE/pair_lj_cut_coul_msm.cpp @@ -87,8 +87,7 @@ void PairLJCutCoulMSM::compute(int eflag, int vflag) } evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -252,8 +251,7 @@ void PairLJCutCoulMSM::compute_outer(int eflag, int vflag) "for rRESPA with kspace_style MSM"); evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KSPACE/pair_lj_cut_tip4p_long.cpp b/src/KSPACE/pair_lj_cut_tip4p_long.cpp index d622a83b39..f5889fd520 100644 --- a/src/KSPACE/pair_lj_cut_tip4p_long.cpp +++ b/src/KSPACE/pair_lj_cut_tip4p_long.cpp @@ -94,8 +94,7 @@ void PairLJCutTIP4PLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/KSPACE/pair_lj_long_coul_long.cpp b/src/KSPACE/pair_lj_long_coul_long.cpp index 2de527ab39..493866a895 100644 --- a/src/KSPACE/pair_lj_long_coul_long.cpp +++ b/src/KSPACE/pair_lj_long_coul_long.cpp @@ -441,8 +441,7 @@ void PairLJLongCoulLong::compute(int eflag, int vflag) { double evdwl,ecoul,fpair; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x, *x0 = x[0]; double **f = atom->f, *f0 = f[0], *fi = f0; @@ -778,8 +777,7 @@ void PairLJLongCoulLong::compute_outer(int eflag, int vflag) { double evdwl,ecoul,fvirial,fpair; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x, *x0 = x[0]; double **f = atom->f, *f0 = f[0], *fi = f0; diff --git a/src/KSPACE/pair_lj_long_tip4p_long.cpp b/src/KSPACE/pair_lj_long_tip4p_long.cpp index a571e30fc3..3137b9d79a 100644 --- a/src/KSPACE/pair_lj_long_tip4p_long.cpp +++ b/src/KSPACE/pair_lj_long_tip4p_long.cpp @@ -92,8 +92,7 @@ void PairLJLongTIP4PLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred @@ -1004,8 +1003,7 @@ void PairLJLongTIP4PLong::compute_outer(int eflag, int vflag) int respa_flag; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/KSPACE/pair_tip4p_long.cpp b/src/KSPACE/pair_tip4p_long.cpp index ac428d483a..9419fdf196 100644 --- a/src/KSPACE/pair_tip4p_long.cpp +++ b/src/KSPACE/pair_tip4p_long.cpp @@ -90,8 +90,7 @@ void PairTIP4PLong::compute(int eflag, int vflag) double rsq; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/MANYBODY/pair_adp.cpp b/src/MANYBODY/pair_adp.cpp index 4fd19a36c4..68511b8709 100644 --- a/src/MANYBODY/pair_adp.cpp +++ b/src/MANYBODY/pair_adp.cpp @@ -133,8 +133,7 @@ void PairADP::compute(int eflag, int vflag) double sumlamxx,sumlamyy,sumlamzz,sumlamyz,sumlamxz,sumlamxy; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // grow local arrays if necessary // need to be atom->nmax in length diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp index f8221e6381..4502bd9a82 100644 --- a/src/MANYBODY/pair_airebo.cpp +++ b/src/MANYBODY/pair_airebo.cpp @@ -108,8 +108,7 @@ PairAIREBO::~PairAIREBO() void PairAIREBO::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); pvector[0] = pvector[1] = pvector[2] = 0.0; REBO_neigh(); diff --git a/src/MANYBODY/pair_atm.cpp b/src/MANYBODY/pair_atm.cpp index e3be72443e..c157e0763c 100644 --- a/src/MANYBODY/pair_atm.cpp +++ b/src/MANYBODY/pair_atm.cpp @@ -82,8 +82,7 @@ void PairATM::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_bop.cpp b/src/MANYBODY/pair_bop.cpp index 6540dedf98..ac157e071c 100644 --- a/src/MANYBODY/pair_bop.cpp +++ b/src/MANYBODY/pair_bop.cpp @@ -297,8 +297,7 @@ void PairBOP::compute(int eflag, int vflag) ilist = list->ilist; firstneigh = list->firstneigh; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // BOP Neighbor lists must be updated every timestep maxnall=nall; diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp index 85ea4812bf..980aa84b2a 100644 --- a/src/MANYBODY/pair_comb.cpp +++ b/src/MANYBODY/pair_comb.cpp @@ -144,8 +144,7 @@ void PairComb::compute(int eflag, int vflag) int sht_jnum, *sht_jlist, nj; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); // Build short range neighbor list diff --git a/src/MANYBODY/pair_comb3.cpp b/src/MANYBODY/pair_comb3.cpp index d82f6dfed0..097f235ff2 100644 --- a/src/MANYBODY/pair_comb3.cpp +++ b/src/MANYBODY/pair_comb3.cpp @@ -987,8 +987,7 @@ void PairComb3::compute(int eflag, int vflag) evdwl = eng_tmp = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); // Build short range neighbor list Short_neigh(); diff --git a/src/MANYBODY/pair_eam.cpp b/src/MANYBODY/pair_eam.cpp index f4b4901075..b7957349b6 100644 --- a/src/MANYBODY/pair_eam.cpp +++ b/src/MANYBODY/pair_eam.cpp @@ -142,8 +142,7 @@ void PairEAM::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); // grow energy and fp arrays if necessary // need to be atom->nmax in length diff --git a/src/MANYBODY/pair_eam_cd.cpp b/src/MANYBODY/pair_eam_cd.cpp index 8db1b6dd9a..c111c6d950 100644 --- a/src/MANYBODY/pair_eam_cd.cpp +++ b/src/MANYBODY/pair_eam_cd.cpp @@ -73,8 +73,7 @@ void PairEAMCD::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); // Grow per-atom arrays if necessary diff --git a/src/MANYBODY/pair_eim.cpp b/src/MANYBODY/pair_eim.cpp index b0fa1b1eef..f1c028ef38 100644 --- a/src/MANYBODY/pair_eim.cpp +++ b/src/MANYBODY/pair_eim.cpp @@ -113,8 +113,7 @@ void PairEIM::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); // grow energy array if necessary diff --git a/src/MANYBODY/pair_gw.cpp b/src/MANYBODY/pair_gw.cpp index 7649090a99..e4b74f7a29 100644 --- a/src/MANYBODY/pair_gw.cpp +++ b/src/MANYBODY/pair_gw.cpp @@ -87,8 +87,7 @@ void PairGW::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_lcbop.cpp b/src/MANYBODY/pair_lcbop.cpp index 0c8b3ef2a6..05cdea8055 100644 --- a/src/MANYBODY/pair_lcbop.cpp +++ b/src/MANYBODY/pair_lcbop.cpp @@ -87,8 +87,7 @@ PairLCBOP::~PairLCBOP() void PairLCBOP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); SR_neigh(); FSR(eflag,vflag); diff --git a/src/MANYBODY/pair_nb3b_harmonic.cpp b/src/MANYBODY/pair_nb3b_harmonic.cpp index ce449e4890..a61b403459 100644 --- a/src/MANYBODY/pair_nb3b_harmonic.cpp +++ b/src/MANYBODY/pair_nb3b_harmonic.cpp @@ -87,8 +87,7 @@ void PairNb3bHarmonic::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_polymorphic.cpp b/src/MANYBODY/pair_polymorphic.cpp index 41c5892d4e..d3aca4e889 100644 --- a/src/MANYBODY/pair_polymorphic.cpp +++ b/src/MANYBODY/pair_polymorphic.cpp @@ -117,8 +117,7 @@ void PairPolymorphic::compute(int eflag, int vflag) double emb; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index 91e11b3d26..5a148fb152 100644 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -91,8 +91,7 @@ void PairSW::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index 54101aef9e..213b1037bb 100644 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -93,8 +93,7 @@ void PairTersoff::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_vashishta.cpp b/src/MANYBODY/pair_vashishta.cpp index b4c3086ca8..3d4b1d900e 100644 --- a/src/MANYBODY/pair_vashishta.cpp +++ b/src/MANYBODY/pair_vashishta.cpp @@ -93,8 +93,7 @@ void PairVashishta::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MANYBODY/pair_vashishta_table.cpp b/src/MANYBODY/pair_vashishta_table.cpp index 1055db99fa..d4eaa59f1a 100644 --- a/src/MANYBODY/pair_vashishta_table.cpp +++ b/src/MANYBODY/pair_vashishta_table.cpp @@ -64,8 +64,7 @@ void PairVashishtaTable::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MISC/pair_nm_cut.cpp b/src/MISC/pair_nm_cut.cpp index 4b1611b137..124832b63e 100644 --- a/src/MISC/pair_nm_cut.cpp +++ b/src/MISC/pair_nm_cut.cpp @@ -70,8 +70,7 @@ void PairNMCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MISC/pair_nm_cut_coul_cut.cpp b/src/MISC/pair_nm_cut_coul_cut.cpp index 999fab1d6e..6a09d579b7 100644 --- a/src/MISC/pair_nm_cut_coul_cut.cpp +++ b/src/MISC/pair_nm_cut_coul_cut.cpp @@ -74,8 +74,7 @@ void PairNMCutCoulCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MISC/pair_nm_cut_coul_long.cpp b/src/MISC/pair_nm_cut_coul_long.cpp index fb82436dba..af21f02881 100644 --- a/src/MISC/pair_nm_cut_coul_long.cpp +++ b/src/MISC/pair_nm_cut_coul_long.cpp @@ -90,8 +90,7 @@ void PairNMCutCoulLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp index c0c885d4d4..ddc1110081 100644 --- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp @@ -91,8 +91,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag) tagint *klist; evdwl = ehbond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp index f464d2c621..055f0ed46b 100644 --- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp +++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp @@ -61,8 +61,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag) tagint *klist; evdwl = ehbond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp index 688c675815..98e272d99a 100644 --- a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp +++ b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp @@ -75,8 +75,7 @@ void PairLJCharmmCoulCharmm::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp b/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp index 6c083a49b0..d68d5e8f6d 100644 --- a/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp +++ b/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp @@ -39,8 +39,7 @@ void PairLJCharmmCoulCharmmImplicit::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp b/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp index 4b9147c169..7ce2417716 100644 --- a/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp +++ b/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp @@ -103,8 +103,7 @@ void PairLJCharmmfswCoulCharmmfsh::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp b/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp index 92dead8435..2b3d2c60f5 100644 --- a/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp +++ b/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp @@ -91,8 +91,7 @@ void PairLJCutTIP4PCut::compute(int eflag, int vflag) double *x1,*x2,*xH1,*xH2; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/MOLECULE/pair_tip4p_cut.cpp b/src/MOLECULE/pair_tip4p_cut.cpp index 79dd79b180..e6fb9aab99 100644 --- a/src/MOLECULE/pair_tip4p_cut.cpp +++ b/src/MOLECULE/pair_tip4p_cut.cpp @@ -79,8 +79,7 @@ void PairTIP4PCut::compute(int eflag, int vflag) double *x1,*x2,*xH1,*xH2; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/OPT/pair_eam_opt.cpp b/src/OPT/pair_eam_opt.cpp index 5345d7f8d6..fc2b6731ee 100644 --- a/src/OPT/pair_eam_opt.cpp +++ b/src/OPT/pair_eam_opt.cpp @@ -38,8 +38,7 @@ PairEAMOpt::PairEAMOpt(LAMMPS *lmp) : PairEAM(lmp) {} void PairEAMOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/OPT/pair_lj_charmm_coul_long_opt.cpp b/src/OPT/pair_lj_charmm_coul_long_opt.cpp index 43f4ba7f5a..d80d3d1ec4 100644 --- a/src/OPT/pair_lj_charmm_coul_long_opt.cpp +++ b/src/OPT/pair_lj_charmm_coul_long_opt.cpp @@ -44,8 +44,7 @@ PairLJCharmmCoulLongOpt::PairLJCharmmCoulLongOpt(LAMMPS *lmp) : void PairLJCharmmCoulLongOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/OPT/pair_lj_cut_coul_long_opt.cpp b/src/OPT/pair_lj_cut_coul_long_opt.cpp index 98683a67a4..a25010cf1f 100644 --- a/src/OPT/pair_lj_cut_coul_long_opt.cpp +++ b/src/OPT/pair_lj_cut_coul_long_opt.cpp @@ -38,8 +38,7 @@ PairLJCutCoulLongOpt::PairLJCutCoulLongOpt(LAMMPS *lmp) : PairLJCutCoulLong(lmp) void PairLJCutCoulLongOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (!ncoultablebits) { if (evflag) { diff --git a/src/OPT/pair_lj_cut_opt.cpp b/src/OPT/pair_lj_cut_opt.cpp index ed35178c1f..c6684461be 100644 --- a/src/OPT/pair_lj_cut_opt.cpp +++ b/src/OPT/pair_lj_cut_opt.cpp @@ -34,8 +34,7 @@ PairLJCutOpt::PairLJCutOpt(LAMMPS *lmp) : PairLJCut(lmp) {} void PairLJCutOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/OPT/pair_lj_cut_tip4p_long_opt.cpp b/src/OPT/pair_lj_cut_tip4p_long_opt.cpp index 4842cc4fc0..92facca43e 100644 --- a/src/OPT/pair_lj_cut_tip4p_long_opt.cpp +++ b/src/OPT/pair_lj_cut_tip4p_long_opt.cpp @@ -53,8 +53,7 @@ PairLJCutTIP4PLongOpt::PairLJCutTIP4PLongOpt(LAMMPS *lmp) : void PairLJCutTIP4PLongOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/OPT/pair_lj_long_coul_long_opt.cpp b/src/OPT/pair_lj_long_coul_long_opt.cpp index 6bd1e8cb96..243b64391f 100644 --- a/src/OPT/pair_lj_long_coul_long_opt.cpp +++ b/src/OPT/pair_lj_long_coul_long_opt.cpp @@ -44,8 +44,7 @@ PairLJLongCoulLongOpt::PairLJLongCoulLongOpt(LAMMPS *lmp) : PairLJLongCoulLong(l void PairLJLongCoulLongOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); if (order6) { @@ -290,8 +289,7 @@ void PairLJLongCoulLongOpt::compute(int eflag, int vflag) void PairLJLongCoulLongOpt::compute_outer(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); if (order6) { diff --git a/src/OPT/pair_morse_opt.cpp b/src/OPT/pair_morse_opt.cpp index 6299136f46..c9c6bba355 100644 --- a/src/OPT/pair_morse_opt.cpp +++ b/src/OPT/pair_morse_opt.cpp @@ -35,8 +35,7 @@ PairMorseOpt::PairMorseOpt(LAMMPS *lmp) : PairMorse(lmp) {} void PairMorseOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/OPT/pair_ufm_opt.cpp b/src/OPT/pair_ufm_opt.cpp index 85c76d624d..f463dac3f1 100644 --- a/src/OPT/pair_ufm_opt.cpp +++ b/src/OPT/pair_ufm_opt.cpp @@ -34,8 +34,7 @@ PairUFMOpt::PairUFMOpt(LAMMPS *lmp) : PairUFM(lmp) {} void PairUFMOpt::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/PERI/pair_peri_eps.cpp b/src/PERI/pair_peri_eps.cpp index 76267426c6..c00495ba4d 100644 --- a/src/PERI/pair_peri_eps.cpp +++ b/src/PERI/pair_peri_eps.cpp @@ -96,8 +96,7 @@ void PairPeriEPS::compute(int eflag, int vflag) double d_ij,delta,stretch; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); double **f = atom->f; double **x = atom->x; diff --git a/src/PERI/pair_peri_lps.cpp b/src/PERI/pair_peri_lps.cpp index 383b91c6f5..f0418c8c8d 100644 --- a/src/PERI/pair_peri_lps.cpp +++ b/src/PERI/pair_peri_lps.cpp @@ -93,8 +93,7 @@ void PairPeriLPS::compute(int eflag, int vflag) double d_ij,delta,stretch; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); double **f = atom->f; double **x = atom->x; diff --git a/src/PERI/pair_peri_pmb.cpp b/src/PERI/pair_peri_pmb.cpp index 772e47f2d6..ad2f3fb7c7 100644 --- a/src/PERI/pair_peri_pmb.cpp +++ b/src/PERI/pair_peri_pmb.cpp @@ -84,8 +84,7 @@ void PairPeriPMB::compute(int eflag, int vflag) double d_ij,delta,stretch; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **f = atom->f; double **x = atom->x; diff --git a/src/PERI/pair_peri_ves.cpp b/src/PERI/pair_peri_ves.cpp index 7590077f0e..24a9f92a97 100644 --- a/src/PERI/pair_peri_ves.cpp +++ b/src/PERI/pair_peri_ves.cpp @@ -98,8 +98,7 @@ void PairPeriVES::compute(int eflag, int vflag) double d_ij,delta,stretch; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); double **f = atom->f; double **x = atom->x; diff --git a/src/PYTHON/pair_python.cpp b/src/PYTHON/pair_python.cpp index 4899e5e2ef..2148fc67b8 100644 --- a/src/PYTHON/pair_python.cpp +++ b/src/PYTHON/pair_python.cpp @@ -82,8 +82,7 @@ void PairPython::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/SNAP/pair_snap.cpp b/src/SNAP/pair_snap.cpp index 81c5e9f6d1..8b547e6e73 100644 --- a/src/SNAP/pair_snap.cpp +++ b/src/SNAP/pair_snap.cpp @@ -176,8 +176,7 @@ void PairSNAP::compute_regular(int eflag, int vflag) int *jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -486,8 +485,7 @@ void PairSNAP::compute_optimized(int eflag, int vflag) #pragma omp master #endif { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); } #if defined(_OPENMP) diff --git a/src/SPIN/pair_spin_dmi.cpp b/src/SPIN/pair_spin_dmi.cpp index 8496e40f99..200cafb999 100644 --- a/src/SPIN/pair_spin_dmi.cpp +++ b/src/SPIN/pair_spin_dmi.cpp @@ -233,8 +233,7 @@ void PairSpinDmi::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/SPIN/pair_spin_exchange.cpp b/src/SPIN/pair_spin_exchange.cpp index b2955aafb2..5b8ec60cd6 100644 --- a/src/SPIN/pair_spin_exchange.cpp +++ b/src/SPIN/pair_spin_exchange.cpp @@ -218,8 +218,7 @@ void PairSpinExchange::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/SPIN/pair_spin_magelec.cpp b/src/SPIN/pair_spin_magelec.cpp index a7357f61e3..95c29b233d 100644 --- a/src/SPIN/pair_spin_magelec.cpp +++ b/src/SPIN/pair_spin_magelec.cpp @@ -225,8 +225,7 @@ void PairSpinMagelec::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/SPIN/pair_spin_neel.cpp b/src/SPIN/pair_spin_neel.cpp index bd12832a8d..64fca23b7a 100644 --- a/src/SPIN/pair_spin_neel.cpp +++ b/src/SPIN/pair_spin_neel.cpp @@ -232,8 +232,7 @@ void PairSpinNeel::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-AWPMD/pair_awpmd_cut.cpp b/src/USER-AWPMD/pair_awpmd_cut.cpp index 806e4f3a14..1b7bf35c28 100644 --- a/src/USER-AWPMD/pair_awpmd_cut.cpp +++ b/src/USER-AWPMD/pair_awpmd_cut.cpp @@ -108,10 +108,7 @@ void PairAWPMDCut::compute(int eflag, int vflag) // pvector = [KE, Pauli, ecoul, radial_restraint] for (int i=0; i<4; i++) pvector[i] = 0.0; - if (eflag || vflag) - ev_setup(eflag,vflag); - else - evflag = vflag_fdotr = 0; //?? + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-CGDNA/pair_oxdna2_coaxstk.cpp b/src/USER-CGDNA/pair_oxdna2_coaxstk.cpp index 0b220a3275..f54197aea7 100644 --- a/src/USER-CGDNA/pair_oxdna2_coaxstk.cpp +++ b/src/USER-CGDNA/pair_oxdna2_coaxstk.cpp @@ -144,8 +144,7 @@ void PairOxdna2Coaxstk::compute(int eflag, int vflag) double df2,df4f6t1,df4t4,df4t5,df4t6,rsint; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); anum = list->inum; alist = list->ilist; diff --git a/src/USER-CGDNA/pair_oxdna2_dh.cpp b/src/USER-CGDNA/pair_oxdna2_dh.cpp index da6e1f8bbd..10e7121427 100644 --- a/src/USER-CGDNA/pair_oxdna2_dh.cpp +++ b/src/USER-CGDNA/pair_oxdna2_dh.cpp @@ -114,8 +114,7 @@ void PairOxdna2Dh::compute(int eflag, int vflag) int a,b,ia,ib,anum,bnum,atype,btype; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); anum = list->inum; alist = list->ilist; diff --git a/src/USER-CGDNA/pair_oxdna_coaxstk.cpp b/src/USER-CGDNA/pair_oxdna_coaxstk.cpp index ef0ff16150..6d3061620d 100644 --- a/src/USER-CGDNA/pair_oxdna_coaxstk.cpp +++ b/src/USER-CGDNA/pair_oxdna_coaxstk.cpp @@ -156,8 +156,7 @@ void PairOxdnaCoaxstk::compute(int eflag, int vflag) double df2,df4t1,df4t4,df4t5,df4t6,df5c3,rsint; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); anum = list->inum; alist = list->ilist; diff --git a/src/USER-CGDNA/pair_oxdna_excv.cpp b/src/USER-CGDNA/pair_oxdna_excv.cpp index 719a63b5f4..82af5ed1c7 100644 --- a/src/USER-CGDNA/pair_oxdna_excv.cpp +++ b/src/USER-CGDNA/pair_oxdna_excv.cpp @@ -144,8 +144,7 @@ void PairOxdnaExcv::compute(int eflag, int vflag) int a,b,ia,ib,anum,bnum,atype,btype; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); anum = list->inum; alist = list->ilist; diff --git a/src/USER-CGDNA/pair_oxdna_hbond.cpp b/src/USER-CGDNA/pair_oxdna_hbond.cpp index d8305e30de..d2aa236a05 100644 --- a/src/USER-CGDNA/pair_oxdna_hbond.cpp +++ b/src/USER-CGDNA/pair_oxdna_hbond.cpp @@ -161,8 +161,7 @@ void PairOxdnaHbond::compute(int eflag, int vflag) double df1,df4t1,df4t4,df4t2,df4t3,df4t7,df4t8; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); anum = list->inum; alist = list->ilist; diff --git a/src/USER-CGDNA/pair_oxdna_stk.cpp b/src/USER-CGDNA/pair_oxdna_stk.cpp index f713e4d27c..4cbc0317dd 100644 --- a/src/USER-CGDNA/pair_oxdna_stk.cpp +++ b/src/USER-CGDNA/pair_oxdna_stk.cpp @@ -154,8 +154,7 @@ void PairOxdnaStk::compute(int eflag, int vflag) double tptofp; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // loop over stacking interaction neighours using bond topology diff --git a/src/USER-CGDNA/pair_oxdna_xstk.cpp b/src/USER-CGDNA/pair_oxdna_xstk.cpp index a354a604fd..071886556c 100644 --- a/src/USER-CGDNA/pair_oxdna_xstk.cpp +++ b/src/USER-CGDNA/pair_oxdna_xstk.cpp @@ -153,8 +153,7 @@ void PairOxdnaXstk::compute(int eflag, int vflag) double df2,df4t1,df4t4,df4t2,df4t3,df4t7,df4t8,rsint; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); anum = list->inum; alist = list->ilist; diff --git a/src/USER-CGSDK/pair_lj_sdk.cpp b/src/USER-CGSDK/pair_lj_sdk.cpp index 3404beb58a..7dd6c04436 100644 --- a/src/USER-CGSDK/pair_lj_sdk.cpp +++ b/src/USER-CGSDK/pair_lj_sdk.cpp @@ -78,9 +78,7 @@ PairLJSDK::~PairLJSDK() void PairLJSDK::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/USER-CGSDK/pair_lj_sdk_coul_long.cpp b/src/USER-CGSDK/pair_lj_sdk_coul_long.cpp index c51235518b..33a1659df9 100644 --- a/src/USER-CGSDK/pair_lj_sdk_coul_long.cpp +++ b/src/USER-CGSDK/pair_lj_sdk_coul_long.cpp @@ -90,9 +90,7 @@ PairLJSDKCoulLong::~PairLJSDKCoulLong() void PairLJSDKCoulLong::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/USER-CGSDK/pair_lj_sdk_coul_msm.cpp b/src/USER-CGSDK/pair_lj_sdk_coul_msm.cpp index c4882fdbdb..d26f8efcdc 100644 --- a/src/USER-CGSDK/pair_lj_sdk_coul_msm.cpp +++ b/src/USER-CGSDK/pair_lj_sdk_coul_msm.cpp @@ -57,9 +57,7 @@ void PairLJSDKCoulMSM::compute(int eflag, int vflag) if (force->kspace->scalar_pressure_flag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' with Pair style"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (evflag) { if (eflag) { diff --git a/src/USER-DPD/pair_dpd_fdt.cpp b/src/USER-DPD/pair_dpd_fdt.cpp index 12e6d9f257..07ef8190f0 100644 --- a/src/USER-DPD/pair_dpd_fdt.cpp +++ b/src/USER-DPD/pair_dpd_fdt.cpp @@ -76,8 +76,7 @@ void PairDPDfdt::compute(int eflag, int vflag) double gamma_ij; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index 42c23e3ad2..12e6989c00 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -85,8 +85,7 @@ void PairDPDfdtEnergy::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/USER-DPD/pair_exp6_rx.cpp b/src/USER-DPD/pair_exp6_rx.cpp index 0251f019c5..13521b52b1 100644 --- a/src/USER-DPD/pair_exp6_rx.cpp +++ b/src/USER-DPD/pair_exp6_rx.cpp @@ -121,8 +121,7 @@ void PairExp6rx::compute(int eflag, int vflag) evdwlOld = 0.0; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-DPD/pair_multi_lucy.cpp b/src/USER-DPD/pair_multi_lucy.cpp index 19a4a02f0b..ffc1562f88 100644 --- a/src/USER-DPD/pair_multi_lucy.cpp +++ b/src/USER-DPD/pair_multi_lucy.cpp @@ -95,8 +95,7 @@ void PairMultiLucy::compute(int eflag, int vflag) int tlm1 = tablength - 1; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-DPD/pair_multi_lucy_rx.cpp b/src/USER-DPD/pair_multi_lucy_rx.cpp index f3ad86eb2f..801e8ff039 100644 --- a/src/USER-DPD/pair_multi_lucy_rx.cpp +++ b/src/USER-DPD/pair_multi_lucy_rx.cpp @@ -111,8 +111,7 @@ void PairMultiLucyRX::compute(int eflag, int vflag) evdwlOld = 0.0; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-DPD/pair_table_rx.cpp b/src/USER-DPD/pair_table_rx.cpp index 1e7bc440d1..f2d0d7b1fb 100644 --- a/src/USER-DPD/pair_table_rx.cpp +++ b/src/USER-DPD/pair_table_rx.cpp @@ -78,8 +78,7 @@ void PairTableRX::compute(int eflag, int vflag) evdwlOld = 0.0; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-DRUDE/pair_lj_cut_thole_long.cpp b/src/USER-DRUDE/pair_lj_cut_thole_long.cpp index f9da40dfb9..1ebe4a4c2d 100644 --- a/src/USER-DRUDE/pair_lj_cut_thole_long.cpp +++ b/src/USER-DRUDE/pair_lj_cut_thole_long.cpp @@ -98,8 +98,7 @@ void PairLJCutTholeLong::compute(int eflag, int vflag) int di_closest; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-DRUDE/pair_thole.cpp b/src/USER-DRUDE/pair_thole.cpp index 5a518d819b..1bb75af825 100644 --- a/src/USER-DRUDE/pair_thole.cpp +++ b/src/USER-DRUDE/pair_thole.cpp @@ -64,8 +64,7 @@ void PairThole::compute(int eflag, int vflag) double dcoul,asr,exp_asr; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-EFF/pair_eff_cut.cpp b/src/USER-EFF/pair_eff_cut.cpp index b4e9011e33..f566922ef7 100644 --- a/src/USER-EFF/pair_eff_cut.cpp +++ b/src/USER-EFF/pair_eff_cut.cpp @@ -81,8 +81,7 @@ void PairEffCut::compute(int eflag, int vflag) // pvector = [KE, Pauli, ecoul, radial_restraint] for (i=0; i<4; i++) pvector[i] = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_coul_cut_soft.cpp b/src/USER-FEP/pair_coul_cut_soft.cpp index 529ffe6b09..86a6d02819 100644 --- a/src/USER-FEP/pair_coul_cut_soft.cpp +++ b/src/USER-FEP/pair_coul_cut_soft.cpp @@ -60,8 +60,7 @@ void PairCoulCutSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_coul_long_soft.cpp b/src/USER-FEP/pair_coul_long_soft.cpp index e45dbe72d6..9d3ffc0da1 100644 --- a/src/USER-FEP/pair_coul_long_soft.cpp +++ b/src/USER-FEP/pair_coul_long_soft.cpp @@ -78,8 +78,7 @@ void PairCoulLongSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_charmm_coul_long_soft.cpp b/src/USER-FEP/pair_lj_charmm_coul_long_soft.cpp index 34758b159b..ac6f1e6384 100644 --- a/src/USER-FEP/pair_lj_charmm_coul_long_soft.cpp +++ b/src/USER-FEP/pair_lj_charmm_coul_long_soft.cpp @@ -92,8 +92,7 @@ void PairLJCharmmCoulLongSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -415,8 +414,7 @@ void PairLJCharmmCoulLongSoft::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp b/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp index 7970097cfe..54643f7305 100644 --- a/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp +++ b/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp @@ -72,8 +72,7 @@ void PairLJClass2CoulCutSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp b/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp index 13096a64c6..4dfafbb268 100644 --- a/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp +++ b/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp @@ -82,8 +82,7 @@ void PairLJClass2CoulLongSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_class2_soft.cpp b/src/USER-FEP/pair_lj_class2_soft.cpp index b7f21fc59c..858e5a727e 100644 --- a/src/USER-FEP/pair_lj_class2_soft.cpp +++ b/src/USER-FEP/pair_lj_class2_soft.cpp @@ -68,8 +68,7 @@ void PairLJClass2Soft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_cut_coul_cut_soft.cpp b/src/USER-FEP/pair_lj_cut_coul_cut_soft.cpp index fc887fbec5..35c9162dbc 100644 --- a/src/USER-FEP/pair_lj_cut_coul_cut_soft.cpp +++ b/src/USER-FEP/pair_lj_cut_coul_cut_soft.cpp @@ -73,8 +73,7 @@ void PairLJCutCoulCutSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_cut_coul_long_soft.cpp b/src/USER-FEP/pair_lj_cut_coul_long_soft.cpp index a9032ab4d7..79253d2b9c 100644 --- a/src/USER-FEP/pair_lj_cut_coul_long_soft.cpp +++ b/src/USER-FEP/pair_lj_cut_coul_long_soft.cpp @@ -89,8 +89,7 @@ void PairLJCutCoulLongSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -390,8 +389,7 @@ void PairLJCutCoulLongSoft::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_cut_soft.cpp b/src/USER-FEP/pair_lj_cut_soft.cpp index 1322565473..4192d6546b 100644 --- a/src/USER-FEP/pair_lj_cut_soft.cpp +++ b/src/USER-FEP/pair_lj_cut_soft.cpp @@ -77,8 +77,7 @@ void PairLJCutSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -323,8 +322,7 @@ void PairLJCutSoft::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_lj_cut_tip4p_long_soft.cpp b/src/USER-FEP/pair_lj_cut_tip4p_long_soft.cpp index 8653800ee6..8ac28f9fa9 100644 --- a/src/USER-FEP/pair_lj_cut_tip4p_long_soft.cpp +++ b/src/USER-FEP/pair_lj_cut_tip4p_long_soft.cpp @@ -92,8 +92,7 @@ void PairLJCutTIP4PLongSoft::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/USER-FEP/pair_morse_soft.cpp b/src/USER-FEP/pair_morse_soft.cpp index f4c5a4b910..21f616a082 100644 --- a/src/USER-FEP/pair_morse_soft.cpp +++ b/src/USER-FEP/pair_morse_soft.cpp @@ -53,8 +53,7 @@ void PairMorseSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-FEP/pair_tip4p_long_soft.cpp b/src/USER-FEP/pair_tip4p_long_soft.cpp index 5e8c5000f8..9b6a6841fe 100644 --- a/src/USER-FEP/pair_tip4p_long_soft.cpp +++ b/src/USER-FEP/pair_tip4p_long_soft.cpp @@ -91,8 +91,7 @@ void PairTIP4PLongSoft::compute(int eflag, int vflag) double rsq; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh & newsite if necessary // initialize hneigh[0] to -1 on steps when reneighboring occurred diff --git a/src/USER-INTEL/pair_airebo_intel.cpp b/src/USER-INTEL/pair_airebo_intel.cpp index 198f8798fa..f330e3ec86 100644 --- a/src/USER-INTEL/pair_airebo_intel.cpp +++ b/src/USER-INTEL/pair_airebo_intel.cpp @@ -292,8 +292,7 @@ template void PairAIREBOIntel::compute( int eflag, int vflag, IntelBuffers * buffers ) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); pvector[0] = pvector[1] = pvector[2] = 0.0; const int inum = list->inum; diff --git a/src/USER-INTEL/pair_buck_coul_cut_intel.cpp b/src/USER-INTEL/pair_buck_coul_cut_intel.cpp index f82f4c1c7a..3f2d64fb93 100644 --- a/src/USER-INTEL/pair_buck_coul_cut_intel.cpp +++ b/src/USER-INTEL/pair_buck_coul_cut_intel.cpp @@ -73,9 +73,7 @@ void PairBuckCoulCutIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_buck_coul_long_intel.cpp b/src/USER-INTEL/pair_buck_coul_long_intel.cpp index 059413c3d9..2ddcd55663 100644 --- a/src/USER-INTEL/pair_buck_coul_long_intel.cpp +++ b/src/USER-INTEL/pair_buck_coul_long_intel.cpp @@ -73,9 +73,7 @@ void PairBuckCoulLongIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_buck_intel.cpp b/src/USER-INTEL/pair_buck_intel.cpp index 0e0bd0f56f..34af3462e2 100644 --- a/src/USER-INTEL/pair_buck_intel.cpp +++ b/src/USER-INTEL/pair_buck_intel.cpp @@ -66,9 +66,7 @@ void PairBuckIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_dpd_intel.cpp b/src/USER-INTEL/pair_dpd_intel.cpp index 5d67a60c4b..016f3b5ca0 100644 --- a/src/USER-INTEL/pair_dpd_intel.cpp +++ b/src/USER-INTEL/pair_dpd_intel.cpp @@ -82,9 +82,7 @@ void PairDPDIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag, vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_eam_intel.cpp b/src/USER-INTEL/pair_eam_intel.cpp index 95d0272d33..7f4806c87c 100644 --- a/src/USER-INTEL/pair_eam_intel.cpp +++ b/src/USER-INTEL/pair_eam_intel.cpp @@ -78,9 +78,7 @@ void PairEAMIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag, vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_gayberne_intel.cpp b/src/USER-INTEL/pair_gayberne_intel.cpp index 51524355d5..1d9ee7d4cd 100644 --- a/src/USER-INTEL/pair_gayberne_intel.cpp +++ b/src/USER-INTEL/pair_gayberne_intel.cpp @@ -72,9 +72,7 @@ void PairGayBerneIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag, vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); const int inum = list->inum; const int nall = atom->nlocal + atom->nghost; diff --git a/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp b/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp index 0b6ac3ffa5..9689c0bf50 100644 --- a/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp +++ b/src/USER-INTEL/pair_lj_charmm_coul_charmm_intel.cpp @@ -66,9 +66,7 @@ void PairLJCharmmCoulCharmmIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_lj_charmm_coul_long_intel.cpp b/src/USER-INTEL/pair_lj_charmm_coul_long_intel.cpp index 753a9afdd9..8de4ced549 100644 --- a/src/USER-INTEL/pair_lj_charmm_coul_long_intel.cpp +++ b/src/USER-INTEL/pair_lj_charmm_coul_long_intel.cpp @@ -70,9 +70,7 @@ void PairLJCharmmCoulLongIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_lj_cut_coul_long_intel.cpp b/src/USER-INTEL/pair_lj_cut_coul_long_intel.cpp index 35ed9061ce..8ad1823d97 100644 --- a/src/USER-INTEL/pair_lj_cut_coul_long_intel.cpp +++ b/src/USER-INTEL/pair_lj_cut_coul_long_intel.cpp @@ -71,9 +71,7 @@ void PairLJCutCoulLongIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_lj_cut_intel.cpp b/src/USER-INTEL/pair_lj_cut_intel.cpp index 94133a7f47..74dae7e096 100644 --- a/src/USER-INTEL/pair_lj_cut_intel.cpp +++ b/src/USER-INTEL/pair_lj_cut_intel.cpp @@ -62,9 +62,7 @@ void PairLJCutIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag, vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_sw_intel.cpp b/src/USER-INTEL/pair_sw_intel.cpp index 9e00516087..8482895fb6 100644 --- a/src/USER-INTEL/pair_sw_intel.cpp +++ b/src/USER-INTEL/pair_sw_intel.cpp @@ -95,9 +95,7 @@ void PairSWIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag, vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-INTEL/pair_tersoff_intel.cpp b/src/USER-INTEL/pair_tersoff_intel.cpp index 5d4c5f2cb6..668cb0cf33 100644 --- a/src/USER-INTEL/pair_tersoff_intel.cpp +++ b/src/USER-INTEL/pair_tersoff_intel.cpp @@ -107,9 +107,7 @@ void PairTersoffIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int inum = list->inum; const int nthreads = comm->nthreads; diff --git a/src/USER-MEAMC/pair_meamc.cpp b/src/USER-MEAMC/pair_meamc.cpp index d0d97740b3..3a934694bf 100644 --- a/src/USER-MEAMC/pair_meamc.cpp +++ b/src/USER-MEAMC/pair_meamc.cpp @@ -93,8 +93,7 @@ void PairMEAMC::compute(int eflag, int vflag) int *ilist_half,*numneigh_half,**firstneigh_half; int *numneigh_full,**firstneigh_full; - if (eflag || vflag) ev_setup(eflag,vflag); - else ev_unset(); + ev_init(eflag,vflag); // neighbor list info diff --git a/src/USER-MESO/pair_edpd.cpp b/src/USER-MESO/pair_edpd.cpp index 1f6222944a..e428b02822 100644 --- a/src/USER-MESO/pair_edpd.cpp +++ b/src/USER-MESO/pair_edpd.cpp @@ -99,8 +99,7 @@ PairEDPD::~PairEDPD() void PairEDPD::compute(int eflag, int vflag) { double evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/USER-MESO/pair_mdpd.cpp b/src/USER-MESO/pair_mdpd.cpp index f9acd3dbe1..4102499d46 100644 --- a/src/USER-MESO/pair_mdpd.cpp +++ b/src/USER-MESO/pair_mdpd.cpp @@ -88,8 +88,7 @@ void PairMDPD::compute(int eflag, int vflag) double rhoi, rhoj; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/USER-MESO/pair_mdpd_rhosum.cpp b/src/USER-MESO/pair_mdpd_rhosum.cpp index 806a63f898..2fd238088c 100644 --- a/src/USER-MESO/pair_mdpd_rhosum.cpp +++ b/src/USER-MESO/pair_mdpd_rhosum.cpp @@ -84,10 +84,7 @@ void PairMDPDRhoSum::compute(int eflag, int vflag) { // neighbor list variables int inum, *ilist, *numneigh, **firstneigh; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **x = atom->x; double *rho = atom->rho; diff --git a/src/USER-MESO/pair_tdpd.cpp b/src/USER-MESO/pair_tdpd.cpp index a41282c0d8..7df9d6d163 100644 --- a/src/USER-MESO/pair_tdpd.cpp +++ b/src/USER-MESO/pair_tdpd.cpp @@ -91,8 +91,7 @@ PairTDPD::~PairTDPD() void PairTDPD::compute(int eflag, int vflag) { double evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/USER-MGPT/pair_mgpt.cpp b/src/USER-MGPT/pair_mgpt.cpp index 347bc9cc69..91c624eec5 100644 --- a/src/USER-MGPT/pair_mgpt.cpp +++ b/src/USER-MGPT/pair_mgpt.cpp @@ -1673,8 +1673,7 @@ void PairMGPT::compute_x(const int *nnei,const int * const *nlist, void PairMGPT::compute(int eflag, int vflag) { - if(eflag || vflag) ev_setup(eflag, vflag); - else evflag = vflag_fdotr = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag, vflag); int newton_pair = force->newton_pair; double e_s,e_p,e_t,e_q; diff --git a/src/USER-MISC/pair_agni.cpp b/src/USER-MISC/pair_agni.cpp index 0277969d15..21a6f1deee 100644 --- a/src/USER-MISC/pair_agni.cpp +++ b/src/USER-MISC/pair_agni.cpp @@ -136,8 +136,7 @@ void PairAGNI::compute(int eflag, int vflag) double rsq; int *ilist,*jlist,*numneigh,**firstneigh; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_buck_mdf.cpp b/src/USER-MISC/pair_buck_mdf.cpp index 38de1c7c50..b5e81417ee 100644 --- a/src/USER-MISC/pair_buck_mdf.cpp +++ b/src/USER-MISC/pair_buck_mdf.cpp @@ -68,8 +68,7 @@ void PairBuckMDF::compute(int eflag, int vflag) double dp, d, tt, dt, dd; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_coul_diel.cpp b/src/USER-MISC/pair_coul_diel.cpp index 0154e89731..a86921d296 100644 --- a/src/USER-MISC/pair_coul_diel.cpp +++ b/src/USER-MISC/pair_coul_diel.cpp @@ -58,8 +58,7 @@ void PairCoulDiel::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_coul_shield.cpp b/src/USER-MISC/pair_coul_shield.cpp index 11df975c19..f74dcfe7d8 100644 --- a/src/USER-MISC/pair_coul_shield.cpp +++ b/src/USER-MISC/pair_coul_shield.cpp @@ -64,8 +64,7 @@ void PairCoulShield::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_edip.cpp b/src/USER-MISC/pair_edip.cpp index 491268567f..0b5220fdfd 100644 --- a/src/USER-MISC/pair_edip.cpp +++ b/src/USER-MISC/pair_edip.cpp @@ -149,8 +149,7 @@ void PairEDIP::compute(int eflag, int vflag) double potential2B_factor; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_edip_multi.cpp b/src/USER-MISC/pair_edip_multi.cpp index f56650d2f6..ab48fbaa73 100644 --- a/src/USER-MISC/pair_edip_multi.cpp +++ b/src/USER-MISC/pair_edip_multi.cpp @@ -118,8 +118,7 @@ void PairEDIPMulti::compute(int eflag, int vflag) // vflag != 0 means compute virial contributions in this step evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_extep.cpp b/src/USER-MISC/pair_extep.cpp index 364fd45016..132b857dde 100644 --- a/src/USER-MISC/pair_extep.cpp +++ b/src/USER-MISC/pair_extep.cpp @@ -190,8 +190,7 @@ void PairExTeP::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); SR_neigh(); diff --git a/src/USER-MISC/pair_gauss_cut.cpp b/src/USER-MISC/pair_gauss_cut.cpp index a000eff028..24d0b191d8 100644 --- a/src/USER-MISC/pair_gauss_cut.cpp +++ b/src/USER-MISC/pair_gauss_cut.cpp @@ -69,8 +69,7 @@ void PairGaussCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_ilp_graphene_hbn.cpp b/src/USER-MISC/pair_ilp_graphene_hbn.cpp index 6257c1d72b..d1b8a3be38 100644 --- a/src/USER-MISC/pair_ilp_graphene_hbn.cpp +++ b/src/USER-MISC/pair_ilp_graphene_hbn.cpp @@ -117,8 +117,7 @@ void PairILPGrapheneHBN::compute(int eflag, int vflag) int *ILP_neighs_i,*ILP_neighs_j; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_kolmogorov_crespi_full.cpp b/src/USER-MISC/pair_kolmogorov_crespi_full.cpp index cbcf6c7934..289ed19bd3 100644 --- a/src/USER-MISC/pair_kolmogorov_crespi_full.cpp +++ b/src/USER-MISC/pair_kolmogorov_crespi_full.cpp @@ -115,8 +115,7 @@ void PairKolmogorovCrespiFull::compute(int eflag, int vflag) int *KC_neighs_i,*KC_neighs_j; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_kolmogorov_crespi_z.cpp b/src/USER-MISC/pair_kolmogorov_crespi_z.cpp index e9583032fe..dcea990a3b 100644 --- a/src/USER-MISC/pair_kolmogorov_crespi_z.cpp +++ b/src/USER-MISC/pair_kolmogorov_crespi_z.cpp @@ -87,8 +87,7 @@ void PairKolmogorovCrespiZ::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_lebedeva_z.cpp b/src/USER-MISC/pair_lebedeva_z.cpp index 5153857c2f..0ab22e04c1 100644 --- a/src/USER-MISC/pair_lebedeva_z.cpp +++ b/src/USER-MISC/pair_lebedeva_z.cpp @@ -87,8 +87,7 @@ void PairLebedevaZ::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_lennard_mdf.cpp b/src/USER-MISC/pair_lennard_mdf.cpp index 4bc2da23f8..b51639e80e 100644 --- a/src/USER-MISC/pair_lennard_mdf.cpp +++ b/src/USER-MISC/pair_lennard_mdf.cpp @@ -65,8 +65,7 @@ void PairLJ_AB_MDF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_list.cpp b/src/USER-MISC/pair_list.cpp index aaeb586c1d..562a60aa99 100644 --- a/src/USER-MISC/pair_list.cpp +++ b/src/USER-MISC/pair_list.cpp @@ -80,9 +80,7 @@ PairList::~PairList() void PairList::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = - vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int newton_pair = force->newton_pair; diff --git a/src/USER-MISC/pair_lj_expand_coul_long.cpp b/src/USER-MISC/pair_lj_expand_coul_long.cpp index 79a3c2a497..fe21538f2d 100644 --- a/src/USER-MISC/pair_lj_expand_coul_long.cpp +++ b/src/USER-MISC/pair_lj_expand_coul_long.cpp @@ -91,8 +91,7 @@ void PairLJExpandCoulLong::compute(int eflag, int vflag) double rsq,rshift,rshiftsq,rshift2inv; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -412,8 +411,7 @@ void PairLJExpandCoulLong::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_lj_mdf.cpp b/src/USER-MISC/pair_lj_mdf.cpp index 4cd21b1dbe..ca0118ffb0 100644 --- a/src/USER-MISC/pair_lj_mdf.cpp +++ b/src/USER-MISC/pair_lj_mdf.cpp @@ -65,8 +65,7 @@ void PairLJMDF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_lj_sf_dipole_sf.cpp b/src/USER-MISC/pair_lj_sf_dipole_sf.cpp index 523b2ca71a..af7d23370d 100644 --- a/src/USER-MISC/pair_lj_sf_dipole_sf.cpp +++ b/src/USER-MISC/pair_lj_sf_dipole_sf.cpp @@ -79,8 +79,7 @@ void PairLJSFDipoleSF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_meam_spline.cpp b/src/USER-MISC/pair_meam_spline.cpp index 0300e2c7a2..f09919ce0f 100644 --- a/src/USER-MISC/pair_meam_spline.cpp +++ b/src/USER-MISC/pair_meam_spline.cpp @@ -103,12 +103,7 @@ void PairMEAMSpline::compute(int eflag, int vflag) double* const * const forces = atom->f; const int ntypes = atom->ntypes; - if (eflag || vflag) { - ev_setup(eflag, vflag); - } else { - evflag = vflag_fdotr = eflag_global = 0; - vflag_global = eflag_atom = vflag_atom = 0; - } + ev_init(eflag, vflag); // Grow per-atom array if necessary diff --git a/src/USER-MISC/pair_meam_sw_spline.cpp b/src/USER-MISC/pair_meam_sw_spline.cpp index e17c13865d..af1e8788bd 100644 --- a/src/USER-MISC/pair_meam_sw_spline.cpp +++ b/src/USER-MISC/pair_meam_sw_spline.cpp @@ -85,9 +85,7 @@ PairMEAMSWSpline::~PairMEAMSWSpline() void PairMEAMSWSpline::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag, vflag); - else evflag = vflag_fdotr = - eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag, vflag); double cutforcesq = cutoff*cutoff; diff --git a/src/USER-MISC/pair_momb.cpp b/src/USER-MISC/pair_momb.cpp index 927181ebf6..1716149a98 100644 --- a/src/USER-MISC/pair_momb.cpp +++ b/src/USER-MISC/pair_momb.cpp @@ -81,8 +81,7 @@ void PairMomb::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_morse_smooth_linear.cpp b/src/USER-MISC/pair_morse_smooth_linear.cpp index a88e7a1a27..7c7973f830 100644 --- a/src/USER-MISC/pair_morse_smooth_linear.cpp +++ b/src/USER-MISC/pair_morse_smooth_linear.cpp @@ -60,8 +60,7 @@ void PairMorseSmoothLinear::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_srp.cpp b/src/USER-MISC/pair_srp.cpp index 8f34e846c5..01deaf0fbe 100644 --- a/src/USER-MISC/pair_srp.cpp +++ b/src/USER-MISC/pair_srp.cpp @@ -143,10 +143,7 @@ void PairSRP::compute(int eflag, int vflag) { // setup energy and virial - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/pair_tersoff_table.cpp b/src/USER-MISC/pair_tersoff_table.cpp index d1044cc336..e0985d1dce 100644 --- a/src/USER-MISC/pair_tersoff_table.cpp +++ b/src/USER-MISC/pair_tersoff_table.cpp @@ -117,8 +117,7 @@ void PairTersoffTable::compute(int eflag, int vflag) double evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp b/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp index 1fc4644420..bb025e4e1e 100644 --- a/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp +++ b/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp @@ -87,8 +87,7 @@ void PairBuck6dCoulGaussDSF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp b/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp index 1ca42d864e..df54925f4e 100644 --- a/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp +++ b/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp @@ -89,8 +89,7 @@ void PairBuck6dCoulGaussLong::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-OMP/pair_adp_omp.cpp b/src/USER-OMP/pair_adp_omp.cpp index 264169773b..645d697994 100644 --- a/src/USER-OMP/pair_adp_omp.cpp +++ b/src/USER-OMP/pair_adp_omp.cpp @@ -39,9 +39,7 @@ PairADPOMP::PairADPOMP(LAMMPS *lmp) : void PairADPOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_agni_omp.cpp b/src/USER-OMP/pair_agni_omp.cpp index e8f003ea88..854bcbebf3 100644 --- a/src/USER-OMP/pair_agni_omp.cpp +++ b/src/USER-OMP/pair_agni_omp.cpp @@ -42,9 +42,7 @@ PairAGNIOMP::PairAGNIOMP(LAMMPS *lmp) : void PairAGNIOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_airebo_omp.cpp b/src/USER-OMP/pair_airebo_omp.cpp index ec5c02d727..bed6c81ee4 100644 --- a/src/USER-OMP/pair_airebo_omp.cpp +++ b/src/USER-OMP/pair_airebo_omp.cpp @@ -49,9 +49,7 @@ void PairAIREBOOMP::compute(int eflag, int vflag) { double pv0=0.0,pv1=0.0,pv2=0.0; - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); REBO_neigh_thr(); diff --git a/src/USER-OMP/pair_beck_omp.cpp b/src/USER-OMP/pair_beck_omp.cpp index 1494ec2987..90c3777932 100644 --- a/src/USER-OMP/pair_beck_omp.cpp +++ b/src/USER-OMP/pair_beck_omp.cpp @@ -38,9 +38,7 @@ PairBeckOMP::PairBeckOMP(LAMMPS *lmp) : void PairBeckOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_born_coul_long_omp.cpp b/src/USER-OMP/pair_born_coul_long_omp.cpp index f198184406..a5df8f8182 100644 --- a/src/USER-OMP/pair_born_coul_long_omp.cpp +++ b/src/USER-OMP/pair_born_coul_long_omp.cpp @@ -44,9 +44,7 @@ PairBornCoulLongOMP::PairBornCoulLongOMP(LAMMPS *lmp) : void PairBornCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_born_coul_msm_omp.cpp b/src/USER-OMP/pair_born_coul_msm_omp.cpp index 1b4757359f..ad1e5e63cd 100644 --- a/src/USER-OMP/pair_born_coul_msm_omp.cpp +++ b/src/USER-OMP/pair_born_coul_msm_omp.cpp @@ -41,9 +41,7 @@ void PairBornCoulMSMOMP::compute(int eflag, int vflag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' " "with OMP MSM Pair styles"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_born_coul_wolf_omp.cpp b/src/USER-OMP/pair_born_coul_wolf_omp.cpp index 7904181ba5..567eddc9cb 100644 --- a/src/USER-OMP/pair_born_coul_wolf_omp.cpp +++ b/src/USER-OMP/pair_born_coul_wolf_omp.cpp @@ -38,9 +38,7 @@ PairBornCoulWolfOMP::PairBornCoulWolfOMP(LAMMPS *lmp) : void PairBornCoulWolfOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_born_omp.cpp b/src/USER-OMP/pair_born_omp.cpp index f75d4b9f35..fce2013745 100644 --- a/src/USER-OMP/pair_born_omp.cpp +++ b/src/USER-OMP/pair_born_omp.cpp @@ -36,9 +36,7 @@ PairBornOMP::PairBornOMP(LAMMPS *lmp) : void PairBornOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_brownian_omp.cpp b/src/USER-OMP/pair_brownian_omp.cpp index b1af821bba..cef9fb0955 100644 --- a/src/USER-OMP/pair_brownian_omp.cpp +++ b/src/USER-OMP/pair_brownian_omp.cpp @@ -68,9 +68,7 @@ PairBrownianOMP::~PairBrownianOMP() void PairBrownianOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int inum = list->inum; diff --git a/src/USER-OMP/pair_brownian_poly_omp.cpp b/src/USER-OMP/pair_brownian_poly_omp.cpp index 2e677ed535..239a820242 100644 --- a/src/USER-OMP/pair_brownian_poly_omp.cpp +++ b/src/USER-OMP/pair_brownian_poly_omp.cpp @@ -68,9 +68,7 @@ PairBrownianPolyOMP::~PairBrownianPolyOMP() void PairBrownianPolyOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int inum = list->inum; diff --git a/src/USER-OMP/pair_buck_coul_cut_omp.cpp b/src/USER-OMP/pair_buck_coul_cut_omp.cpp index 8fa6be06b2..b9b77dc2b6 100644 --- a/src/USER-OMP/pair_buck_coul_cut_omp.cpp +++ b/src/USER-OMP/pair_buck_coul_cut_omp.cpp @@ -36,9 +36,7 @@ PairBuckCoulCutOMP::PairBuckCoulCutOMP(LAMMPS *lmp) : void PairBuckCoulCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_buck_coul_long_omp.cpp b/src/USER-OMP/pair_buck_coul_long_omp.cpp index 4d30eb3e82..951ba0688c 100644 --- a/src/USER-OMP/pair_buck_coul_long_omp.cpp +++ b/src/USER-OMP/pair_buck_coul_long_omp.cpp @@ -44,9 +44,7 @@ PairBuckCoulLongOMP::PairBuckCoulLongOMP(LAMMPS *lmp) : void PairBuckCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_buck_coul_msm_omp.cpp b/src/USER-OMP/pair_buck_coul_msm_omp.cpp index a8bca36394..6226191627 100644 --- a/src/USER-OMP/pair_buck_coul_msm_omp.cpp +++ b/src/USER-OMP/pair_buck_coul_msm_omp.cpp @@ -41,9 +41,7 @@ void PairBuckCoulMSMOMP::compute(int eflag, int vflag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' " "with OMP MSM Pair styles"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_buck_long_coul_long_omp.cpp b/src/USER-OMP/pair_buck_long_coul_long_omp.cpp index acb95ab76c..20d380a464 100644 --- a/src/USER-OMP/pair_buck_long_coul_long_omp.cpp +++ b/src/USER-OMP/pair_buck_long_coul_long_omp.cpp @@ -46,9 +46,8 @@ PairBuckLongCoulLongOMP::PairBuckLongCoulLongOMP(LAMMPS *lmp) : void PairBuckLongCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); + const int order1 = ewald_order&(1<<1); const int order6 = ewald_order&(1<<6); diff --git a/src/USER-OMP/pair_buck_omp.cpp b/src/USER-OMP/pair_buck_omp.cpp index f3fa32a5ea..cc7e81b9c5 100644 --- a/src/USER-OMP/pair_buck_omp.cpp +++ b/src/USER-OMP/pair_buck_omp.cpp @@ -36,9 +36,7 @@ PairBuckOMP::PairBuckOMP(LAMMPS *lmp) : void PairBuckOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_colloid_omp.cpp b/src/USER-OMP/pair_colloid_omp.cpp index 536b7644bd..64613cb31d 100644 --- a/src/USER-OMP/pair_colloid_omp.cpp +++ b/src/USER-OMP/pair_colloid_omp.cpp @@ -39,9 +39,7 @@ PairColloidOMP::PairColloidOMP(LAMMPS *lmp) : void PairColloidOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_comb_omp.cpp b/src/USER-OMP/pair_comb_omp.cpp index 8a77ab955f..be641dd0b9 100644 --- a/src/USER-OMP/pair_comb_omp.cpp +++ b/src/USER-OMP/pair_comb_omp.cpp @@ -41,9 +41,7 @@ PairCombOMP::PairCombOMP(LAMMPS *lmp) : void PairCombOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_cut_omp.cpp b/src/USER-OMP/pair_coul_cut_omp.cpp index b9ac72421e..056daf210a 100644 --- a/src/USER-OMP/pair_coul_cut_omp.cpp +++ b/src/USER-OMP/pair_coul_cut_omp.cpp @@ -36,9 +36,7 @@ PairCoulCutOMP::PairCoulCutOMP(LAMMPS *lmp) : void PairCoulCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_cut_soft_omp.cpp b/src/USER-OMP/pair_coul_cut_soft_omp.cpp index c7e8c5e560..70997da62b 100644 --- a/src/USER-OMP/pair_coul_cut_soft_omp.cpp +++ b/src/USER-OMP/pair_coul_cut_soft_omp.cpp @@ -36,9 +36,7 @@ PairCoulCutSoftOMP::PairCoulCutSoftOMP(LAMMPS *lmp) : void PairCoulCutSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_debye_omp.cpp b/src/USER-OMP/pair_coul_debye_omp.cpp index cb7a9025ce..d202e314bf 100644 --- a/src/USER-OMP/pair_coul_debye_omp.cpp +++ b/src/USER-OMP/pair_coul_debye_omp.cpp @@ -36,9 +36,7 @@ PairCoulDebyeOMP::PairCoulDebyeOMP(LAMMPS *lmp) : void PairCoulDebyeOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_diel_omp.cpp b/src/USER-OMP/pair_coul_diel_omp.cpp index c75e36b55e..f2bb6a46bf 100644 --- a/src/USER-OMP/pair_coul_diel_omp.cpp +++ b/src/USER-OMP/pair_coul_diel_omp.cpp @@ -36,9 +36,7 @@ PairCoulDielOMP::PairCoulDielOMP(LAMMPS *lmp) : void PairCoulDielOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_dsf_omp.cpp b/src/USER-OMP/pair_coul_dsf_omp.cpp index 740e3242ad..217fb844c3 100644 --- a/src/USER-OMP/pair_coul_dsf_omp.cpp +++ b/src/USER-OMP/pair_coul_dsf_omp.cpp @@ -46,9 +46,7 @@ PairCoulDSFOMP::PairCoulDSFOMP(LAMMPS *lmp) : void PairCoulDSFOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_long_omp.cpp b/src/USER-OMP/pair_coul_long_omp.cpp index eb74bb9615..1e3170c73c 100644 --- a/src/USER-OMP/pair_coul_long_omp.cpp +++ b/src/USER-OMP/pair_coul_long_omp.cpp @@ -45,9 +45,7 @@ PairCoulLongOMP::PairCoulLongOMP(LAMMPS *lmp) : void PairCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_long_soft_omp.cpp b/src/USER-OMP/pair_coul_long_soft_omp.cpp index 4e65483a17..dd1fc1030d 100644 --- a/src/USER-OMP/pair_coul_long_soft_omp.cpp +++ b/src/USER-OMP/pair_coul_long_soft_omp.cpp @@ -44,9 +44,7 @@ PairCoulLongSoftOMP::PairCoulLongSoftOMP(LAMMPS *lmp) : void PairCoulLongSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_msm_omp.cpp b/src/USER-OMP/pair_coul_msm_omp.cpp index f4bc279532..9b50b86954 100644 --- a/src/USER-OMP/pair_coul_msm_omp.cpp +++ b/src/USER-OMP/pair_coul_msm_omp.cpp @@ -42,9 +42,7 @@ void PairCoulMSMOMP::compute(int eflag, int vflag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' with " "OMP MSM Pair styles"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_coul_wolf_omp.cpp b/src/USER-OMP/pair_coul_wolf_omp.cpp index bc86cdbf5d..0913a2b188 100644 --- a/src/USER-OMP/pair_coul_wolf_omp.cpp +++ b/src/USER-OMP/pair_coul_wolf_omp.cpp @@ -38,9 +38,7 @@ PairCoulWolfOMP::PairCoulWolfOMP(LAMMPS *lmp) : void PairCoulWolfOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_dpd_omp.cpp b/src/USER-OMP/pair_dpd_omp.cpp index 29b5568def..77db3d9183 100644 --- a/src/USER-OMP/pair_dpd_omp.cpp +++ b/src/USER-OMP/pair_dpd_omp.cpp @@ -55,9 +55,7 @@ PairDPDOMP::~PairDPDOMP() void PairDPDOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int inum = list->inum; diff --git a/src/USER-OMP/pair_dpd_tstat_omp.cpp b/src/USER-OMP/pair_dpd_tstat_omp.cpp index 0a9e96fa0c..d7233a16c5 100644 --- a/src/USER-OMP/pair_dpd_tstat_omp.cpp +++ b/src/USER-OMP/pair_dpd_tstat_omp.cpp @@ -55,9 +55,7 @@ PairDPDTstatOMP::~PairDPDTstatOMP() void PairDPDTstatOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int inum = list->inum; diff --git a/src/USER-OMP/pair_eam_cd_omp.cpp b/src/USER-OMP/pair_eam_cd_omp.cpp index 68c01c83d2..51b83f3bf5 100644 --- a/src/USER-OMP/pair_eam_cd_omp.cpp +++ b/src/USER-OMP/pair_eam_cd_omp.cpp @@ -55,9 +55,7 @@ PairEAMCDOMP::PairEAMCDOMP(LAMMPS *lmp, int _cdeamVersion) : void PairEAMCDOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_eam_omp.cpp b/src/USER-OMP/pair_eam_omp.cpp index 492ff79769..99417f27da 100644 --- a/src/USER-OMP/pair_eam_omp.cpp +++ b/src/USER-OMP/pair_eam_omp.cpp @@ -39,9 +39,7 @@ PairEAMOMP::PairEAMOMP(LAMMPS *lmp) : void PairEAMOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_edip_omp.cpp b/src/USER-OMP/pair_edip_omp.cpp index 3392160d92..144d893c1c 100644 --- a/src/USER-OMP/pair_edip_omp.cpp +++ b/src/USER-OMP/pair_edip_omp.cpp @@ -43,9 +43,7 @@ PairEDIPOMP::PairEDIPOMP(LAMMPS *lmp) : void PairEDIPOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_eim_omp.cpp b/src/USER-OMP/pair_eim_omp.cpp index 6a3e0bc529..2ecd6f8ec7 100644 --- a/src/USER-OMP/pair_eim_omp.cpp +++ b/src/USER-OMP/pair_eim_omp.cpp @@ -39,9 +39,7 @@ PairEIMOMP::PairEIMOMP(LAMMPS *lmp) : void PairEIMOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_gauss_cut_omp.cpp b/src/USER-OMP/pair_gauss_cut_omp.cpp index 9a41dcc87e..928312240b 100644 --- a/src/USER-OMP/pair_gauss_cut_omp.cpp +++ b/src/USER-OMP/pair_gauss_cut_omp.cpp @@ -36,9 +36,7 @@ PairGaussCutOMP::PairGaussCutOMP(LAMMPS *lmp) : void PairGaussCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_gauss_omp.cpp b/src/USER-OMP/pair_gauss_omp.cpp index 059c77c677..159f1c3e31 100644 --- a/src/USER-OMP/pair_gauss_omp.cpp +++ b/src/USER-OMP/pair_gauss_omp.cpp @@ -37,9 +37,7 @@ PairGaussOMP::PairGaussOMP(LAMMPS *lmp) : void PairGaussOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_gayberne_omp.cpp b/src/USER-OMP/pair_gayberne_omp.cpp index 5b0ff67afe..cfa05745ff 100644 --- a/src/USER-OMP/pair_gayberne_omp.cpp +++ b/src/USER-OMP/pair_gayberne_omp.cpp @@ -38,9 +38,7 @@ PairGayBerneOMP::PairGayBerneOMP(LAMMPS *lmp) : void PairGayBerneOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_gran_hertz_history_omp.cpp b/src/USER-OMP/pair_gran_hertz_history_omp.cpp index 9854b8f9ff..271c70e9b9 100644 --- a/src/USER-OMP/pair_gran_hertz_history_omp.cpp +++ b/src/USER-OMP/pair_gran_hertz_history_omp.cpp @@ -40,9 +40,7 @@ PairGranHertzHistoryOMP::PairGranHertzHistoryOMP(LAMMPS *lmp) : void PairGranHertzHistoryOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_gran_hooke_history_omp.cpp b/src/USER-OMP/pair_gran_hooke_history_omp.cpp index 2327fc815a..9a0e8aab76 100644 --- a/src/USER-OMP/pair_gran_hooke_history_omp.cpp +++ b/src/USER-OMP/pair_gran_hooke_history_omp.cpp @@ -41,9 +41,7 @@ PairGranHookeHistoryOMP::PairGranHookeHistoryOMP(LAMMPS *lmp) : void PairGranHookeHistoryOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int shearupdate = (update->setupflag) ? 0 : 1; diff --git a/src/USER-OMP/pair_gran_hooke_omp.cpp b/src/USER-OMP/pair_gran_hooke_omp.cpp index 876fe9c4de..d226ceaa14 100644 --- a/src/USER-OMP/pair_gran_hooke_omp.cpp +++ b/src/USER-OMP/pair_gran_hooke_omp.cpp @@ -38,9 +38,7 @@ PairGranHookeOMP::PairGranHookeOMP(LAMMPS *lmp) : void PairGranHookeOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp index ec9da78b16..ea56ff51b5 100644 --- a/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp +++ b/src/USER-OMP/pair_hbond_dreiding_lj_omp.cpp @@ -57,9 +57,7 @@ PairHbondDreidingLJOMP::~PairHbondDreidingLJOMP() void PairHbondDreidingLJOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp index 4965be43b8..1cff2de3b2 100644 --- a/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp +++ b/src/USER-OMP/pair_hbond_dreiding_morse_omp.cpp @@ -57,9 +57,7 @@ PairHbondDreidingMorseOMP::~PairHbondDreidingMorseOMP() void PairHbondDreidingMorseOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj96_cut_omp.cpp b/src/USER-OMP/pair_lj96_cut_omp.cpp index 1cca674369..9ba8e09a54 100644 --- a/src/USER-OMP/pair_lj96_cut_omp.cpp +++ b/src/USER-OMP/pair_lj96_cut_omp.cpp @@ -37,9 +37,7 @@ PairLJ96CutOMP::PairLJ96CutOMP(LAMMPS *lmp) : void PairLJ96CutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; 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 index 2f72f3851e..3dc9b77c0f 100644 --- a/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp +++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_implicit_omp.cpp @@ -36,9 +36,7 @@ PairLJCharmmCoulCharmmImplicitOMP::PairLJCharmmCoulCharmmImplicitOMP(LAMMPS *lmp void PairLJCharmmCoulCharmmImplicitOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp index b61a80a178..f9230996f0 100644 --- a/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp +++ b/src/USER-OMP/pair_lj_charmm_coul_charmm_omp.cpp @@ -36,9 +36,7 @@ PairLJCharmmCoulCharmmOMP::PairLJCharmmCoulCharmmOMP(LAMMPS *lmp) : void PairLJCharmmCoulCharmmOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp index 5351ab9aea..4bdaa3519f 100644 --- a/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp +++ b/src/USER-OMP/pair_lj_charmm_coul_long_omp.cpp @@ -37,9 +37,7 @@ PairLJCharmmCoulLongOMP::PairLJCharmmCoulLongOMP(LAMMPS *lmp) : void PairLJCharmmCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_charmm_coul_long_soft_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_long_soft_omp.cpp index ea5d739e49..1f6daf052c 100644 --- a/src/USER-OMP/pair_lj_charmm_coul_long_soft_omp.cpp +++ b/src/USER-OMP/pair_lj_charmm_coul_long_soft_omp.cpp @@ -37,9 +37,7 @@ PairLJCharmmCoulLongSoftOMP::PairLJCharmmCoulLongSoftOMP(LAMMPS *lmp) : void PairLJCharmmCoulLongSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_charmm_coul_msm_omp.cpp b/src/USER-OMP/pair_lj_charmm_coul_msm_omp.cpp index 3baa9597a8..eab62d919e 100644 --- a/src/USER-OMP/pair_lj_charmm_coul_msm_omp.cpp +++ b/src/USER-OMP/pair_lj_charmm_coul_msm_omp.cpp @@ -42,9 +42,7 @@ void PairLJCharmmCoulMSMOMP::compute(int eflag, int vflag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' " "with OMP MSM Pair styles"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp index 38390918c7..b9ffad134b 100644 --- a/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp +++ b/src/USER-OMP/pair_lj_class2_coul_cut_omp.cpp @@ -36,9 +36,7 @@ PairLJClass2CoulCutOMP::PairLJClass2CoulCutOMP(LAMMPS *lmp) : void PairLJClass2CoulCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp index f47672c9bc..e5995363ad 100644 --- a/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp +++ b/src/USER-OMP/pair_lj_class2_coul_long_omp.cpp @@ -44,9 +44,7 @@ PairLJClass2CoulLongOMP::PairLJClass2CoulLongOMP(LAMMPS *lmp) : void PairLJClass2CoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_class2_omp.cpp b/src/USER-OMP/pair_lj_class2_omp.cpp index 7ab4626c3e..67715572ae 100644 --- a/src/USER-OMP/pair_lj_class2_omp.cpp +++ b/src/USER-OMP/pair_lj_class2_omp.cpp @@ -36,9 +36,7 @@ PairLJClass2OMP::PairLJClass2OMP(LAMMPS *lmp) : void PairLJClass2OMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cubic_omp.cpp b/src/USER-OMP/pair_lj_cubic_omp.cpp index 3e8adb33b8..5fa4f92f45 100644 --- a/src/USER-OMP/pair_lj_cubic_omp.cpp +++ b/src/USER-OMP/pair_lj_cubic_omp.cpp @@ -37,9 +37,7 @@ PairLJCubicOMP::PairLJCubicOMP(LAMMPS *lmp) : void PairLJCubicOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp index ea560a09bf..69cc2d3042 100644 --- a/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_cut_omp.cpp @@ -36,9 +36,7 @@ PairLJCutCoulCutOMP::PairLJCutCoulCutOMP(LAMMPS *lmp) : void PairLJCutCoulCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_cut_soft_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_cut_soft_omp.cpp index 4ef12bb1bb..5dfa414bd4 100644 --- a/src/USER-OMP/pair_lj_cut_coul_cut_soft_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_cut_soft_omp.cpp @@ -36,9 +36,7 @@ PairLJCutCoulCutSoftOMP::PairLJCutCoulCutSoftOMP(LAMMPS *lmp) : void PairLJCutCoulCutSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp index 9163e98edd..4644e565a7 100644 --- a/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_debye_omp.cpp @@ -36,9 +36,7 @@ PairLJCutCoulDebyeOMP::PairLJCutCoulDebyeOMP(LAMMPS *lmp) : void PairLJCutCoulDebyeOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_dsf_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_dsf_omp.cpp index 9d9c098f87..13d877ec07 100644 --- a/src/USER-OMP/pair_lj_cut_coul_dsf_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_dsf_omp.cpp @@ -46,9 +46,7 @@ PairLJCutCoulDSFOMP::PairLJCutCoulDSFOMP(LAMMPS *lmp) : void PairLJCutCoulDSFOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp index d2eaae4ca4..d4fe5fd2a7 100644 --- a/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_long_omp.cpp @@ -45,9 +45,7 @@ PairLJCutCoulLongOMP::PairLJCutCoulLongOMP(LAMMPS *lmp) : void PairLJCutCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_long_soft_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_soft_omp.cpp index 725bfe4724..4a0ef73f60 100644 --- a/src/USER-OMP/pair_lj_cut_coul_long_soft_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_long_soft_omp.cpp @@ -45,9 +45,7 @@ PairLJCutCoulLongSoftOMP::PairLJCutCoulLongSoftOMP(LAMMPS *lmp) : void PairLJCutCoulLongSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_msm_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_msm_omp.cpp index 234204af93..4c34b73622 100644 --- a/src/USER-OMP/pair_lj_cut_coul_msm_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_msm_omp.cpp @@ -42,9 +42,7 @@ void PairLJCutCoulMSMOMP::compute(int eflag, int vflag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' " "with OMP MSM Pair styles"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_coul_wolf_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_wolf_omp.cpp index 36ef9d54f9..052be0a2fa 100644 --- a/src/USER-OMP/pair_lj_cut_coul_wolf_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_coul_wolf_omp.cpp @@ -38,9 +38,7 @@ PairLJCutCoulWolfOMP::PairLJCutCoulWolfOMP(LAMMPS *lmp) : void PairLJCutCoulWolfOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_dipole_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_dipole_cut_omp.cpp index d4145d9835..55359db3be 100644 --- a/src/USER-OMP/pair_lj_cut_dipole_cut_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_dipole_cut_omp.cpp @@ -36,9 +36,7 @@ PairLJCutDipoleCutOMP::PairLJCutDipoleCutOMP(LAMMPS *lmp) : void PairLJCutDipoleCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_omp.cpp index 319257b56b..34068185d2 100644 --- a/src/USER-OMP/pair_lj_cut_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_omp.cpp @@ -37,9 +37,7 @@ PairLJCutOMP::PairLJCutOMP(LAMMPS *lmp) : void PairLJCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_soft_omp.cpp b/src/USER-OMP/pair_lj_cut_soft_omp.cpp index 7698f19b95..9bbe58146c 100644 --- a/src/USER-OMP/pair_lj_cut_soft_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_soft_omp.cpp @@ -37,9 +37,7 @@ PairLJCutSoftOMP::PairLJCutSoftOMP(LAMMPS *lmp) : void PairLJCutSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_thole_long_omp.cpp b/src/USER-OMP/pair_lj_cut_thole_long_omp.cpp index 536d5bcb86..85cab4fe7b 100644 --- a/src/USER-OMP/pair_lj_cut_thole_long_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_thole_long_omp.cpp @@ -57,9 +57,7 @@ PairLJCutTholeLongOMP::PairLJCutTholeLongOMP(LAMMPS *lmp) : void PairLJCutTholeLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_cut_tip4p_cut_omp.cpp b/src/USER-OMP/pair_lj_cut_tip4p_cut_omp.cpp index 619e970bb0..288724cd77 100644 --- a/src/USER-OMP/pair_lj_cut_tip4p_cut_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_tip4p_cut_omp.cpp @@ -62,8 +62,7 @@ PairLJCutTIP4PCutOMP::~PairLJCutTIP4PCutOMP() void PairLJCutTIP4PCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_lj_cut_tip4p_long_omp.cpp b/src/USER-OMP/pair_lj_cut_tip4p_long_omp.cpp index ca8f450dc6..e2c1da1a89 100644 --- a/src/USER-OMP/pair_lj_cut_tip4p_long_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_tip4p_long_omp.cpp @@ -62,8 +62,7 @@ PairLJCutTIP4PLongOMP::~PairLJCutTIP4PLongOMP() void PairLJCutTIP4PLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_lj_cut_tip4p_long_soft_omp.cpp b/src/USER-OMP/pair_lj_cut_tip4p_long_soft_omp.cpp index 80b17fba96..6baba8aec4 100644 --- a/src/USER-OMP/pair_lj_cut_tip4p_long_soft_omp.cpp +++ b/src/USER-OMP/pair_lj_cut_tip4p_long_soft_omp.cpp @@ -62,8 +62,7 @@ PairLJCutTIP4PLongSoftOMP::~PairLJCutTIP4PLongSoftOMP() void PairLJCutTIP4PLongSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_lj_expand_omp.cpp b/src/USER-OMP/pair_lj_expand_omp.cpp index 064ea97809..6c6ddb045e 100644 --- a/src/USER-OMP/pair_lj_expand_omp.cpp +++ b/src/USER-OMP/pair_lj_expand_omp.cpp @@ -36,9 +36,7 @@ PairLJExpandOMP::PairLJExpandOMP(LAMMPS *lmp) : void PairLJExpandOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp index c87f369d11..77c5bc0da0 100644 --- a/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp +++ b/src/USER-OMP/pair_lj_gromacs_coul_gromacs_omp.cpp @@ -36,9 +36,7 @@ PairLJGromacsCoulGromacsOMP::PairLJGromacsCoulGromacsOMP(LAMMPS *lmp) : void PairLJGromacsCoulGromacsOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_gromacs_omp.cpp b/src/USER-OMP/pair_lj_gromacs_omp.cpp index 1d7cec5eef..15bcb08eed 100644 --- a/src/USER-OMP/pair_lj_gromacs_omp.cpp +++ b/src/USER-OMP/pair_lj_gromacs_omp.cpp @@ -36,9 +36,7 @@ PairLJGromacsOMP::PairLJGromacsOMP(LAMMPS *lmp) : void PairLJGromacsOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_long_coul_long_omp.cpp b/src/USER-OMP/pair_lj_long_coul_long_omp.cpp index 391840285b..c9edc087b6 100644 --- a/src/USER-OMP/pair_lj_long_coul_long_omp.cpp +++ b/src/USER-OMP/pair_lj_long_coul_long_omp.cpp @@ -46,9 +46,8 @@ PairLJLongCoulLongOMP::PairLJLongCoulLongOMP(LAMMPS *lmp) : void PairLJLongCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); + const int order1 = ewald_order&(1<<1); const int order6 = ewald_order&(1<<6); diff --git a/src/USER-OMP/pair_lj_long_tip4p_long_omp.cpp b/src/USER-OMP/pair_lj_long_tip4p_long_omp.cpp index 19278d19bb..6d7c5b5638 100644 --- a/src/USER-OMP/pair_lj_long_tip4p_long_omp.cpp +++ b/src/USER-OMP/pair_lj_long_tip4p_long_omp.cpp @@ -63,9 +63,7 @@ PairLJLongTIP4PLongOMP::~PairLJLongTIP4PLongOMP() void PairLJLongTIP4PLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // reallocate hneigh_thr & newsite_thr if necessary // initialize hneigh_thr[0] to -1 on steps when reneighboring occured diff --git a/src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp b/src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp index c87f26204e..16c87d5ed4 100644 --- a/src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp +++ b/src/USER-OMP/pair_lj_sdk_coul_long_omp.cpp @@ -38,9 +38,7 @@ PairLJSDKCoulLongOMP::PairLJSDKCoulLongOMP(LAMMPS *lmp) : void PairLJSDKCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_sdk_coul_msm_omp.cpp b/src/USER-OMP/pair_lj_sdk_coul_msm_omp.cpp index 8ff0cfe921..1002cc193e 100644 --- a/src/USER-OMP/pair_lj_sdk_coul_msm_omp.cpp +++ b/src/USER-OMP/pair_lj_sdk_coul_msm_omp.cpp @@ -44,9 +44,7 @@ void PairLJSDKCoulMSMOMP::compute(int eflag, int vflag) error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' " "with OMP MSM Pair styles"); - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_sdk_omp.cpp b/src/USER-OMP/pair_lj_sdk_omp.cpp index e107399316..1e64973cbb 100644 --- a/src/USER-OMP/pair_lj_sdk_omp.cpp +++ b/src/USER-OMP/pair_lj_sdk_omp.cpp @@ -40,9 +40,7 @@ PairLJSDKOMP::PairLJSDKOMP(LAMMPS *lmp) : void PairLJSDKOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_sf_dipole_sf_omp.cpp b/src/USER-OMP/pair_lj_sf_dipole_sf_omp.cpp index 250f6ff272..aea22fc4df 100644 --- a/src/USER-OMP/pair_lj_sf_dipole_sf_omp.cpp +++ b/src/USER-OMP/pair_lj_sf_dipole_sf_omp.cpp @@ -36,9 +36,7 @@ PairLJSFDipoleSFOMP::PairLJSFDipoleSFOMP(LAMMPS *lmp) : void PairLJSFDipoleSFOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_smooth_linear_omp.cpp b/src/USER-OMP/pair_lj_smooth_linear_omp.cpp index b06de641f5..420c55b0ed 100644 --- a/src/USER-OMP/pair_lj_smooth_linear_omp.cpp +++ b/src/USER-OMP/pair_lj_smooth_linear_omp.cpp @@ -36,9 +36,7 @@ PairLJSmoothLinearOMP::PairLJSmoothLinearOMP(LAMMPS *lmp) : void PairLJSmoothLinearOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lj_smooth_omp.cpp b/src/USER-OMP/pair_lj_smooth_omp.cpp index 36935616bf..d61dc19ff1 100644 --- a/src/USER-OMP/pair_lj_smooth_omp.cpp +++ b/src/USER-OMP/pair_lj_smooth_omp.cpp @@ -36,9 +36,7 @@ PairLJSmoothOMP::PairLJSmoothOMP(LAMMPS *lmp) : void PairLJSmoothOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lubricate_omp.cpp b/src/USER-OMP/pair_lubricate_omp.cpp index a7f9fc65b5..132dbc575e 100644 --- a/src/USER-OMP/pair_lubricate_omp.cpp +++ b/src/USER-OMP/pair_lubricate_omp.cpp @@ -54,9 +54,7 @@ PairLubricateOMP::~PairLubricateOMP() void PairLubricateOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_lubricate_poly_omp.cpp b/src/USER-OMP/pair_lubricate_poly_omp.cpp index 3f0ef1dba6..3a5f03364d 100644 --- a/src/USER-OMP/pair_lubricate_poly_omp.cpp +++ b/src/USER-OMP/pair_lubricate_poly_omp.cpp @@ -54,9 +54,7 @@ PairLubricatePolyOMP::~PairLubricatePolyOMP() void PairLubricatePolyOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_meam_spline_omp.cpp b/src/USER-OMP/pair_meam_spline_omp.cpp index dfc3b978a2..e9307c8666 100644 --- a/src/USER-OMP/pair_meam_spline_omp.cpp +++ b/src/USER-OMP/pair_meam_spline_omp.cpp @@ -39,9 +39,7 @@ PairMEAMSplineOMP::PairMEAMSplineOMP(LAMMPS *lmp) : void PairMEAMSplineOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_morse_omp.cpp b/src/USER-OMP/pair_morse_omp.cpp index 922b67b463..bf57019f11 100644 --- a/src/USER-OMP/pair_morse_omp.cpp +++ b/src/USER-OMP/pair_morse_omp.cpp @@ -36,9 +36,7 @@ PairMorseOMP::PairMorseOMP(LAMMPS *lmp) : void PairMorseOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_morse_smooth_linear_omp.cpp b/src/USER-OMP/pair_morse_smooth_linear_omp.cpp index 61cef69c37..5ba6acb439 100644 --- a/src/USER-OMP/pair_morse_smooth_linear_omp.cpp +++ b/src/USER-OMP/pair_morse_smooth_linear_omp.cpp @@ -40,9 +40,7 @@ PairMorseSmoothLinearOMP::PairMorseSmoothLinearOMP(LAMMPS *lmp) : void PairMorseSmoothLinearOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_nm_cut_coul_cut_omp.cpp b/src/USER-OMP/pair_nm_cut_coul_cut_omp.cpp index fcbf5dbabb..d62b4e5c62 100644 --- a/src/USER-OMP/pair_nm_cut_coul_cut_omp.cpp +++ b/src/USER-OMP/pair_nm_cut_coul_cut_omp.cpp @@ -36,9 +36,7 @@ PairNMCutCoulCutOMP::PairNMCutCoulCutOMP(LAMMPS *lmp) : void PairNMCutCoulCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_nm_cut_coul_long_omp.cpp b/src/USER-OMP/pair_nm_cut_coul_long_omp.cpp index b31387dbfe..a8696c74a1 100644 --- a/src/USER-OMP/pair_nm_cut_coul_long_omp.cpp +++ b/src/USER-OMP/pair_nm_cut_coul_long_omp.cpp @@ -44,9 +44,7 @@ PairNMCutCoulLongOMP::PairNMCutCoulLongOMP(LAMMPS *lmp) : void PairNMCutCoulLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_nm_cut_omp.cpp b/src/USER-OMP/pair_nm_cut_omp.cpp index 79cd046311..9304b10ef0 100644 --- a/src/USER-OMP/pair_nm_cut_omp.cpp +++ b/src/USER-OMP/pair_nm_cut_omp.cpp @@ -36,9 +36,7 @@ PairNMCutOMP::PairNMCutOMP(LAMMPS *lmp) : void PairNMCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_peri_lps_omp.cpp b/src/USER-OMP/pair_peri_lps_omp.cpp index 7b174face7..61db45363e 100644 --- a/src/USER-OMP/pair_peri_lps_omp.cpp +++ b/src/USER-OMP/pair_peri_lps_omp.cpp @@ -45,9 +45,7 @@ PairPeriLPSOMP::PairPeriLPSOMP(LAMMPS *lmp) : void PairPeriLPSOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = eflag_global = eflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_peri_pmb_omp.cpp b/src/USER-OMP/pair_peri_pmb_omp.cpp index 8199d8aa47..b1816e4052 100644 --- a/src/USER-OMP/pair_peri_pmb_omp.cpp +++ b/src/USER-OMP/pair_peri_pmb_omp.cpp @@ -43,9 +43,7 @@ PairPeriPMBOMP::PairPeriPMBOMP(LAMMPS *lmp) : void PairPeriPMBOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_reaxc_omp.cpp b/src/USER-OMP/pair_reaxc_omp.cpp index 63beb61be6..7f2db420bf 100644 --- a/src/USER-OMP/pair_reaxc_omp.cpp +++ b/src/USER-OMP/pair_reaxc_omp.cpp @@ -191,8 +191,7 @@ void PairReaxCOMP::compute(int eflag, int vflag) int *num_hbonds = fix_reax->num_hbonds; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else ev_unset(); + ev_init(eflag,vflag); if (vflag_global) control->virial = 1; else control->virial = 0; diff --git a/src/USER-OMP/pair_resquared_omp.cpp b/src/USER-OMP/pair_resquared_omp.cpp index 1736e794f5..d9e0059a9f 100644 --- a/src/USER-OMP/pair_resquared_omp.cpp +++ b/src/USER-OMP/pair_resquared_omp.cpp @@ -38,9 +38,7 @@ PairRESquaredOMP::PairRESquaredOMP(LAMMPS *lmp) : void PairRESquaredOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_soft_omp.cpp b/src/USER-OMP/pair_soft_omp.cpp index a860ad97d9..eb151bc0df 100644 --- a/src/USER-OMP/pair_soft_omp.cpp +++ b/src/USER-OMP/pair_soft_omp.cpp @@ -40,9 +40,7 @@ PairSoftOMP::PairSoftOMP(LAMMPS *lmp) : void PairSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_sw_omp.cpp b/src/USER-OMP/pair_sw_omp.cpp index e323fc4c37..745b3a1f04 100644 --- a/src/USER-OMP/pair_sw_omp.cpp +++ b/src/USER-OMP/pair_sw_omp.cpp @@ -37,9 +37,7 @@ PairSWOMP::PairSWOMP(LAMMPS *lmp) : void PairSWOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_table_omp.cpp b/src/USER-OMP/pair_table_omp.cpp index d27456e1b5..b55817e75c 100644 --- a/src/USER-OMP/pair_table_omp.cpp +++ b/src/USER-OMP/pair_table_omp.cpp @@ -37,9 +37,7 @@ PairTableOMP::PairTableOMP(LAMMPS *lmp) : void PairTableOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_tersoff_mod_c_omp.cpp b/src/USER-OMP/pair_tersoff_mod_c_omp.cpp index fad077ca12..a11bd87640 100644 --- a/src/USER-OMP/pair_tersoff_mod_c_omp.cpp +++ b/src/USER-OMP/pair_tersoff_mod_c_omp.cpp @@ -36,9 +36,7 @@ PairTersoffMODCOMP::PairTersoffMODCOMP(LAMMPS *lmp) : void PairTersoffMODCOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_tersoff_mod_omp.cpp b/src/USER-OMP/pair_tersoff_mod_omp.cpp index 04e54c6e69..da22110c1c 100644 --- a/src/USER-OMP/pair_tersoff_mod_omp.cpp +++ b/src/USER-OMP/pair_tersoff_mod_omp.cpp @@ -36,9 +36,7 @@ PairTersoffMODOMP::PairTersoffMODOMP(LAMMPS *lmp) : void PairTersoffMODOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_tersoff_omp.cpp b/src/USER-OMP/pair_tersoff_omp.cpp index a5afdc7509..661f15d64d 100644 --- a/src/USER-OMP/pair_tersoff_omp.cpp +++ b/src/USER-OMP/pair_tersoff_omp.cpp @@ -37,9 +37,7 @@ PairTersoffOMP::PairTersoffOMP(LAMMPS *lmp) : void PairTersoffOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_tersoff_table_omp.cpp b/src/USER-OMP/pair_tersoff_table_omp.cpp index de045f9c62..7e83814f95 100644 --- a/src/USER-OMP/pair_tersoff_table_omp.cpp +++ b/src/USER-OMP/pair_tersoff_table_omp.cpp @@ -61,9 +61,7 @@ PairTersoffTableOMP::~PairTersoffTableOMP() void PairTersoffTableOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_tip4p_cut_omp.cpp b/src/USER-OMP/pair_tip4p_cut_omp.cpp index 85589cf043..1900ed4394 100644 --- a/src/USER-OMP/pair_tip4p_cut_omp.cpp +++ b/src/USER-OMP/pair_tip4p_cut_omp.cpp @@ -62,8 +62,7 @@ PairTIP4PCutOMP::~PairTIP4PCutOMP() void PairTIP4PCutOMP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_tip4p_long_omp.cpp b/src/USER-OMP/pair_tip4p_long_omp.cpp index c6c4bfe5fc..ee65937c46 100644 --- a/src/USER-OMP/pair_tip4p_long_omp.cpp +++ b/src/USER-OMP/pair_tip4p_long_omp.cpp @@ -62,8 +62,7 @@ PairTIP4PLongOMP::~PairTIP4PLongOMP() void PairTIP4PLongOMP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_tip4p_long_soft_omp.cpp b/src/USER-OMP/pair_tip4p_long_soft_omp.cpp index 7e9d3b6dff..adb984a2cd 100644 --- a/src/USER-OMP/pair_tip4p_long_soft_omp.cpp +++ b/src/USER-OMP/pair_tip4p_long_soft_omp.cpp @@ -62,8 +62,7 @@ PairTIP4PLongSoftOMP::~PairTIP4PLongSoftOMP() void PairTIP4PLongSoftOMP::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nlocal = atom->nlocal; const int nall = nlocal + atom->nghost; diff --git a/src/USER-OMP/pair_ufm_omp.cpp b/src/USER-OMP/pair_ufm_omp.cpp index ff258b5b3b..08d8cc15f9 100644 --- a/src/USER-OMP/pair_ufm_omp.cpp +++ b/src/USER-OMP/pair_ufm_omp.cpp @@ -38,9 +38,7 @@ PairUFMOMP::PairUFMOMP(LAMMPS *lmp) : void PairUFMOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_vashishta_omp.cpp b/src/USER-OMP/pair_vashishta_omp.cpp index 194a3e2d86..28104013f0 100644 --- a/src/USER-OMP/pair_vashishta_omp.cpp +++ b/src/USER-OMP/pair_vashishta_omp.cpp @@ -37,9 +37,7 @@ PairVashishtaOMP::PairVashishtaOMP(LAMMPS *lmp) : void PairVashishtaOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_vashishta_table_omp.cpp b/src/USER-OMP/pair_vashishta_table_omp.cpp index e0d96d8bb6..b044902ebe 100644 --- a/src/USER-OMP/pair_vashishta_table_omp.cpp +++ b/src/USER-OMP/pair_vashishta_table_omp.cpp @@ -37,9 +37,7 @@ PairVashishtaTableOMP::PairVashishtaTableOMP(LAMMPS *lmp) : void PairVashishtaTableOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_yukawa_colloid_omp.cpp b/src/USER-OMP/pair_yukawa_colloid_omp.cpp index c1d2133a1c..86314ce7b8 100644 --- a/src/USER-OMP/pair_yukawa_colloid_omp.cpp +++ b/src/USER-OMP/pair_yukawa_colloid_omp.cpp @@ -36,9 +36,7 @@ PairYukawaColloidOMP::PairYukawaColloidOMP(LAMMPS *lmp) : void PairYukawaColloidOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_yukawa_omp.cpp b/src/USER-OMP/pair_yukawa_omp.cpp index cbfd627f97..add81e9b04 100644 --- a/src/USER-OMP/pair_yukawa_omp.cpp +++ b/src/USER-OMP/pair_yukawa_omp.cpp @@ -36,9 +36,7 @@ PairYukawaOMP::PairYukawaOMP(LAMMPS *lmp) : void PairYukawaOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/pair_zbl_omp.cpp b/src/USER-OMP/pair_zbl_omp.cpp index 788679434b..f6856c4fa0 100644 --- a/src/USER-OMP/pair_zbl_omp.cpp +++ b/src/USER-OMP/pair_zbl_omp.cpp @@ -37,9 +37,7 @@ PairZBLOMP::PairZBLOMP(LAMMPS *lmp) : void PairZBLOMP::compute(int eflag, int vflag) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-QUIP/pair_quip.cpp b/src/USER-QUIP/pair_quip.cpp index fce6313754..c3b03bc5e0 100644 --- a/src/USER-QUIP/pair_quip.cpp +++ b/src/USER-QUIP/pair_quip.cpp @@ -75,8 +75,7 @@ void PairQUIP::compute(int eflag, int vflag) double *quip_local_e, *quip_force, *quip_local_virial, *quip_virial, quip_energy, *lattice; - if (eflag || vflag) ev_setup(eflag,vflag); - else ev_unset(); + ev_init(eflag,vflag); inum = list->inum; ilist = list->ilist; diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index b68e0d0779..b9d488d8cf 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -497,8 +497,7 @@ void PairReaxC::compute(int eflag, int vflag) int *num_hbonds = fix_reax->num_hbonds; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else ev_unset(); + ev_init(eflag,vflag); if (vflag_global) control->virial = 1; else control->virial = 0; diff --git a/src/USER-SDPD/pair_sdpd_taitwater_isothermal.cpp b/src/USER-SDPD/pair_sdpd_taitwater_isothermal.cpp index 7cfc950eff..db80debe51 100644 --- a/src/USER-SDPD/pair_sdpd_taitwater_isothermal.cpp +++ b/src/USER-SDPD/pair_sdpd_taitwater_isothermal.cpp @@ -71,8 +71,7 @@ void PairSDPDTaitwaterIsothermal::compute (int eflag, int vflag) { double rsq, tmp, wfd, delVdotDelR; double prefactor, wiener[3][3], f_random[3]; - if (eflag || vflag) ev_setup (eflag, vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **v = atom->vest; double **x = atom->x; diff --git a/src/USER-SMD/pair_smd_hertz.cpp b/src/USER-SMD/pair_smd_hertz.cpp index 13f48e995e..541be9f05c 100644 --- a/src/USER-SMD/pair_smd_hertz.cpp +++ b/src/USER-SMD/pair_smd_hertz.cpp @@ -87,10 +87,7 @@ void PairHertz::compute(int eflag, int vflag) { double *rmass = atom->rmass; evdwl = 0.0; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **f = atom->f; double **x = atom->x; diff --git a/src/USER-SMD/pair_smd_tlsph.cpp b/src/USER-SMD/pair_smd_tlsph.cpp index ab6b7d2785..ac67a3279a 100644 --- a/src/USER-SMD/pair_smd_tlsph.cpp +++ b/src/USER-SMD/pair_smd_tlsph.cpp @@ -448,10 +448,7 @@ void PairTlsph::ComputeForces(int eflag, int vflag) { Matrix3d eye; eye.setIdentity(); - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); /* * iterate over pairs of particles i, j and assign forces using PK1 stress tensor diff --git a/src/USER-SMD/pair_smd_triangulated_surface.cpp b/src/USER-SMD/pair_smd_triangulated_surface.cpp index e40c876ec3..d3a4983379 100644 --- a/src/USER-SMD/pair_smd_triangulated_surface.cpp +++ b/src/USER-SMD/pair_smd_triangulated_surface.cpp @@ -96,10 +96,7 @@ void PairTriSurf::compute(int eflag, int vflag) { Vector2d w2d, rhs; evdwl = 0.0; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); tagint *mol = atom->molecule; double **f = atom->f; diff --git a/src/USER-SMD/pair_smd_ulsph.cpp b/src/USER-SMD/pair_smd_ulsph.cpp index 50af6e2356..2c4a2de989 100644 --- a/src/USER-SMD/pair_smd_ulsph.cpp +++ b/src/USER-SMD/pair_smd_ulsph.cpp @@ -386,10 +386,7 @@ void PairULSPH::compute(int eflag, int vflag) { int k; SelfAdjointEigenSolver < Matrix3d > es; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); if (atom->nmax > nmax) { //printf("... allocating in compute with nmax = %d\n", atom->nmax); diff --git a/src/USER-SMTBQ/pair_smtbq.cpp b/src/USER-SMTBQ/pair_smtbq.cpp index 5c3189fc31..ba7f8eb88c 100644 --- a/src/USER-SMTBQ/pair_smtbq.cpp +++ b/src/USER-SMTBQ/pair_smtbq.cpp @@ -899,8 +899,7 @@ void PairSMTBQ::compute(int eflag, int vflag) evdwl = ecoul = ecovtot = ErepOO = ErepMO = Eion = 0.0; Eself = 0.0; - if (eflag || vflag) { ev_setup(eflag,vflag); } - else { evflag = vflag_fdotr = vflag_atom = 0; } + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-SPH/pair_sph_heatconduction.cpp b/src/USER-SPH/pair_sph_heatconduction.cpp index c93e8040b2..bafa26be89 100644 --- a/src/USER-SPH/pair_sph_heatconduction.cpp +++ b/src/USER-SPH/pair_sph_heatconduction.cpp @@ -52,10 +52,7 @@ void PairSPHHeatConduction::compute(int eflag, int vflag) { double imass, jmass, h, ih, ihsq; double rsq, wfd, D, deltaE; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **x = atom->x; double *e = atom->e; diff --git a/src/USER-SPH/pair_sph_idealgas.cpp b/src/USER-SPH/pair_sph_idealgas.cpp index d12ee06736..db5ec964bc 100644 --- a/src/USER-SPH/pair_sph_idealgas.cpp +++ b/src/USER-SPH/pair_sph_idealgas.cpp @@ -53,10 +53,7 @@ void PairSPHIdealGas::compute(int eflag, int vflag) { double vxtmp, vytmp, vztmp, imass, jmass, fi, fj, fvisc, h, ih, ihsq; double rsq, wfd, delVdotDelR, mu, deltaE, ci, cj; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **v = atom->vest; double **x = atom->x; diff --git a/src/USER-SPH/pair_sph_lj.cpp b/src/USER-SPH/pair_sph_lj.cpp index 3a30ecb5fa..7d315c975c 100644 --- a/src/USER-SPH/pair_sph_lj.cpp +++ b/src/USER-SPH/pair_sph_lj.cpp @@ -53,10 +53,7 @@ void PairSPHLJ::compute(int eflag, int vflag) { double vxtmp, vytmp, vztmp, imass, jmass, fi, fj, fvisc, h, ih, ihsq, ihcub; double rsq, wfd, delVdotDelR, mu, deltaE, ci, cj, lrc; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **v = atom->vest; double **x = atom->x; diff --git a/src/USER-SPH/pair_sph_rhosum.cpp b/src/USER-SPH/pair_sph_rhosum.cpp index 896a422782..842dddc744 100644 --- a/src/USER-SPH/pair_sph_rhosum.cpp +++ b/src/USER-SPH/pair_sph_rhosum.cpp @@ -72,10 +72,7 @@ void PairSPHRhoSum::compute(int eflag, int vflag) { // neighbor list variables int inum, *ilist, *numneigh, **firstneigh; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **x = atom->x; double *rho = atom->rho; diff --git a/src/USER-SPH/pair_sph_taitwater.cpp b/src/USER-SPH/pair_sph_taitwater.cpp index 9d5a417e5b..cf3c0e914b 100644 --- a/src/USER-SPH/pair_sph_taitwater.cpp +++ b/src/USER-SPH/pair_sph_taitwater.cpp @@ -58,10 +58,7 @@ void PairSPHTaitwater::compute(int eflag, int vflag) { double vxtmp, vytmp, vztmp, imass, jmass, fi, fj, fvisc, h, ih, ihsq; double rsq, tmp, wfd, delVdotDelR, mu, deltaE; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **v = atom->vest; double **x = atom->x; diff --git a/src/USER-SPH/pair_sph_taitwater_morris.cpp b/src/USER-SPH/pair_sph_taitwater_morris.cpp index fb745ac7da..5cbaa5959f 100644 --- a/src/USER-SPH/pair_sph_taitwater_morris.cpp +++ b/src/USER-SPH/pair_sph_taitwater_morris.cpp @@ -58,10 +58,7 @@ void PairSPHTaitwaterMorris::compute(int eflag, int vflag) { double vxtmp, vytmp, vztmp, imass, jmass, fi, fj, fvisc, h, ih, ihsq, velx, vely, velz; double rsq, tmp, wfd, delVdotDelR, deltaE; - if (eflag || vflag) - ev_setup(eflag, vflag); - else - evflag = vflag_fdotr = 0; + ev_init(eflag, vflag); double **v = atom->vest; double **x = atom->x; diff --git a/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp b/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp index 91c75d6945..f37dcc3ed1 100644 --- a/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp +++ b/src/USER-YAFF/pair_lj_switch3_coulgauss_long.cpp @@ -91,8 +91,7 @@ void PairLJSwitch3CoulGaussLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp b/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp index aa656e5b2d..931ed1d116 100644 --- a/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp +++ b/src/USER-YAFF/pair_mm3_switch3_coulgauss_long.cpp @@ -91,8 +91,7 @@ void PairMM3Switch3CoulGaussLong::compute(int eflag, int vflag) double rsq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair.cpp b/src/pair.cpp index 44cf3a43ea..79b94ef597 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -688,8 +688,7 @@ double Pair::mix_distance(double sig1, double sig2) void Pair::compute_dummy(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); } /* ---------------------------------------------------------------------- */ diff --git a/src/pair.h b/src/pair.h index 27b6d41eef..37606ed595 100644 --- a/src/pair.h +++ b/src/pair.h @@ -220,6 +220,10 @@ class Pair : protected Pointers { virtual void ev_setup(int, int, int alloc = 1); void ev_unset(); + void ev_init(int eflag, int vflag, int alloc = 1) { + if (eflag||vflag) ev_setup(eflag, vflag, alloc); + else ev_unset(); + } void ev_tally_full(int, double, double, double, double, double, double); void ev_tally_xyz_full(int, double, double, double, double, double, double, double, double); diff --git a/src/pair_beck.cpp b/src/pair_beck.cpp index d9c0fb902c..17731ebf0b 100644 --- a/src/pair_beck.cpp +++ b/src/pair_beck.cpp @@ -63,8 +63,7 @@ void PairBeck::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_born.cpp b/src/pair_born.cpp index 1a1db9dd90..78434c91f8 100644 --- a/src/pair_born.cpp +++ b/src/pair_born.cpp @@ -71,8 +71,7 @@ void PairBorn::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_born_coul_dsf.cpp b/src/pair_born_coul_dsf.cpp index be7f41ca2b..2e565897b5 100644 --- a/src/pair_born_coul_dsf.cpp +++ b/src/pair_born_coul_dsf.cpp @@ -77,8 +77,7 @@ void PairBornCoulDSF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_born_coul_wolf.cpp b/src/pair_born_coul_wolf.cpp index 22dcfa9f2d..3bb0e39e57 100644 --- a/src/pair_born_coul_wolf.cpp +++ b/src/pair_born_coul_wolf.cpp @@ -76,8 +76,7 @@ void PairBornCoulWolf::compute(int eflag, int vflag) double erfcc,erfcd,v_sh,dvdrr,e_self,e_shift,f_shift,qisq; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp index 8b6d79234b..a3cf1a38d6 100644 --- a/src/pair_buck.cpp +++ b/src/pair_buck.cpp @@ -66,8 +66,7 @@ void PairBuck::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp index 7eecb62121..c472ab456f 100644 --- a/src/pair_buck_coul_cut.cpp +++ b/src/pair_buck_coul_cut.cpp @@ -71,8 +71,7 @@ void PairBuckCoulCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_coul_cut.cpp b/src/pair_coul_cut.cpp index 8741abdb89..e7c0e0aabb 100644 --- a/src/pair_coul_cut.cpp +++ b/src/pair_coul_cut.cpp @@ -53,8 +53,7 @@ void PairCoulCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_coul_debye.cpp b/src/pair_coul_debye.cpp index 432a015598..c8afdabb93 100644 --- a/src/pair_coul_debye.cpp +++ b/src/pair_coul_debye.cpp @@ -40,8 +40,7 @@ void PairCoulDebye::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_coul_dsf.cpp b/src/pair_coul_dsf.cpp index 8cd5f7fece..e487ff171c 100644 --- a/src/pair_coul_dsf.cpp +++ b/src/pair_coul_dsf.cpp @@ -68,8 +68,7 @@ void PairCoulDSF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_coul_streitz.cpp b/src/pair_coul_streitz.cpp index 920770ed7f..244dccda12 100644 --- a/src/pair_coul_streitz.cpp +++ b/src/pair_coul_streitz.cpp @@ -412,8 +412,7 @@ void PairCoulStreitz::compute(int eflag, int vflag) ci_jfi = ci_fifj = dci_jfi = dci_fifj = 0.0; forcecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = vflag_atom = 0; + ev_init(eflag,vflag); inum = list->inum; ilist = list->ilist; diff --git a/src/pair_coul_wolf.cpp b/src/pair_coul_wolf.cpp index 762491166e..dbf21b8bee 100644 --- a/src/pair_coul_wolf.cpp +++ b/src/pair_coul_wolf.cpp @@ -64,8 +64,7 @@ void PairCoulWolf::compute(int eflag, int vflag) double erfcc,erfcd,v_sh,dvdrr,e_self,e_shift,f_shift,qisq; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_dpd.cpp b/src/pair_dpd.cpp index 5c5fc4254b..914b4aee17 100644 --- a/src/pair_dpd.cpp +++ b/src/pair_dpd.cpp @@ -70,8 +70,7 @@ void PairDPD::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **v = atom->v; diff --git a/src/pair_dpd_tstat.cpp b/src/pair_dpd_tstat.cpp index f2c0b157ea..1207c954eb 100644 --- a/src/pair_dpd_tstat.cpp +++ b/src/pair_dpd_tstat.cpp @@ -43,8 +43,7 @@ void PairDPDTstat::compute(int eflag, int vflag) double rsq,r,rinv,dot,wd,randnum,factor_dpd; int *ilist,*jlist,*numneigh,**firstneigh; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); // adjust sigma if target T is changing diff --git a/src/pair_gauss.cpp b/src/pair_gauss.cpp index 426389753b..2d157d6cac 100644 --- a/src/pair_gauss.cpp +++ b/src/pair_gauss.cpp @@ -68,8 +68,7 @@ void PairGauss::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); int occ = 0; double **x = atom->x; diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 2b2304718c..4961ce35c6 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -1,3 +1,4 @@ + /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories @@ -95,9 +96,7 @@ void PairHybrid::compute(int eflag, int vflag) if (no_virial_fdotr_compute && vflag % 4 == 2) vflag = 1 + vflag/4 * 4; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); // check if global component of incoming vflag = 2 // if so, reset vflag passed to substyle as if it were 0 diff --git a/src/pair_lj96_cut.cpp b/src/pair_lj96_cut.cpp index 457eba0e79..cefe9b87e0 100644 --- a/src/pair_lj96_cut.cpp +++ b/src/pair_lj96_cut.cpp @@ -73,8 +73,7 @@ void PairLJ96Cut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -308,8 +307,7 @@ void PairLJ96Cut::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_cubic.cpp b/src/pair_lj_cubic.cpp index 770caa6359..fdbfca608f 100644 --- a/src/pair_lj_cubic.cpp +++ b/src/pair_lj_cubic.cpp @@ -67,8 +67,7 @@ void PairLJCubic::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp index 13a546f5a5..2a0fcde3a5 100644 --- a/src/pair_lj_cut.cpp +++ b/src/pair_lj_cut.cpp @@ -73,8 +73,7 @@ void PairLJCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -305,8 +304,7 @@ void PairLJCut::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp index 15c06ab36a..6f2ba75309 100644 --- a/src/pair_lj_cut_coul_cut.cpp +++ b/src/pair_lj_cut_coul_cut.cpp @@ -67,8 +67,7 @@ void PairLJCutCoulCut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_cut_coul_debye.cpp b/src/pair_lj_cut_coul_debye.cpp index dfd866ca7a..cc6e92b2e3 100644 --- a/src/pair_lj_cut_coul_debye.cpp +++ b/src/pair_lj_cut_coul_debye.cpp @@ -37,8 +37,7 @@ void PairLJCutCoulDebye::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_cut_coul_dsf.cpp b/src/pair_lj_cut_coul_dsf.cpp index a49af13fb2..a0f9824b7f 100644 --- a/src/pair_lj_cut_coul_dsf.cpp +++ b/src/pair_lj_cut_coul_dsf.cpp @@ -81,8 +81,7 @@ void PairLJCutCoulDSF::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_cut_coul_wolf.cpp b/src/pair_lj_cut_coul_wolf.cpp index fc8a858ce1..2f796ded12 100644 --- a/src/pair_lj_cut_coul_wolf.cpp +++ b/src/pair_lj_cut_coul_wolf.cpp @@ -77,8 +77,7 @@ void PairLJCutCoulWolf::compute(int eflag, int vflag) evdwl = 0.0; ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp index 9aa58b3b88..662a1f8bd2 100644 --- a/src/pair_lj_expand.cpp +++ b/src/pair_lj_expand.cpp @@ -67,8 +67,7 @@ void PairLJExpand::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_gromacs.cpp b/src/pair_lj_gromacs.cpp index 495e96c368..bd19966ea3 100644 --- a/src/pair_lj_gromacs.cpp +++ b/src/pair_lj_gromacs.cpp @@ -75,8 +75,7 @@ void PairLJGromacs::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_gromacs_coul_gromacs.cpp b/src/pair_lj_gromacs_coul_gromacs.cpp index 414bfea92a..5821f26c81 100644 --- a/src/pair_lj_gromacs_coul_gromacs.cpp +++ b/src/pair_lj_gromacs_coul_gromacs.cpp @@ -72,8 +72,7 @@ void PairLJGromacsCoulGromacs::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_smooth.cpp b/src/pair_lj_smooth.cpp index a12046bb3b..ecacadbffa 100644 --- a/src/pair_lj_smooth.cpp +++ b/src/pair_lj_smooth.cpp @@ -72,8 +72,7 @@ void PairLJSmooth::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_lj_smooth_linear.cpp b/src/pair_lj_smooth_linear.cpp index 17c789bcee..265828c4cf 100644 --- a/src/pair_lj_smooth_linear.cpp +++ b/src/pair_lj_smooth_linear.cpp @@ -62,8 +62,7 @@ void PairLJSmoothLinear::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_mie_cut.cpp b/src/pair_mie_cut.cpp index c1e1c1ff50..231832dc48 100644 --- a/src/pair_mie_cut.cpp +++ b/src/pair_mie_cut.cpp @@ -75,8 +75,7 @@ void PairMIECut::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; @@ -310,8 +309,7 @@ void PairMIECut::compute_outer(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_morse.cpp b/src/pair_morse.cpp index c1031343e1..dca1834c14 100644 --- a/src/pair_morse.cpp +++ b/src/pair_morse.cpp @@ -59,8 +59,7 @@ void PairMorse::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp index d1c51ac600..7602f7b925 100644 --- a/src/pair_soft.cpp +++ b/src/pair_soft.cpp @@ -58,8 +58,7 @@ void PairSoft::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_table.cpp b/src/pair_table.cpp index 04b1e4ceee..cf9e5c3bfb 100644 --- a/src/pair_table.cpp +++ b/src/pair_table.cpp @@ -74,8 +74,7 @@ void PairTable::compute(int eflag, int vflag) int tlm1 = tablength - 1; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_ufm.cpp b/src/pair_ufm.cpp index a9f076f504..226fb6e7d9 100644 --- a/src/pair_ufm.cpp +++ b/src/pair_ufm.cpp @@ -74,8 +74,7 @@ void PairUFM::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_yukawa.cpp b/src/pair_yukawa.cpp index af520fd3da..913afbd5a1 100644 --- a/src/pair_yukawa.cpp +++ b/src/pair_yukawa.cpp @@ -55,8 +55,7 @@ void PairYukawa::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_zbl.cpp b/src/pair_zbl.cpp index f23a1e5d56..254a82ea64 100644 --- a/src/pair_zbl.cpp +++ b/src/pair_zbl.cpp @@ -78,8 +78,7 @@ void PairZBL::compute(int eflag, int vflag) int *ilist,*jlist,*numneigh,**firstneigh; evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/pair_zero.cpp b/src/pair_zero.cpp index d423e196af..143808f598 100644 --- a/src/pair_zero.cpp +++ b/src/pair_zero.cpp @@ -50,8 +50,7 @@ PairZero::~PairZero() void PairZero::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = vflag_fdotr = 0; + ev_init(eflag,vflag); if (vflag_fdotr) virial_fdotr_compute(); } -- GitLab From 17c81295c23f4df5aef2599216231310dcf82ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 17:50:10 +0100 Subject: [PATCH 0233/1243] use ev_init for fixes --- src/LATTE/fix_latte.cpp | 3 +-- src/MOLECULE/fix_cmap.cpp | 3 +-- src/fix.h | 4 ++++ src/fix_external.cpp | 3 +-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/LATTE/fix_latte.cpp b/src/LATTE/fix_latte.cpp index d1a96d32c6..645b298e09 100644 --- a/src/LATTE/fix_latte.cpp +++ b/src/LATTE/fix_latte.cpp @@ -239,8 +239,7 @@ void FixLatte::pre_reverse(int eflag, int /*vflag*/) void FixLatte::post_force(int vflag) { int eflag = eflag_caller; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); // compute Coulombic potential = pe[i]/q[i] // invoke compute pe/atom diff --git a/src/MOLECULE/fix_cmap.cpp b/src/MOLECULE/fix_cmap.cpp index ec2588e61b..3395c7ef14 100644 --- a/src/MOLECULE/fix_cmap.cpp +++ b/src/MOLECULE/fix_cmap.cpp @@ -341,8 +341,7 @@ void FixCMAP::post_force(int vflag) ecmap = 0.0; int eflag = eflag_caller; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); for (n = 0; n < ncrosstermlist; n++) { i1 = crosstermlist[n][0]; diff --git a/src/fix.h b/src/fix.h index 21dfc955a8..f5b3338aee 100644 --- a/src/fix.h +++ b/src/fix.h @@ -224,6 +224,10 @@ class Fix : protected Pointers { int dynamic; // recount atoms for temperature computes void ev_setup(int, int); + void ev_init(int eflag, int vflag) { + if (eflag||vflag) ev_setup(eflag, vflag); + else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; + } void ev_tally(int, int *, double, double, double *); void v_setup(int); void v_tally(int, int *, double, double *); diff --git a/src/fix_external.cpp b/src/fix_external.cpp index 5ac9206e7f..b1ffa65e49 100644 --- a/src/fix_external.cpp +++ b/src/fix_external.cpp @@ -141,8 +141,7 @@ void FixExternal::post_force(int vflag) bigint ntimestep = update->ntimestep; int eflag = eflag_caller; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); // invoke the callback in driver program // it will fill fexternal with forces -- GitLab From c7af948dfca45ecf0c1e8c367724bcdefea7acc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 17:50:50 +0100 Subject: [PATCH 0234/1243] use ev_init for impropers --- src/CLASS2/improper_class2.cpp | 3 +-- src/KOKKOS/improper_class2_kokkos.cpp | 3 +-- src/KOKKOS/improper_harmonic_kokkos.cpp | 3 +-- src/MOLECULE/improper_cvff.cpp | 3 +-- src/MOLECULE/improper_harmonic.cpp | 3 +-- src/MOLECULE/improper_umbrella.cpp | 3 +-- src/USER-INTEL/improper_cvff_intel.cpp | 3 +-- src/USER-INTEL/improper_harmonic_intel.cpp | 3 +-- src/USER-MISC/improper_cossq.cpp | 3 +-- src/USER-MISC/improper_distance.cpp | 3 +-- src/USER-MISC/improper_fourier.cpp | 3 +-- src/USER-MISC/improper_ring.cpp | 3 +-- src/USER-MOFFF/improper_inversion_harmonic.cpp | 3 +-- src/USER-OMP/improper_class2_omp.cpp | 5 +---- src/USER-OMP/improper_cossq_omp.cpp | 5 +---- src/USER-OMP/improper_cvff_omp.cpp | 5 +---- src/USER-OMP/improper_fourier_omp.cpp | 5 +---- src/USER-OMP/improper_harmonic_omp.cpp | 5 +---- src/USER-OMP/improper_ring_omp.cpp | 5 +---- src/USER-OMP/improper_umbrella_omp.cpp | 5 +---- src/USER-YAFF/improper_distharm.cpp | 3 +-- src/USER-YAFF/improper_sqdistharm.cpp | 3 +-- src/improper.h | 4 ++++ src/improper_hybrid.cpp | 3 +-- src/improper_zero.cpp | 3 +-- 25 files changed, 28 insertions(+), 62 deletions(-) diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp index 77f594af9d..ccb81aebd9 100644 --- a/src/CLASS2/improper_class2.cpp +++ b/src/CLASS2/improper_class2.cpp @@ -90,8 +90,7 @@ void ImproperClass2::compute(int eflag, int vflag) double fabcd[4][3]; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); for (i = 0; i < 3; i++) for (j = 0; j < 4; j++) diff --git a/src/KOKKOS/improper_class2_kokkos.cpp b/src/KOKKOS/improper_class2_kokkos.cpp index e3af52b494..ad32e6da4e 100644 --- a/src/KOKKOS/improper_class2_kokkos.cpp +++ b/src/KOKKOS/improper_class2_kokkos.cpp @@ -71,8 +71,7 @@ void ImproperClass2Kokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/improper_harmonic_kokkos.cpp b/src/KOKKOS/improper_harmonic_kokkos.cpp index 4d41f3ef48..bb397a2c2f 100644 --- a/src/KOKKOS/improper_harmonic_kokkos.cpp +++ b/src/KOKKOS/improper_harmonic_kokkos.cpp @@ -71,8 +71,7 @@ void ImproperHarmonicKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/MOLECULE/improper_cvff.cpp b/src/MOLECULE/improper_cvff.cpp index 641eea74a8..01e9729e80 100644 --- a/src/MOLECULE/improper_cvff.cpp +++ b/src/MOLECULE/improper_cvff.cpp @@ -61,8 +61,7 @@ void ImproperCvff::compute(int eflag, int vflag) double a33,a12,a13,a23,sx2,sy2,sz2; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp index 091bd46316..c5421fffdb 100644 --- a/src/MOLECULE/improper_harmonic.cpp +++ b/src/MOLECULE/improper_harmonic.cpp @@ -61,8 +61,7 @@ void ImproperHarmonic::compute(int eflag, int vflag) double sx2,sy2,sz2; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp index 8ed3d3a84c..3de46df0f3 100644 --- a/src/MOLECULE/improper_umbrella.cpp +++ b/src/MOLECULE/improper_umbrella.cpp @@ -65,8 +65,7 @@ void ImproperUmbrella::compute(int eflag, int vflag) double ax,ay,az,ra2,rh2,ra,rh,rar,rhr,arx,ary,arz,hrx,hry,hrz; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-INTEL/improper_cvff_intel.cpp b/src/USER-INTEL/improper_cvff_intel.cpp index 03bd134b40..de316250c0 100644 --- a/src/USER-INTEL/improper_cvff_intel.cpp +++ b/src/USER-INTEL/improper_cvff_intel.cpp @@ -83,8 +83,7 @@ void ImproperCvffIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-INTEL/improper_harmonic_intel.cpp b/src/USER-INTEL/improper_harmonic_intel.cpp index 167095150e..846c3cfbf9 100644 --- a/src/USER-INTEL/improper_harmonic_intel.cpp +++ b/src/USER-INTEL/improper_harmonic_intel.cpp @@ -84,8 +84,7 @@ void ImproperHarmonicIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-MISC/improper_cossq.cpp b/src/USER-MISC/improper_cossq.cpp index 2483840e42..c8eb0808fb 100644 --- a/src/USER-MISC/improper_cossq.cpp +++ b/src/USER-MISC/improper_cossq.cpp @@ -63,8 +63,7 @@ void ImproperCossq::compute(int eflag, int vflag) eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/improper_distance.cpp b/src/USER-MISC/improper_distance.cpp index 2edf37ec5c..50babcc84e 100644 --- a/src/USER-MISC/improper_distance.cpp +++ b/src/USER-MISC/improper_distance.cpp @@ -67,8 +67,7 @@ void ImproperDistance::compute(int eflag, int vflag) double domega,a; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/improper_fourier.cpp b/src/USER-MISC/improper_fourier.cpp index 927478fa1a..288d888d12 100644 --- a/src/USER-MISC/improper_fourier.cpp +++ b/src/USER-MISC/improper_fourier.cpp @@ -59,8 +59,7 @@ void ImproperFourier::compute(int eflag, int vflag) int i1,i2,i3,i4,n,type; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; int **improperlist = neighbor->improperlist; diff --git a/src/USER-MISC/improper_ring.cpp b/src/USER-MISC/improper_ring.cpp index 70124b2ed1..36ba73af0f 100644 --- a/src/USER-MISC/improper_ring.cpp +++ b/src/USER-MISC/improper_ring.cpp @@ -95,8 +95,7 @@ void ImproperRing::compute(int eflag, int vflag) double cjiji, ckjji, ckjkj, fix, fiy, fiz, fjx, fjy, fjz, fkx, fky, fkz; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); /* References to simulation data. */ double **x = atom->x; diff --git a/src/USER-MOFFF/improper_inversion_harmonic.cpp b/src/USER-MOFFF/improper_inversion_harmonic.cpp index 8404984b53..3f1e61e54a 100644 --- a/src/USER-MOFFF/improper_inversion_harmonic.cpp +++ b/src/USER-MOFFF/improper_inversion_harmonic.cpp @@ -66,8 +66,7 @@ void ImproperInversionHarmonic::compute(int eflag, int vflag) double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z; double rrvb1,rrvb2,rrvb3,rr2vb1,rr2vb2,rr2vb3; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; int **improperlist = neighbor->improperlist; diff --git a/src/USER-OMP/improper_class2_omp.cpp b/src/USER-OMP/improper_class2_omp.cpp index 7184cbeb69..c2b493f425 100644 --- a/src/USER-OMP/improper_class2_omp.cpp +++ b/src/USER-OMP/improper_class2_omp.cpp @@ -43,10 +43,7 @@ ImproperClass2OMP::ImproperClass2OMP(class LAMMPS *lmp) void ImproperClass2OMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/improper_cossq_omp.cpp b/src/USER-OMP/improper_cossq_omp.cpp index 022cfa6adf..3b328e5b78 100644 --- a/src/USER-OMP/improper_cossq_omp.cpp +++ b/src/USER-OMP/improper_cossq_omp.cpp @@ -43,10 +43,7 @@ ImproperCossqOMP::ImproperCossqOMP(class LAMMPS *lmp) void ImproperCossqOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/improper_cvff_omp.cpp b/src/USER-OMP/improper_cvff_omp.cpp index 78c5a55e05..fe1fc45bec 100644 --- a/src/USER-OMP/improper_cvff_omp.cpp +++ b/src/USER-OMP/improper_cvff_omp.cpp @@ -43,10 +43,7 @@ ImproperCvffOMP::ImproperCvffOMP(class LAMMPS *lmp) void ImproperCvffOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/improper_fourier_omp.cpp b/src/USER-OMP/improper_fourier_omp.cpp index 77dd36b64f..b5af428cb9 100644 --- a/src/USER-OMP/improper_fourier_omp.cpp +++ b/src/USER-OMP/improper_fourier_omp.cpp @@ -43,10 +43,7 @@ ImproperFourierOMP::ImproperFourierOMP(class LAMMPS *lmp) void ImproperFourierOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/improper_harmonic_omp.cpp b/src/USER-OMP/improper_harmonic_omp.cpp index 3f1895142d..6e02d0968e 100644 --- a/src/USER-OMP/improper_harmonic_omp.cpp +++ b/src/USER-OMP/improper_harmonic_omp.cpp @@ -43,10 +43,7 @@ ImproperHarmonicOMP::ImproperHarmonicOMP(class LAMMPS *lmp) void ImproperHarmonicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/improper_ring_omp.cpp b/src/USER-OMP/improper_ring_omp.cpp index 7970de3839..e198b99337 100644 --- a/src/USER-OMP/improper_ring_omp.cpp +++ b/src/USER-OMP/improper_ring_omp.cpp @@ -45,10 +45,7 @@ ImproperRingOMP::ImproperRingOMP(class LAMMPS *lmp) void ImproperRingOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/improper_umbrella_omp.cpp b/src/USER-OMP/improper_umbrella_omp.cpp index 69d41176c6..ceaca35074 100644 --- a/src/USER-OMP/improper_umbrella_omp.cpp +++ b/src/USER-OMP/improper_umbrella_omp.cpp @@ -43,10 +43,7 @@ ImproperUmbrellaOMP::ImproperUmbrellaOMP(class LAMMPS *lmp) void ImproperUmbrellaOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-YAFF/improper_distharm.cpp b/src/USER-YAFF/improper_distharm.cpp index 9a54afed9a..b45087a9ab 100644 --- a/src/USER-YAFF/improper_distharm.cpp +++ b/src/USER-YAFF/improper_distharm.cpp @@ -67,8 +67,7 @@ void ImproperDistHarm::compute(int eflag, int vflag) double domega,a; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-YAFF/improper_sqdistharm.cpp b/src/USER-YAFF/improper_sqdistharm.cpp index 763d82f1c5..ae702820cb 100644 --- a/src/USER-YAFF/improper_sqdistharm.cpp +++ b/src/USER-YAFF/improper_sqdistharm.cpp @@ -67,8 +67,7 @@ void ImproperSQDistHarm::compute(int eflag, int vflag) double domega,a; eimproper = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/improper.h b/src/improper.h index adcf6d29c8..8ee2c2996d 100644 --- a/src/improper.h +++ b/src/improper.h @@ -57,6 +57,10 @@ class Improper : protected Pointers { int maxeatom,maxvatom; void ev_setup(int, int, int alloc = 1); + void ev_init(int eflag, int vflag, int alloc = 1) { + if (eflag||vflag) ev_setup(eflag, vflag, alloc); + else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; + } void ev_tally(int, int, int, int, int, int, double, double *, double *, double *, double, double, double, double, double, double, double, double, double); diff --git a/src/improper_hybrid.cpp b/src/improper_hybrid.cpp index 3c17e42eaf..5fdcb42a96 100644 --- a/src/improper_hybrid.cpp +++ b/src/improper_hybrid.cpp @@ -104,8 +104,7 @@ void ImproperHybrid::compute(int eflag, int vflag) // set neighbor->improperlist to sub-style improperlist before call // accumulate sub-style global/peratom energy/virial in hybrid - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); for (m = 0; m < nstyles; m++) { neighbor->nimproperlist = nimproperlist[m]; diff --git a/src/improper_zero.cpp b/src/improper_zero.cpp index 8a1fa529c6..747dd57919 100644 --- a/src/improper_zero.cpp +++ b/src/improper_zero.cpp @@ -44,8 +44,7 @@ ImproperZero::~ImproperZero() void ImproperZero::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); } /* ---------------------------------------------------------------------- */ -- GitLab From 6e6f9038181acc6348f8e2f53057dbeb05660fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 17:51:41 +0100 Subject: [PATCH 0235/1243] use ev_init for angles --- src/CLASS2/angle_class2.cpp | 3 +-- src/KOKKOS/angle_charmm_kokkos.cpp | 3 +-- src/KOKKOS/angle_class2_kokkos.cpp | 3 +-- src/KOKKOS/angle_cosine_kokkos.cpp | 3 +-- src/KOKKOS/angle_harmonic_kokkos.cpp | 3 +-- src/MOLECULE/angle_charmm.cpp | 3 +-- src/MOLECULE/angle_cosine.cpp | 3 +-- src/MOLECULE/angle_cosine_delta.cpp | 3 +-- src/MOLECULE/angle_cosine_periodic.cpp | 3 +-- src/MOLECULE/angle_cosine_squared.cpp | 3 +-- src/MOLECULE/angle_harmonic.cpp | 3 +-- src/MOLECULE/angle_table.cpp | 3 +-- src/USER-CGSDK/angle_sdk.cpp | 3 +-- src/USER-INTEL/angle_charmm_intel.cpp | 3 +-- src/USER-INTEL/angle_harmonic_intel.cpp | 3 +-- src/USER-MISC/angle_cosine_shift.cpp | 3 +-- src/USER-MISC/angle_cosine_shift_exp.cpp | 3 +-- src/USER-MISC/angle_dipole.cpp | 3 +-- src/USER-MISC/angle_fourier.cpp | 3 +-- src/USER-MISC/angle_fourier_simple.cpp | 3 +-- src/USER-MISC/angle_quartic.cpp | 3 +-- src/USER-MOFFF/angle_class2_p6.cpp | 3 +-- src/USER-MOFFF/angle_cosine_buck6d.cpp | 3 +-- src/USER-OMP/angle_charmm_omp.cpp | 5 +---- src/USER-OMP/angle_class2_omp.cpp | 5 +---- src/USER-OMP/angle_cosine_delta_omp.cpp | 5 +---- src/USER-OMP/angle_cosine_omp.cpp | 5 +---- src/USER-OMP/angle_cosine_periodic_omp.cpp | 5 +---- src/USER-OMP/angle_cosine_shift_exp_omp.cpp | 5 +---- src/USER-OMP/angle_cosine_shift_omp.cpp | 5 +---- src/USER-OMP/angle_cosine_squared_omp.cpp | 5 +---- src/USER-OMP/angle_dipole_omp.cpp | 5 +---- src/USER-OMP/angle_fourier_omp.cpp | 5 +---- src/USER-OMP/angle_fourier_simple_omp.cpp | 5 +---- src/USER-OMP/angle_harmonic_omp.cpp | 5 +---- src/USER-OMP/angle_quartic_omp.cpp | 5 +---- src/USER-OMP/angle_sdk_omp.cpp | 5 +---- src/USER-OMP/angle_table_omp.cpp | 5 +---- src/USER-YAFF/angle_cross.cpp | 3 +-- src/USER-YAFF/angle_mm3.cpp | 3 +-- src/angle.h | 4 ++++ src/angle_hybrid.cpp | 3 +-- src/angle_zero.cpp | 3 +-- 43 files changed, 46 insertions(+), 114 deletions(-) diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp index 24f41bfd58..d550767e5e 100644 --- a/src/CLASS2/angle_class2.cpp +++ b/src/CLASS2/angle_class2.cpp @@ -78,8 +78,7 @@ void AngleClass2::compute(int eflag, int vflag) double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KOKKOS/angle_charmm_kokkos.cpp b/src/KOKKOS/angle_charmm_kokkos.cpp index ec2955b28d..0f46c958d6 100644 --- a/src/KOKKOS/angle_charmm_kokkos.cpp +++ b/src/KOKKOS/angle_charmm_kokkos.cpp @@ -64,8 +64,7 @@ void AngleCharmmKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/angle_class2_kokkos.cpp b/src/KOKKOS/angle_class2_kokkos.cpp index fe5b1895fe..836714764d 100644 --- a/src/KOKKOS/angle_class2_kokkos.cpp +++ b/src/KOKKOS/angle_class2_kokkos.cpp @@ -64,8 +64,7 @@ void AngleClass2Kokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/angle_cosine_kokkos.cpp b/src/KOKKOS/angle_cosine_kokkos.cpp index 08faa254f4..4a4866948f 100644 --- a/src/KOKKOS/angle_cosine_kokkos.cpp +++ b/src/KOKKOS/angle_cosine_kokkos.cpp @@ -64,8 +64,7 @@ void AngleCosineKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/angle_harmonic_kokkos.cpp b/src/KOKKOS/angle_harmonic_kokkos.cpp index 8cdab2063a..dbe705800c 100644 --- a/src/KOKKOS/angle_harmonic_kokkos.cpp +++ b/src/KOKKOS/angle_harmonic_kokkos.cpp @@ -64,8 +64,7 @@ void AngleHarmonicKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp index 3608601c1f..efd1c682f7 100644 --- a/src/MOLECULE/angle_charmm.cpp +++ b/src/MOLECULE/angle_charmm.cpp @@ -61,8 +61,7 @@ void AngleCharmm::compute(int eflag, int vflag) double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/angle_cosine.cpp b/src/MOLECULE/angle_cosine.cpp index 18763e1b76..6e1b9fa2fb 100644 --- a/src/MOLECULE/angle_cosine.cpp +++ b/src/MOLECULE/angle_cosine.cpp @@ -52,8 +52,7 @@ void AngleCosine::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/angle_cosine_delta.cpp b/src/MOLECULE/angle_cosine_delta.cpp index 6f4f5c20d7..eca10970f2 100644 --- a/src/MOLECULE/angle_cosine_delta.cpp +++ b/src/MOLECULE/angle_cosine_delta.cpp @@ -44,8 +44,7 @@ void AngleCosineDelta::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,a,cot,a11,a12,a22,b11,b12,b22,c0,s0,s; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/angle_cosine_periodic.cpp b/src/MOLECULE/angle_cosine_periodic.cpp index e8dd970b3b..cb0a26871a 100644 --- a/src/MOLECULE/angle_cosine_periodic.cpp +++ b/src/MOLECULE/angle_cosine_periodic.cpp @@ -61,8 +61,7 @@ void AngleCosinePeriodic::compute(int eflag, int vflag) double tn,tn_1,tn_2,un,un_1,un_2; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/angle_cosine_squared.cpp b/src/MOLECULE/angle_cosine_squared.cpp index c83ba90a60..28d63344a4 100644 --- a/src/MOLECULE/angle_cosine_squared.cpp +++ b/src/MOLECULE/angle_cosine_squared.cpp @@ -62,8 +62,7 @@ void AngleCosineSquared::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp index d28afd76d6..48b493d9b2 100644 --- a/src/MOLECULE/angle_harmonic.cpp +++ b/src/MOLECULE/angle_harmonic.cpp @@ -58,8 +58,7 @@ void AngleHarmonic::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/angle_table.cpp b/src/MOLECULE/angle_table.cpp index 6c1af54dcf..7dd56ffb76 100644 --- a/src/MOLECULE/angle_table.cpp +++ b/src/MOLECULE/angle_table.cpp @@ -72,8 +72,7 @@ void AngleTable::compute(int eflag, int vflag) double theta,u,mdu; //mdu: minus du, -du/dx=f eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-CGSDK/angle_sdk.cpp b/src/USER-CGSDK/angle_sdk.cpp index 6b8245b491..823c725e07 100644 --- a/src/USER-CGSDK/angle_sdk.cpp +++ b/src/USER-CGSDK/angle_sdk.cpp @@ -68,8 +68,7 @@ void AngleSDK::compute(int eflag, int vflag) double rsq1,rsq2,rsq3,r1,r2,c,s,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-INTEL/angle_charmm_intel.cpp b/src/USER-INTEL/angle_charmm_intel.cpp index f2542fc0c7..c5ada951a5 100644 --- a/src/USER-INTEL/angle_charmm_intel.cpp +++ b/src/USER-INTEL/angle_charmm_intel.cpp @@ -78,8 +78,7 @@ void AngleCharmmIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-INTEL/angle_harmonic_intel.cpp b/src/USER-INTEL/angle_harmonic_intel.cpp index 6d8901a5ee..aae6fcf0a2 100644 --- a/src/USER-INTEL/angle_harmonic_intel.cpp +++ b/src/USER-INTEL/angle_harmonic_intel.cpp @@ -78,8 +78,7 @@ void AngleHarmonicIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-MISC/angle_cosine_shift.cpp b/src/USER-MISC/angle_cosine_shift.cpp index a361db4970..18c87c81e3 100644 --- a/src/USER-MISC/angle_cosine_shift.cpp +++ b/src/USER-MISC/angle_cosine_shift.cpp @@ -62,8 +62,7 @@ void AngleCosineShift::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,s,cps,kcos,ksin,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/angle_cosine_shift_exp.cpp b/src/USER-MISC/angle_cosine_shift_exp.cpp index c87c73171a..8c6282de20 100644 --- a/src/USER-MISC/angle_cosine_shift_exp.cpp +++ b/src/USER-MISC/angle_cosine_shift_exp.cpp @@ -72,8 +72,7 @@ void AngleCosineShiftExp::compute(int eflag, int vflag) double exp2,aa,uumin,cccpsss,cssmscc; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/angle_dipole.cpp b/src/USER-MISC/angle_dipole.cpp index c4186da472..781da46869 100644 --- a/src/USER-MISC/angle_dipole.cpp +++ b/src/USER-MISC/angle_dipole.cpp @@ -59,8 +59,7 @@ void AngleDipole::compute(int eflag, int vflag) double r,cosGamma,deltaGamma,kdg,rmu; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; // position vector double **mu = atom->mu; // point-dipole components and moment magnitude diff --git a/src/USER-MISC/angle_fourier.cpp b/src/USER-MISC/angle_fourier.cpp index e6cc1f1a7e..8f5074ff5d 100644 --- a/src/USER-MISC/angle_fourier.cpp +++ b/src/USER-MISC/angle_fourier.cpp @@ -67,8 +67,7 @@ void AngleFourier::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,c2,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/angle_fourier_simple.cpp b/src/USER-MISC/angle_fourier_simple.cpp index 8464fe815c..615556bbe7 100644 --- a/src/USER-MISC/angle_fourier_simple.cpp +++ b/src/USER-MISC/angle_fourier_simple.cpp @@ -65,8 +65,7 @@ void AngleFourierSimple::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,cn,th,nth,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/angle_quartic.cpp b/src/USER-MISC/angle_quartic.cpp index 356f2df5d4..21a96100aa 100644 --- a/src/USER-MISC/angle_quartic.cpp +++ b/src/USER-MISC/angle_quartic.cpp @@ -61,8 +61,7 @@ void AngleQuartic::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MOFFF/angle_class2_p6.cpp b/src/USER-MOFFF/angle_class2_p6.cpp index d2a6e21e6b..e8e6f279de 100644 --- a/src/USER-MOFFF/angle_class2_p6.cpp +++ b/src/USER-MOFFF/angle_class2_p6.cpp @@ -79,8 +79,7 @@ void AngleClass2P6::compute(int eflag, int vflag) double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MOFFF/angle_cosine_buck6d.cpp b/src/USER-MOFFF/angle_cosine_buck6d.cpp index f358097802..3829d2b8dc 100644 --- a/src/USER-MOFFF/angle_cosine_buck6d.cpp +++ b/src/USER-MOFFF/angle_cosine_buck6d.cpp @@ -69,8 +69,7 @@ void AngleCosineBuck6d::compute(int eflag, int vflag) double rcu,rqu,sme,smf; eangle = evdwl = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-3 virial contribution diff --git a/src/USER-OMP/angle_charmm_omp.cpp b/src/USER-OMP/angle_charmm_omp.cpp index 1f24438df3..118ba00226 100644 --- a/src/USER-OMP/angle_charmm_omp.cpp +++ b/src/USER-OMP/angle_charmm_omp.cpp @@ -44,10 +44,7 @@ using namespace MathConst; void AngleCharmmOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_class2_omp.cpp b/src/USER-OMP/angle_class2_omp.cpp index bd13e20bcc..e072d136e1 100644 --- a/src/USER-OMP/angle_class2_omp.cpp +++ b/src/USER-OMP/angle_class2_omp.cpp @@ -44,10 +44,7 @@ AngleClass2OMP::AngleClass2OMP(class LAMMPS *lmp) void AngleClass2OMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_cosine_delta_omp.cpp b/src/USER-OMP/angle_cosine_delta_omp.cpp index b3bb3e1f8a..a6dfb20433 100644 --- a/src/USER-OMP/angle_cosine_delta_omp.cpp +++ b/src/USER-OMP/angle_cosine_delta_omp.cpp @@ -44,10 +44,7 @@ AngleCosineDeltaOMP::AngleCosineDeltaOMP(class LAMMPS *lmp) void AngleCosineDeltaOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_cosine_omp.cpp b/src/USER-OMP/angle_cosine_omp.cpp index 04b3870bc4..9097c8569c 100644 --- a/src/USER-OMP/angle_cosine_omp.cpp +++ b/src/USER-OMP/angle_cosine_omp.cpp @@ -44,10 +44,7 @@ AngleCosineOMP::AngleCosineOMP(class LAMMPS *lmp) void AngleCosineOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_cosine_periodic_omp.cpp b/src/USER-OMP/angle_cosine_periodic_omp.cpp index 8060ebec7b..3fcea7ad1d 100644 --- a/src/USER-OMP/angle_cosine_periodic_omp.cpp +++ b/src/USER-OMP/angle_cosine_periodic_omp.cpp @@ -46,10 +46,7 @@ AngleCosinePeriodicOMP::AngleCosinePeriodicOMP(class LAMMPS *lmp) void AngleCosinePeriodicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_cosine_shift_exp_omp.cpp b/src/USER-OMP/angle_cosine_shift_exp_omp.cpp index 3e00681ec9..6bd2feb023 100644 --- a/src/USER-OMP/angle_cosine_shift_exp_omp.cpp +++ b/src/USER-OMP/angle_cosine_shift_exp_omp.cpp @@ -44,10 +44,7 @@ AngleCosineShiftExpOMP::AngleCosineShiftExpOMP(class LAMMPS *lmp) void AngleCosineShiftExpOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_cosine_shift_omp.cpp b/src/USER-OMP/angle_cosine_shift_omp.cpp index 0ab3df4359..56486faac1 100644 --- a/src/USER-OMP/angle_cosine_shift_omp.cpp +++ b/src/USER-OMP/angle_cosine_shift_omp.cpp @@ -44,10 +44,7 @@ AngleCosineShiftOMP::AngleCosineShiftOMP(class LAMMPS *lmp) void AngleCosineShiftOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_cosine_squared_omp.cpp b/src/USER-OMP/angle_cosine_squared_omp.cpp index a1b1ffdf1a..6dd2a3bb3b 100644 --- a/src/USER-OMP/angle_cosine_squared_omp.cpp +++ b/src/USER-OMP/angle_cosine_squared_omp.cpp @@ -44,10 +44,7 @@ AngleCosineSquaredOMP::AngleCosineSquaredOMP(class LAMMPS *lmp) void AngleCosineSquaredOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_dipole_omp.cpp b/src/USER-OMP/angle_dipole_omp.cpp index 92a5ba092e..da2e819ee2 100644 --- a/src/USER-OMP/angle_dipole_omp.cpp +++ b/src/USER-OMP/angle_dipole_omp.cpp @@ -45,10 +45,7 @@ AngleDipoleOMP::AngleDipoleOMP(class LAMMPS *lmp) void AngleDipoleOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); if (!force->newton_bond) error->all(FLERR,"'newton' flag for bonded interactions must be 'on'"); diff --git a/src/USER-OMP/angle_fourier_omp.cpp b/src/USER-OMP/angle_fourier_omp.cpp index dfc713c372..b2f9b47e05 100644 --- a/src/USER-OMP/angle_fourier_omp.cpp +++ b/src/USER-OMP/angle_fourier_omp.cpp @@ -44,10 +44,7 @@ AngleFourierOMP::AngleFourierOMP(class LAMMPS *lmp) void AngleFourierOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_fourier_simple_omp.cpp b/src/USER-OMP/angle_fourier_simple_omp.cpp index dea7a88723..93532a30e5 100644 --- a/src/USER-OMP/angle_fourier_simple_omp.cpp +++ b/src/USER-OMP/angle_fourier_simple_omp.cpp @@ -44,10 +44,7 @@ AngleFourierSimpleOMP::AngleFourierSimpleOMP(class LAMMPS *lmp) void AngleFourierSimpleOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_harmonic_omp.cpp b/src/USER-OMP/angle_harmonic_omp.cpp index 0a71e5c9dd..824b254287 100644 --- a/src/USER-OMP/angle_harmonic_omp.cpp +++ b/src/USER-OMP/angle_harmonic_omp.cpp @@ -44,10 +44,7 @@ AngleHarmonicOMP::AngleHarmonicOMP(class LAMMPS *lmp) void AngleHarmonicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_quartic_omp.cpp b/src/USER-OMP/angle_quartic_omp.cpp index 97a9b14f1d..fff08ddb39 100644 --- a/src/USER-OMP/angle_quartic_omp.cpp +++ b/src/USER-OMP/angle_quartic_omp.cpp @@ -44,10 +44,7 @@ AngleQuarticOMP::AngleQuarticOMP(class LAMMPS *lmp) void AngleQuarticOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_sdk_omp.cpp b/src/USER-OMP/angle_sdk_omp.cpp index 9383a9af83..e8c762092c 100644 --- a/src/USER-OMP/angle_sdk_omp.cpp +++ b/src/USER-OMP/angle_sdk_omp.cpp @@ -46,10 +46,7 @@ AngleSDKOMP::AngleSDKOMP(class LAMMPS *lmp) void AngleSDKOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/angle_table_omp.cpp b/src/USER-OMP/angle_table_omp.cpp index c3d2307489..d9d80b744d 100644 --- a/src/USER-OMP/angle_table_omp.cpp +++ b/src/USER-OMP/angle_table_omp.cpp @@ -44,10 +44,7 @@ AngleTableOMP::AngleTableOMP(class LAMMPS *lmp) void AngleTableOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-YAFF/angle_cross.cpp b/src/USER-YAFF/angle_cross.cpp index 6333c2f035..2e6731f494 100644 --- a/src/USER-YAFF/angle_cross.cpp +++ b/src/USER-YAFF/angle_cross.cpp @@ -67,8 +67,7 @@ void AngleCross::compute(int eflag, int vflag) double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-YAFF/angle_mm3.cpp b/src/USER-YAFF/angle_mm3.cpp index 4e44f10408..53cb11b5df 100644 --- a/src/USER-YAFF/angle_mm3.cpp +++ b/src/USER-YAFF/angle_mm3.cpp @@ -61,8 +61,7 @@ void AngleMM3::compute(int eflag, int vflag) double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22; eangle = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/angle.h b/src/angle.h index 0247fa0ff8..196c2a44d1 100644 --- a/src/angle.h +++ b/src/angle.h @@ -59,6 +59,10 @@ class Angle : protected Pointers { int maxeatom,maxvatom; void ev_setup(int, int, int alloc = 1); + void ev_init(int eflag, int vflag, int alloc = 1) { + if (eflag||vflag) ev_setup(eflag, vflag, alloc); + else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; + } void ev_tally(int, int, int, int, int, double, double *, double *, double, double, double, double, double, double); }; diff --git a/src/angle_hybrid.cpp b/src/angle_hybrid.cpp index c29eaac2ae..6afa7413b2 100644 --- a/src/angle_hybrid.cpp +++ b/src/angle_hybrid.cpp @@ -103,8 +103,7 @@ void AngleHybrid::compute(int eflag, int vflag) // set neighbor->anglelist to sub-style anglelist before call // accumulate sub-style global/peratom energy/virial in hybrid - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); for (m = 0; m < nstyles; m++) { neighbor->nanglelist = nanglelist[m]; diff --git a/src/angle_zero.cpp b/src/angle_zero.cpp index d7b7c9cdb5..6eb127fa58 100644 --- a/src/angle_zero.cpp +++ b/src/angle_zero.cpp @@ -47,8 +47,7 @@ AngleZero::~AngleZero() void AngleZero::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); } /* ---------------------------------------------------------------------- */ -- GitLab From fbd600592b802cdcb3a45e0bbf3126ae5c1c702c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 17:53:22 +0100 Subject: [PATCH 0236/1243] use ev_init for dihedrals --- src/CLASS2/dihedral_class2.cpp | 3 +-- src/KOKKOS/dihedral_charmm_kokkos.cpp | 3 +-- src/KOKKOS/dihedral_class2_kokkos.cpp | 3 +-- src/KOKKOS/dihedral_opls_kokkos.cpp | 3 +-- src/MOLECULE/dihedral_charmm.cpp | 3 +-- src/MOLECULE/dihedral_charmmfsw.cpp | 3 +-- src/MOLECULE/dihedral_harmonic.cpp | 3 +-- src/MOLECULE/dihedral_helix.cpp | 3 +-- src/MOLECULE/dihedral_multi_harmonic.cpp | 3 +-- src/MOLECULE/dihedral_opls.cpp | 3 +-- src/USER-INTEL/dihedral_charmm_intel.cpp | 4 +--- src/USER-INTEL/dihedral_fourier_intel.cpp | 4 +--- src/USER-INTEL/dihedral_harmonic_intel.cpp | 4 +--- src/USER-INTEL/dihedral_opls_intel.cpp | 4 +--- src/USER-MISC/dihedral_cosine_shift_exp.cpp | 3 +-- src/USER-MISC/dihedral_fourier.cpp | 3 +-- src/USER-MISC/dihedral_nharmonic.cpp | 3 +-- src/USER-MISC/dihedral_quadratic.cpp | 3 +-- src/USER-MISC/dihedral_spherical.cpp | 3 +-- src/USER-MISC/dihedral_table.cpp | 3 +-- src/USER-MISC/dihedral_table_cut.cpp | 3 +-- src/USER-OMP/dihedral_charmm_omp.cpp | 5 +---- src/USER-OMP/dihedral_class2_omp.cpp | 5 +---- src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp | 5 +---- src/USER-OMP/dihedral_fourier_omp.cpp | 5 +---- src/USER-OMP/dihedral_harmonic_omp.cpp | 5 +---- src/USER-OMP/dihedral_helix_omp.cpp | 5 +---- src/USER-OMP/dihedral_multi_harmonic_omp.cpp | 5 +---- src/USER-OMP/dihedral_nharmonic_omp.cpp | 5 +---- src/USER-OMP/dihedral_opls_omp.cpp | 5 +---- src/USER-OMP/dihedral_quadratic_omp.cpp | 5 +---- src/USER-OMP/dihedral_table_omp.cpp | 5 +---- src/dihedral.h | 4 ++++ src/dihedral_hybrid.cpp | 3 +-- src/dihedral_zero.cpp | 3 +-- 35 files changed, 38 insertions(+), 94 deletions(-) diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp index c6360dd846..c471b1f353 100644 --- a/src/CLASS2/dihedral_class2.cpp +++ b/src/CLASS2/dihedral_class2.cpp @@ -118,8 +118,7 @@ void DihedralClass2::compute(int eflag, int vflag) double fabcd[4][3]; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KOKKOS/dihedral_charmm_kokkos.cpp b/src/KOKKOS/dihedral_charmm_kokkos.cpp index 3931309dc1..61ddcc425a 100644 --- a/src/KOKKOS/dihedral_charmm_kokkos.cpp +++ b/src/KOKKOS/dihedral_charmm_kokkos.cpp @@ -69,8 +69,7 @@ void DihedralCharmmKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/KOKKOS/dihedral_class2_kokkos.cpp b/src/KOKKOS/dihedral_class2_kokkos.cpp index c7db07a6cb..98436bc696 100644 --- a/src/KOKKOS/dihedral_class2_kokkos.cpp +++ b/src/KOKKOS/dihedral_class2_kokkos.cpp @@ -69,8 +69,7 @@ void DihedralClass2Kokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/dihedral_opls_kokkos.cpp b/src/KOKKOS/dihedral_opls_kokkos.cpp index 9d01cf1a54..f50dea2c36 100644 --- a/src/KOKKOS/dihedral_opls_kokkos.cpp +++ b/src/KOKKOS/dihedral_opls_kokkos.cpp @@ -69,8 +69,7 @@ void DihedralOPLSKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp index 2372fae38b..68c62eb4fd 100644 --- a/src/MOLECULE/dihedral_charmm.cpp +++ b/src/MOLECULE/dihedral_charmm.cpp @@ -76,8 +76,7 @@ void DihedralCharmm::compute(int eflag, int vflag) double forcecoul,forcelj,fpair,ecoul,evdwl; edihedral = evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/MOLECULE/dihedral_charmmfsw.cpp b/src/MOLECULE/dihedral_charmmfsw.cpp index 99a5333620..f65d01e9ed 100644 --- a/src/MOLECULE/dihedral_charmmfsw.cpp +++ b/src/MOLECULE/dihedral_charmmfsw.cpp @@ -79,8 +79,7 @@ void DihedralCharmmfsw::compute(int eflag, int vflag) double forcecoul,forcelj,fpair,ecoul,evdwl; edihedral = evdwl = ecoul = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/MOLECULE/dihedral_harmonic.cpp b/src/MOLECULE/dihedral_harmonic.cpp index cb122f4bc2..ddb94dc571 100644 --- a/src/MOLECULE/dihedral_harmonic.cpp +++ b/src/MOLECULE/dihedral_harmonic.cpp @@ -67,8 +67,7 @@ void DihedralHarmonic::compute(int eflag, int vflag) double c,s,p,sx2,sy2,sz2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp index ae23b77951..6b6d19ecdf 100644 --- a/src/MOLECULE/dihedral_helix.cpp +++ b/src/MOLECULE/dihedral_helix.cpp @@ -67,8 +67,7 @@ void DihedralHelix::compute(int eflag, int vflag) double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/dihedral_multi_harmonic.cpp b/src/MOLECULE/dihedral_multi_harmonic.cpp index f6461abb6e..f0097342a8 100644 --- a/src/MOLECULE/dihedral_multi_harmonic.cpp +++ b/src/MOLECULE/dihedral_multi_harmonic.cpp @@ -64,8 +64,7 @@ void DihedralMultiHarmonic::compute(int eflag, int vflag) double s2,sin2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/dihedral_opls.cpp b/src/MOLECULE/dihedral_opls.cpp index b5103413b2..293245e411 100644 --- a/src/MOLECULE/dihedral_opls.cpp +++ b/src/MOLECULE/dihedral_opls.cpp @@ -67,8 +67,7 @@ void DihedralOPLS::compute(int eflag, int vflag) double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-INTEL/dihedral_charmm_intel.cpp b/src/USER-INTEL/dihedral_charmm_intel.cpp index c9237e7309..4f4b091300 100644 --- a/src/USER-INTEL/dihedral_charmm_intel.cpp +++ b/src/USER-INTEL/dihedral_charmm_intel.cpp @@ -84,9 +84,7 @@ void DihedralCharmmIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/USER-INTEL/dihedral_fourier_intel.cpp b/src/USER-INTEL/dihedral_fourier_intel.cpp index 6ccc165c61..030d371e44 100644 --- a/src/USER-INTEL/dihedral_fourier_intel.cpp +++ b/src/USER-INTEL/dihedral_fourier_intel.cpp @@ -73,9 +73,7 @@ void DihedralFourierIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-INTEL/dihedral_harmonic_intel.cpp b/src/USER-INTEL/dihedral_harmonic_intel.cpp index ae5eb914e7..d84db4f4ac 100644 --- a/src/USER-INTEL/dihedral_harmonic_intel.cpp +++ b/src/USER-INTEL/dihedral_harmonic_intel.cpp @@ -73,9 +73,7 @@ void DihedralHarmonicIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-INTEL/dihedral_opls_intel.cpp b/src/USER-INTEL/dihedral_opls_intel.cpp index 7a60b62cae..eae796974b 100644 --- a/src/USER-INTEL/dihedral_opls_intel.cpp +++ b/src/USER-INTEL/dihedral_opls_intel.cpp @@ -77,9 +77,7 @@ void DihedralOPLSIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-MISC/dihedral_cosine_shift_exp.cpp b/src/USER-MISC/dihedral_cosine_shift_exp.cpp index 82da173f8e..c1396aba11 100644 --- a/src/USER-MISC/dihedral_cosine_shift_exp.cpp +++ b/src/USER-MISC/dihedral_cosine_shift_exp.cpp @@ -68,8 +68,7 @@ void DihedralCosineShiftExp::compute(int eflag, int vflag) double cccpsss,cssmscc,exp2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/dihedral_fourier.cpp b/src/USER-MISC/dihedral_fourier.cpp index 7c405ee28c..af86259c01 100644 --- a/src/USER-MISC/dihedral_fourier.cpp +++ b/src/USER-MISC/dihedral_fourier.cpp @@ -79,8 +79,7 @@ void DihedralFourier::compute(int eflag, int vflag) double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; double c,s,p_,sx2,sy2,sz2; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/dihedral_nharmonic.cpp b/src/USER-MISC/dihedral_nharmonic.cpp index f8e8850680..189555946b 100644 --- a/src/USER-MISC/dihedral_nharmonic.cpp +++ b/src/USER-MISC/dihedral_nharmonic.cpp @@ -66,8 +66,7 @@ void DihedralNHarmonic::compute(int eflag, int vflag) double s2,sin2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/dihedral_quadratic.cpp b/src/USER-MISC/dihedral_quadratic.cpp index 1b64b52faf..4c65f2fd70 100644 --- a/src/USER-MISC/dihedral_quadratic.cpp +++ b/src/USER-MISC/dihedral_quadratic.cpp @@ -65,8 +65,7 @@ void DihedralQuadratic::compute(int eflag, int vflag) double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/dihedral_spherical.cpp b/src/USER-MISC/dihedral_spherical.cpp index 77fa885b7a..97cdf13801 100644 --- a/src/USER-MISC/dihedral_spherical.cpp +++ b/src/USER-MISC/dihedral_spherical.cpp @@ -213,8 +213,7 @@ void DihedralSpherical::compute(int eflag, int vflag) // perp34on23[d] = v34[d] - proj34on23[d] edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); for (n = 0; n < ndihedrallist; n++) { diff --git a/src/USER-MISC/dihedral_table.cpp b/src/USER-MISC/dihedral_table.cpp index e221a54a82..a97ae3649f 100644 --- a/src/USER-MISC/dihedral_table.cpp +++ b/src/USER-MISC/dihedral_table.cpp @@ -549,8 +549,7 @@ void DihedralTable::compute(int eflag, int vflag) edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); for (n = 0; n < ndihedrallist; n++) { diff --git a/src/USER-MISC/dihedral_table_cut.cpp b/src/USER-MISC/dihedral_table_cut.cpp index 6ebe094e50..a11ad94969 100644 --- a/src/USER-MISC/dihedral_table_cut.cpp +++ b/src/USER-MISC/dihedral_table_cut.cpp @@ -472,8 +472,7 @@ void DihedralTableCut::compute(int eflag, int vflag) double fabcd[4][3]; edihedral = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-OMP/dihedral_charmm_omp.cpp b/src/USER-OMP/dihedral_charmm_omp.cpp index 1bed449774..b09863613e 100644 --- a/src/USER-OMP/dihedral_charmm_omp.cpp +++ b/src/USER-OMP/dihedral_charmm_omp.cpp @@ -45,10 +45,7 @@ DihedralCharmmOMP::DihedralCharmmOMP(class LAMMPS *lmp) void DihedralCharmmOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/USER-OMP/dihedral_class2_omp.cpp b/src/USER-OMP/dihedral_class2_omp.cpp index c7ae1572c7..03ac9d9bab 100644 --- a/src/USER-OMP/dihedral_class2_omp.cpp +++ b/src/USER-OMP/dihedral_class2_omp.cpp @@ -43,10 +43,7 @@ DihedralClass2OMP::DihedralClass2OMP(class LAMMPS *lmp) void DihedralClass2OMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp index c43b990028..c64cad9fc3 100644 --- a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp +++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp @@ -43,10 +43,7 @@ DihedralCosineShiftExpOMP::DihedralCosineShiftExpOMP(class LAMMPS *lmp) void DihedralCosineShiftExpOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_fourier_omp.cpp b/src/USER-OMP/dihedral_fourier_omp.cpp index 319acb0beb..94bdae3795 100644 --- a/src/USER-OMP/dihedral_fourier_omp.cpp +++ b/src/USER-OMP/dihedral_fourier_omp.cpp @@ -44,10 +44,7 @@ DihedralFourierOMP::DihedralFourierOMP(class LAMMPS *lmp) void DihedralFourierOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_harmonic_omp.cpp b/src/USER-OMP/dihedral_harmonic_omp.cpp index bb659cf262..10ccbd3d9f 100644 --- a/src/USER-OMP/dihedral_harmonic_omp.cpp +++ b/src/USER-OMP/dihedral_harmonic_omp.cpp @@ -43,10 +43,7 @@ DihedralHarmonicOMP::DihedralHarmonicOMP(class LAMMPS *lmp) void DihedralHarmonicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp index e40f084e54..8c8e29cac0 100644 --- a/src/USER-OMP/dihedral_helix_omp.cpp +++ b/src/USER-OMP/dihedral_helix_omp.cpp @@ -46,10 +46,7 @@ DihedralHelixOMP::DihedralHelixOMP(class LAMMPS *lmp) void DihedralHelixOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp index e10fc7b94a..38961e1746 100644 --- a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp +++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp @@ -43,10 +43,7 @@ DihedralMultiHarmonicOMP::DihedralMultiHarmonicOMP(class LAMMPS *lmp) void DihedralMultiHarmonicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_nharmonic_omp.cpp b/src/USER-OMP/dihedral_nharmonic_omp.cpp index ad758fc892..e74238265d 100644 --- a/src/USER-OMP/dihedral_nharmonic_omp.cpp +++ b/src/USER-OMP/dihedral_nharmonic_omp.cpp @@ -43,10 +43,7 @@ DihedralNHarmonicOMP::DihedralNHarmonicOMP(class LAMMPS *lmp) void DihedralNHarmonicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_opls_omp.cpp b/src/USER-OMP/dihedral_opls_omp.cpp index 53fddf51cb..64eaffe6fe 100644 --- a/src/USER-OMP/dihedral_opls_omp.cpp +++ b/src/USER-OMP/dihedral_opls_omp.cpp @@ -44,10 +44,7 @@ DihedralOPLSOMP::DihedralOPLSOMP(class LAMMPS *lmp) void DihedralOPLSOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_quadratic_omp.cpp b/src/USER-OMP/dihedral_quadratic_omp.cpp index f6110cd505..8df622b847 100644 --- a/src/USER-OMP/dihedral_quadratic_omp.cpp +++ b/src/USER-OMP/dihedral_quadratic_omp.cpp @@ -44,10 +44,7 @@ DihedralQuadraticOMP::DihedralQuadraticOMP(class LAMMPS *lmp) void DihedralQuadraticOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/dihedral_table_omp.cpp b/src/USER-OMP/dihedral_table_omp.cpp index 1457f7b2bf..792ee90c26 100644 --- a/src/USER-OMP/dihedral_table_omp.cpp +++ b/src/USER-OMP/dihedral_table_omp.cpp @@ -111,10 +111,7 @@ DihedralTableOMP::DihedralTableOMP(class LAMMPS *lmp) void DihedralTableOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/dihedral.h b/src/dihedral.h index 627104871b..0769d79163 100644 --- a/src/dihedral.h +++ b/src/dihedral.h @@ -57,6 +57,10 @@ class Dihedral : protected Pointers { int maxeatom,maxvatom; void ev_setup(int, int, int alloc = 1); + void ev_init(int eflag, int vflag, int alloc = 1) { + if (eflag||vflag) ev_setup(eflag, vflag, alloc); + else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; + } void ev_tally(int, int, int, int, int, int, double, double *, double *, double *, double, double, double, double, double, double, double, double, double); diff --git a/src/dihedral_hybrid.cpp b/src/dihedral_hybrid.cpp index b9107ac874..f3e4823d53 100644 --- a/src/dihedral_hybrid.cpp +++ b/src/dihedral_hybrid.cpp @@ -104,8 +104,7 @@ void DihedralHybrid::compute(int eflag, int vflag) // set neighbor->dihedrallist to sub-style dihedrallist before call // accumulate sub-style global/peratom energy/virial in hybrid - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); for (m = 0; m < nstyles; m++) { neighbor->ndihedrallist = ndihedrallist[m]; diff --git a/src/dihedral_zero.cpp b/src/dihedral_zero.cpp index 46facdb6db..8145d5f32d 100644 --- a/src/dihedral_zero.cpp +++ b/src/dihedral_zero.cpp @@ -44,8 +44,7 @@ DihedralZero::~DihedralZero() void DihedralZero::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); } /* ---------------------------------------------------------------------- */ -- GitLab From ff2d8e55c99dca2a55a537b12f6e3dcf30b87b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 17:54:10 +0100 Subject: [PATCH 0237/1243] use ev_init for bonds --- src/CLASS2/bond_class2.cpp | 3 +-- src/KOKKOS/bond_class2_kokkos.cpp | 3 +-- src/KOKKOS/bond_fene_kokkos.cpp | 3 +-- src/KOKKOS/bond_harmonic_kokkos.cpp | 3 +-- src/MOLECULE/bond_fene.cpp | 3 +-- src/MOLECULE/bond_fene_expand.cpp | 3 +-- src/MOLECULE/bond_gromos.cpp | 3 +-- src/MOLECULE/bond_harmonic.cpp | 3 +-- src/MOLECULE/bond_morse.cpp | 3 +-- src/MOLECULE/bond_nonlinear.cpp | 3 +-- src/MOLECULE/bond_quartic.cpp | 3 +-- src/MOLECULE/bond_table.cpp | 3 +-- src/USER-CGDNA/bond_oxdna_fene.cpp | 3 +-- src/USER-INTEL/bond_fene_intel.cpp | 3 +-- src/USER-INTEL/bond_harmonic_intel.cpp | 3 +-- src/USER-MISC/bond_harmonic_shift.cpp | 3 +-- src/USER-MISC/bond_harmonic_shift_cut.cpp | 3 +-- src/USER-OMP/bond_class2_omp.cpp | 5 +---- src/USER-OMP/bond_fene_expand_omp.cpp | 5 +---- src/USER-OMP/bond_fene_omp.cpp | 5 +---- src/USER-OMP/bond_gromos_omp.cpp | 5 +---- src/USER-OMP/bond_harmonic_omp.cpp | 5 +---- src/USER-OMP/bond_harmonic_shift_cut_omp.cpp | 5 +---- src/USER-OMP/bond_harmonic_shift_omp.cpp | 5 +---- src/USER-OMP/bond_morse_omp.cpp | 5 +---- src/USER-OMP/bond_nonlinear_omp.cpp | 5 +---- src/USER-OMP/bond_quartic_omp.cpp | 5 +---- src/USER-OMP/bond_table_omp.cpp | 5 +---- src/USER-YAFF/bond_mm3.cpp | 3 +-- src/bond.h | 4 ++++ src/bond_hybrid.cpp | 3 +-- src/bond_zero.cpp | 3 +-- 32 files changed, 35 insertions(+), 84 deletions(-) diff --git a/src/CLASS2/bond_class2.cpp b/src/CLASS2/bond_class2.cpp index af20313e0a..26c4e63a4d 100644 --- a/src/CLASS2/bond_class2.cpp +++ b/src/CLASS2/bond_class2.cpp @@ -56,8 +56,7 @@ void BondClass2::compute(int eflag, int vflag) double rsq,r,dr,dr2,dr3,dr4,de_bond; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/KOKKOS/bond_class2_kokkos.cpp b/src/KOKKOS/bond_class2_kokkos.cpp index d84b3d390c..798fb41c92 100644 --- a/src/KOKKOS/bond_class2_kokkos.cpp +++ b/src/KOKKOS/bond_class2_kokkos.cpp @@ -60,8 +60,7 @@ void BondClass2Kokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/bond_fene_kokkos.cpp b/src/KOKKOS/bond_fene_kokkos.cpp index d37943ba82..b5cdc1a05a 100644 --- a/src/KOKKOS/bond_fene_kokkos.cpp +++ b/src/KOKKOS/bond_fene_kokkos.cpp @@ -69,8 +69,7 @@ void BondFENEKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/KOKKOS/bond_harmonic_kokkos.cpp b/src/KOKKOS/bond_harmonic_kokkos.cpp index 6cdd4fe856..51a9fa4389 100644 --- a/src/KOKKOS/bond_harmonic_kokkos.cpp +++ b/src/KOKKOS/bond_harmonic_kokkos.cpp @@ -61,8 +61,7 @@ void BondHarmonicKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = 0; + ev_init(eflag,vflag,0); // reallocate per-atom arrays if necessary diff --git a/src/MOLECULE/bond_fene.cpp b/src/MOLECULE/bond_fene.cpp index 671290b0ad..c023a7e81e 100644 --- a/src/MOLECULE/bond_fene.cpp +++ b/src/MOLECULE/bond_fene.cpp @@ -54,8 +54,7 @@ void BondFENE::compute(int eflag, int vflag) double rsq,r0sq,rlogarg,sr2,sr6; ebond = sr6 = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/bond_fene_expand.cpp b/src/MOLECULE/bond_fene_expand.cpp index 3e191683fb..b1bfdc6a1b 100644 --- a/src/MOLECULE/bond_fene_expand.cpp +++ b/src/MOLECULE/bond_fene_expand.cpp @@ -56,8 +56,7 @@ void BondFENEExpand::compute(int eflag, int vflag) double r,rshift,rshiftsq; ebond = sr6 = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/bond_gromos.cpp b/src/MOLECULE/bond_gromos.cpp index 57091903af..f65adeb2cb 100644 --- a/src/MOLECULE/bond_gromos.cpp +++ b/src/MOLECULE/bond_gromos.cpp @@ -55,8 +55,7 @@ void BondGromos::compute(int eflag, int vflag) double delx,dely,delz,ebond,fbond; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/bond_harmonic.cpp b/src/MOLECULE/bond_harmonic.cpp index fb4581d0d6..cb8434ce6e 100644 --- a/src/MOLECULE/bond_harmonic.cpp +++ b/src/MOLECULE/bond_harmonic.cpp @@ -52,8 +52,7 @@ void BondHarmonic::compute(int eflag, int vflag) double rsq,r,dr,rk; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/bond_morse.cpp b/src/MOLECULE/bond_morse.cpp index 06af28f2b0..91dd2dbc49 100644 --- a/src/MOLECULE/bond_morse.cpp +++ b/src/MOLECULE/bond_morse.cpp @@ -53,8 +53,7 @@ void BondMorse::compute(int eflag, int vflag) double rsq,r,dr,ralpha; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/bond_nonlinear.cpp b/src/MOLECULE/bond_nonlinear.cpp index 645b081779..9999ead47f 100644 --- a/src/MOLECULE/bond_nonlinear.cpp +++ b/src/MOLECULE/bond_nonlinear.cpp @@ -49,8 +49,7 @@ void BondNonlinear::compute(int eflag, int vflag) double rsq,r,dr,drsq,lamdasq,denom,denomsq; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/MOLECULE/bond_quartic.cpp b/src/MOLECULE/bond_quartic.cpp index f200030d6c..895202ff00 100644 --- a/src/MOLECULE/bond_quartic.cpp +++ b/src/MOLECULE/bond_quartic.cpp @@ -60,8 +60,7 @@ void BondQuartic::compute(int eflag, int vflag) double r,rsq,dr,r2,ra,rb,sr2,sr6; ebond = evdwl = sr6 = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/MOLECULE/bond_table.cpp b/src/MOLECULE/bond_table.cpp index c75779922a..94e843eb65 100644 --- a/src/MOLECULE/bond_table.cpp +++ b/src/MOLECULE/bond_table.cpp @@ -68,8 +68,7 @@ void BondTable::compute(int eflag, int vflag) double u,mdu; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-CGDNA/bond_oxdna_fene.cpp b/src/USER-CGDNA/bond_oxdna_fene.cpp index 34a25a9b5a..8271668e3f 100644 --- a/src/USER-CGDNA/bond_oxdna_fene.cpp +++ b/src/USER-CGDNA/bond_oxdna_fene.cpp @@ -96,8 +96,7 @@ void BondOxdnaFene::compute(int eflag, int vflag) int newton_bond = force->newton_bond; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); // loop over FENE bonds diff --git a/src/USER-INTEL/bond_fene_intel.cpp b/src/USER-INTEL/bond_fene_intel.cpp index bff3722a44..bd8bc94c18 100644 --- a/src/USER-INTEL/bond_fene_intel.cpp +++ b/src/USER-INTEL/bond_fene_intel.cpp @@ -74,8 +74,7 @@ void BondFENEIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-INTEL/bond_harmonic_intel.cpp b/src/USER-INTEL/bond_harmonic_intel.cpp index 65894efa05..4424b868eb 100644 --- a/src/USER-INTEL/bond_harmonic_intel.cpp +++ b/src/USER-INTEL/bond_harmonic_intel.cpp @@ -74,8 +74,7 @@ void BondHarmonicIntel::compute(int eflag, int vflag, IntelBuffers *buffers, const ForceConst &fc) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); if (evflag) { if (vflag && !eflag) { diff --git a/src/USER-MISC/bond_harmonic_shift.cpp b/src/USER-MISC/bond_harmonic_shift.cpp index b34f71e888..c7e4444cce 100644 --- a/src/USER-MISC/bond_harmonic_shift.cpp +++ b/src/USER-MISC/bond_harmonic_shift.cpp @@ -53,8 +53,7 @@ void BondHarmonicShift::compute(int eflag, int vflag) double rsq,r,dr,rk; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-MISC/bond_harmonic_shift_cut.cpp b/src/USER-MISC/bond_harmonic_shift_cut.cpp index a58df70878..5b396f5d72 100644 --- a/src/USER-MISC/bond_harmonic_shift_cut.cpp +++ b/src/USER-MISC/bond_harmonic_shift_cut.cpp @@ -53,8 +53,7 @@ void BondHarmonicShiftCut::compute(int eflag, int vflag) double rsq,r,dr,rk; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/USER-OMP/bond_class2_omp.cpp b/src/USER-OMP/bond_class2_omp.cpp index 1f9bcaa320..fdd73c20b0 100644 --- a/src/USER-OMP/bond_class2_omp.cpp +++ b/src/USER-OMP/bond_class2_omp.cpp @@ -40,10 +40,7 @@ BondClass2OMP::BondClass2OMP(class LAMMPS *lmp) void BondClass2OMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_fene_expand_omp.cpp b/src/USER-OMP/bond_fene_expand_omp.cpp index d002d454dd..a8eec11760 100644 --- a/src/USER-OMP/bond_fene_expand_omp.cpp +++ b/src/USER-OMP/bond_fene_expand_omp.cpp @@ -41,10 +41,7 @@ BondFENEExpandOMP::BondFENEExpandOMP(class LAMMPS *lmp) void BondFENEExpandOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_fene_omp.cpp b/src/USER-OMP/bond_fene_omp.cpp index ba958e1d6f..be7dcd4b49 100644 --- a/src/USER-OMP/bond_fene_omp.cpp +++ b/src/USER-OMP/bond_fene_omp.cpp @@ -41,10 +41,7 @@ BondFENEOMP::BondFENEOMP(class LAMMPS *lmp) void BondFENEOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_gromos_omp.cpp b/src/USER-OMP/bond_gromos_omp.cpp index bcfde436d5..8f0926c0e9 100644 --- a/src/USER-OMP/bond_gromos_omp.cpp +++ b/src/USER-OMP/bond_gromos_omp.cpp @@ -39,10 +39,7 @@ BondGromosOMP::BondGromosOMP(class LAMMPS *lmp) void BondGromosOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_harmonic_omp.cpp b/src/USER-OMP/bond_harmonic_omp.cpp index 46a93cbbdd..a3bb69c53c 100644 --- a/src/USER-OMP/bond_harmonic_omp.cpp +++ b/src/USER-OMP/bond_harmonic_omp.cpp @@ -39,10 +39,7 @@ BondHarmonicOMP::BondHarmonicOMP(class LAMMPS *lmp) void BondHarmonicOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp b/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp index 5f39bb1b64..5c16e27a32 100644 --- a/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp +++ b/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp @@ -39,10 +39,7 @@ BondHarmonicShiftCutOMP::BondHarmonicShiftCutOMP(class LAMMPS *lmp) void BondHarmonicShiftCutOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_harmonic_shift_omp.cpp b/src/USER-OMP/bond_harmonic_shift_omp.cpp index 8c260bfc9b..39e957c137 100644 --- a/src/USER-OMP/bond_harmonic_shift_omp.cpp +++ b/src/USER-OMP/bond_harmonic_shift_omp.cpp @@ -39,10 +39,7 @@ BondHarmonicShiftOMP::BondHarmonicShiftOMP(class LAMMPS *lmp) void BondHarmonicShiftOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_morse_omp.cpp b/src/USER-OMP/bond_morse_omp.cpp index 0c3cded71a..c0203de0d6 100644 --- a/src/USER-OMP/bond_morse_omp.cpp +++ b/src/USER-OMP/bond_morse_omp.cpp @@ -39,10 +39,7 @@ BondMorseOMP::BondMorseOMP(class LAMMPS *lmp) void BondMorseOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_nonlinear_omp.cpp b/src/USER-OMP/bond_nonlinear_omp.cpp index cdc70eac8d..8fa3daf8ab 100644 --- a/src/USER-OMP/bond_nonlinear_omp.cpp +++ b/src/USER-OMP/bond_nonlinear_omp.cpp @@ -39,10 +39,7 @@ BondNonlinearOMP::BondNonlinearOMP(class LAMMPS *lmp) void BondNonlinearOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-OMP/bond_quartic_omp.cpp b/src/USER-OMP/bond_quartic_omp.cpp index b2b1696bb4..fd0ccaf79d 100644 --- a/src/USER-OMP/bond_quartic_omp.cpp +++ b/src/USER-OMP/bond_quartic_omp.cpp @@ -40,10 +40,7 @@ BondQuarticOMP::BondQuarticOMP(class LAMMPS *lmp) void BondQuarticOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); // insure pair->ev_tally() will use 1-4 virial contribution diff --git a/src/USER-OMP/bond_table_omp.cpp b/src/USER-OMP/bond_table_omp.cpp index 71dc237496..1616988385 100644 --- a/src/USER-OMP/bond_table_omp.cpp +++ b/src/USER-OMP/bond_table_omp.cpp @@ -39,10 +39,7 @@ BondTableOMP::BondTableOMP(class LAMMPS *lmp) void BondTableOMP::compute(int eflag, int vflag) { - - if (eflag || vflag) { - ev_setup(eflag,vflag); - } else evflag = 0; + ev_init(eflag,vflag); const int nall = atom->nlocal + atom->nghost; const int nthreads = comm->nthreads; diff --git a/src/USER-YAFF/bond_mm3.cpp b/src/USER-YAFF/bond_mm3.cpp index 1c464ff895..ee1ebcdd61 100644 --- a/src/USER-YAFF/bond_mm3.cpp +++ b/src/USER-YAFF/bond_mm3.cpp @@ -54,8 +54,7 @@ void BondMM3::compute(int eflag, int vflag) double rsq,r,dr,dr2,de_bond,K3,K4; ebond = 0.0; - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); double **x = atom->x; double **f = atom->f; diff --git a/src/bond.h b/src/bond.h index 9c353a1a6d..1082748403 100644 --- a/src/bond.h +++ b/src/bond.h @@ -65,6 +65,10 @@ class Bond : protected Pointers { int maxeatom,maxvatom; void ev_setup(int, int, int alloc = 1); + void ev_init(int eflag, int vflag, int alloc = 1) { + if (eflag||vflag) ev_setup(eflag, vflag, alloc); + else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; + } void ev_tally(int, int, int, int, double, double, double, double, double); }; diff --git a/src/bond_hybrid.cpp b/src/bond_hybrid.cpp index 4e5a26f731..65609b4b6e 100644 --- a/src/bond_hybrid.cpp +++ b/src/bond_hybrid.cpp @@ -103,8 +103,7 @@ void BondHybrid::compute(int eflag, int vflag) // set neighbor->bondlist to sub-style bondlist before call // accumulate sub-style global/peratom energy/virial in hybrid - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); for (m = 0; m < nstyles; m++) { neighbor->nbondlist = nbondlist[m]; diff --git a/src/bond_zero.cpp b/src/bond_zero.cpp index 9fcf300b21..0847cf9e6b 100644 --- a/src/bond_zero.cpp +++ b/src/bond_zero.cpp @@ -45,8 +45,7 @@ BondZero::~BondZero() void BondZero::compute(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = 0; + ev_init(eflag,vflag); } /* ---------------------------------------------------------------------- */ -- GitLab From 985fc86aa3f8e907c8dae04321db2b6464c007eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=BCtter?= Date: Wed, 13 Mar 2019 17:55:30 +0100 Subject: [PATCH 0238/1243] use ev_init for kspace --- src/GPU/pppm_gpu.cpp | 4 +--- src/KOKKOS/pppm_kokkos.cpp | 3 +-- src/KSPACE/ewald.cpp | 4 +--- src/KSPACE/ewald_disp.cpp | 3 +-- src/KSPACE/msm.cpp | 4 +--- src/KSPACE/msm_cg.cpp | 4 +--- src/KSPACE/pppm.cpp | 4 +--- src/KSPACE/pppm_cg.cpp | 4 +--- src/KSPACE/pppm_disp.cpp | 4 +--- src/KSPACE/pppm_stagger.cpp | 4 +--- src/USER-INTEL/pppm_disp_intel.cpp | 4 +--- src/USER-INTEL/pppm_intel.cpp | 4 +--- src/USER-OMP/ewald_omp.cpp | 4 +--- src/USER-OMP/msm_cg_omp.cpp | 4 +--- src/USER-SCAFACOS/scafacos.cpp | 7 +------ src/kspace.cpp | 4 +--- src/kspace.h | 4 ++++ 17 files changed, 20 insertions(+), 49 deletions(-) diff --git a/src/GPU/pppm_gpu.cpp b/src/GPU/pppm_gpu.cpp index 4b460b1280..1bb1a39703 100644 --- a/src/GPU/pppm_gpu.cpp +++ b/src/GPU/pppm_gpu.cpp @@ -199,9 +199,7 @@ void PPPMGPU::compute(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); // If need per-atom energies/virials, allocate per-atom arrays here // so that particle map on host can be done concurrently with GPU calculations diff --git a/src/KOKKOS/pppm_kokkos.cpp b/src/KOKKOS/pppm_kokkos.cpp index bcac29ba9b..c233ca6264 100644 --- a/src/KOKKOS/pppm_kokkos.cpp +++ b/src/KOKKOS/pppm_kokkos.cpp @@ -615,8 +615,7 @@ void PPPMKokkos::compute(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag,0); - else evflag = evflag_atom = eflag_global = vflag_global = + ev_init(eflag,vflag,0); eflag_atom = vflag_atom = 0; // reallocate per-atom arrays if necessary diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp index 283c672bad..ccbb3ed708 100644 --- a/src/KSPACE/ewald.cpp +++ b/src/KSPACE/ewald.cpp @@ -365,9 +365,7 @@ void Ewald::compute(int eflag, int vflag) // set energy/virial flags - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); // if atom count has changed, update qsum and qsqsum diff --git a/src/KSPACE/ewald_disp.cpp b/src/KSPACE/ewald_disp.cpp index 4cbdf7b9cb..0603d68eb2 100644 --- a/src/KSPACE/ewald_disp.cpp +++ b/src/KSPACE/ewald_disp.cpp @@ -688,8 +688,7 @@ void EwaldDisp::compute(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = eflag_global = vflag_global = eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (!peratom_allocate_flag && (eflag_atom || vflag_atom)) { allocate_peratom(); diff --git a/src/KSPACE/msm.cpp b/src/KSPACE/msm.cpp index d8964ffa67..d7cc3f6876 100644 --- a/src/KSPACE/msm.cpp +++ b/src/KSPACE/msm.cpp @@ -454,9 +454,7 @@ void MSM::compute(int eflag, int vflag) // set energy/virial flags - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = eflag_either = vflag_either = 0; + ev_init(eflag,vflag); if (scalar_pressure_flag && vflag_either) { if (vflag_atom) diff --git a/src/KSPACE/msm_cg.cpp b/src/KSPACE/msm_cg.cpp index 55435e5a6e..c7896db50c 100644 --- a/src/KSPACE/msm_cg.cpp +++ b/src/KSPACE/msm_cg.cpp @@ -90,9 +90,7 @@ void MSMCG::compute(int eflag, int vflag) // set energy/virial flags - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = eflag_either = vflag_either = 0; + ev_init(eflag,vflag); // invoke allocate_peratom() if needed for first time diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp index 8fd74d00dc..773305bb5e 100644 --- a/src/KSPACE/pppm.cpp +++ b/src/KSPACE/pppm.cpp @@ -630,9 +630,7 @@ void PPPM::compute(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); diff --git a/src/KSPACE/pppm_cg.cpp b/src/KSPACE/pppm_cg.cpp index fa73588363..3285dba21c 100644 --- a/src/KSPACE/pppm_cg.cpp +++ b/src/KSPACE/pppm_cg.cpp @@ -88,9 +88,7 @@ void PPPMCG::compute(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); diff --git a/src/KSPACE/pppm_disp.cpp b/src/KSPACE/pppm_disp.cpp index 687ea0b3f9..45dce0895b 100644 --- a/src/KSPACE/pppm_disp.cpp +++ b/src/KSPACE/pppm_disp.cpp @@ -928,9 +928,7 @@ void PPPMDisp::compute(int eflag, int vflag) int i; // convert atoms from box to lamda coords - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); diff --git a/src/KSPACE/pppm_stagger.cpp b/src/KSPACE/pppm_stagger.cpp index ca369cf260..a5ed6de626 100644 --- a/src/KSPACE/pppm_stagger.cpp +++ b/src/KSPACE/pppm_stagger.cpp @@ -124,9 +124,7 @@ void PPPMStagger::compute(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); diff --git a/src/USER-INTEL/pppm_disp_intel.cpp b/src/USER-INTEL/pppm_disp_intel.cpp index 795fe1a47d..9d075c78a1 100644 --- a/src/USER-INTEL/pppm_disp_intel.cpp +++ b/src/USER-INTEL/pppm_disp_intel.cpp @@ -174,9 +174,7 @@ void PPPMDispIntel::compute(int eflag, int vflag) int i; // convert atoms from box to lamda coords - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); diff --git a/src/USER-INTEL/pppm_intel.cpp b/src/USER-INTEL/pppm_intel.cpp index 59455bcf52..e3d1e7d4aa 100644 --- a/src/USER-INTEL/pppm_intel.cpp +++ b/src/USER-INTEL/pppm_intel.cpp @@ -161,9 +161,7 @@ void PPPMIntel::compute_first(int eflag, int vflag) // set energy/virial flags // invoke allocate_peratom() if needed for first time - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); if (evflag_atom && !peratom_allocate_flag) { allocate_peratom(); diff --git a/src/USER-OMP/ewald_omp.cpp b/src/USER-OMP/ewald_omp.cpp index 1fece5c31b..b56fc25142 100644 --- a/src/USER-OMP/ewald_omp.cpp +++ b/src/USER-OMP/ewald_omp.cpp @@ -61,9 +61,7 @@ void EwaldOMP::compute(int eflag, int vflag) { // set energy/virial flags - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); // extend size of per-atom arrays if necessary diff --git a/src/USER-OMP/msm_cg_omp.cpp b/src/USER-OMP/msm_cg_omp.cpp index dee9fd85b6..8a920e05d5 100644 --- a/src/USER-OMP/msm_cg_omp.cpp +++ b/src/USER-OMP/msm_cg_omp.cpp @@ -90,9 +90,7 @@ void MSMCGOMP::compute(int eflag, int vflag) // set energy/virial flags - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = eflag_either = vflag_either = 0; + ev_init(eflag,vflag); // invoke allocate_peratom() if needed for first time diff --git a/src/USER-SCAFACOS/scafacos.cpp b/src/USER-SCAFACOS/scafacos.cpp index 4b8e10123c..497442fbe8 100644 --- a/src/USER-SCAFACOS/scafacos.cpp +++ b/src/USER-SCAFACOS/scafacos.cpp @@ -197,12 +197,7 @@ void Scafacos::compute(int eflag, int vflag) fcs_set_redistribute((FCS)fcs,0); } - if (eflag || vflag) ev_setup(eflag,vflag); - else - { - eflag_atom = 0; - vflag_global = 0; - } + ev_init(eflag,vflag); // grow xpbc, epot, efield if necessary diff --git a/src/kspace.cpp b/src/kspace.cpp index 25491cd964..0144ea59a3 100644 --- a/src/kspace.cpp +++ b/src/kspace.cpp @@ -168,9 +168,7 @@ void KSpace::triclinic_check() void KSpace::compute_dummy(int eflag, int vflag) { - if (eflag || vflag) ev_setup(eflag,vflag); - else evflag = evflag_atom = eflag_global = vflag_global = - eflag_atom = vflag_atom = 0; + ev_init(eflag,vflag); } /* ---------------------------------------------------------------------- diff --git a/src/kspace.h b/src/kspace.h index f29659d0e8..12cb16c929 100644 --- a/src/kspace.h +++ b/src/kspace.h @@ -195,6 +195,10 @@ class KSpace : protected Pointers { void pair_check(); void ev_setup(int, int, int alloc = 1); + void ev_init(int eflag, int vflag, int alloc = 1) { + if (eflag||vflag) ev_setup(eflag, vflag, alloc); + else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; + } double estimate_table_accuracy(double, double); }; -- GitLab From 8c50c3d7c87be57f356b9ad454fbe66799c3c7ef Mon Sep 17 00:00:00 2001 From: julient31 Date: Wed, 13 Mar 2019 17:02:40 -0600 Subject: [PATCH 0239/1243] Commit JT 031319 - improved gneb functions - correct name in fix_neb (Weinan) --- doc/src/fix_neb.txt | 6 +- doc/src/min_modify.txt | 1 + src/REPLICA/fix_neb_spin.cpp | 72 ++---- src/REPLICA/neb_spin.cpp | 417 ++++++----------------------------- src/REPLICA/neb_spin.h | 6 +- 5 files changed, 82 insertions(+), 420 deletions(-) diff --git a/doc/src/fix_neb.txt b/doc/src/fix_neb.txt index 410ab3d4d1..87292bb5cd 100644 --- a/doc/src/fix_neb.txt +++ b/doc/src/fix_neb.txt @@ -97,7 +97,7 @@ Note that in this case the specified {Kspring} is in force/distance units. With a value of {ideal}, the spring force is computed as suggested in -"(WeinenE)"_#WeinenE : +"(WeinanE)"_#WeinanE : Fnudge_parallel = -{Kspring} * (RD-RDideal) / (2 * meanDist) :pre @@ -224,8 +224,8 @@ specified (no inter-replica force on the end replicas). [(Henkelman2)] Henkelman, Uberuaga, Jonsson, J Chem Phys, 113, 9901-9904 (2000). -:link(WeinenE) -[(WeinenE)] E, Ren, Vanden-Eijnden, Phys Rev B, 66, 052301 (2002). +:link(WeinanE) +[(WeinanE)] E, Ren, Vanden-Eijnden, Phys Rev B, 66, 052301 (2002). :link(Jonsson) [(Jonsson)] Jonsson, Mills and Jacobsen, in Classical and Quantum diff --git a/doc/src/min_modify.txt b/doc/src/min_modify.txt index bb5ad513c1..701f579af4 100644 --- a/doc/src/min_modify.txt +++ b/doc/src/min_modify.txt @@ -71,6 +71,7 @@ could move in the gradient direction to reduce forces further. Keywords {alpha_damp} and {discret_factor} only make sense when a {spinmin} minimization style is declared. +Default values are alpha_damp = 1.0 and discret_factor = 10.0. [Restrictions:] none diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index d8f9e655fd..015ff1a313 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -69,65 +69,25 @@ FixNEB_spin::FixNEB_spin(LAMMPS *lmp, int narg, char **arg) : kspringPerp = 0.0; kspringIni = 1.0; kspringFinal = 1.0; - // only regular neb for now - SpinLattice = false; - + SpinLattice = false; // no spin-lattice neb for now + // no available fix neb/spin options for now int iarg = 4; while (iarg < narg) { - if (strcmp(arg[iarg],"lattice") == 0) - error->all(FLERR,"Illegal fix neb command"); - } - - /* if (strcmp(arg[iarg],"parallel") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix neb command"); - if (strcmp(arg[iarg+1],"ideal") == 0) { - NEBLongRange = true; - StandardNEB = false; - } else if (strcmp(arg[iarg+1],"neigh") == 0) { - NEBLongRange = false; - StandardNEB = true; - } else error->all(FLERR,"Illegal fix neb command"); + error->all(FLERR,"Illegal fix neb command"); iarg += 2; - } else if (strcmp(arg[iarg],"perp") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal fix neb command"); - PerpSpring = true; - kspringPerp = force->numeric(FLERR,arg[iarg+1]); - if (kspringPerp == 0.0) PerpSpring = false; - if (kspringPerp < 0.0) error->all(FLERR,"Illegal fix neb command"); + error->all(FLERR,"Illegal fix neb command"); iarg += 2; - } else if (strcmp (arg[iarg],"end") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal fix neb command"); - if (strcmp(arg[iarg+1],"first") == 0) { - FreeEndIni = true; - kspringIni = force->numeric(FLERR,arg[iarg+2]); - } else if (strcmp(arg[iarg+1],"last") == 0) { - FreeEndFinal = true; - FinalAndInterWithRespToEIni = false; - FreeEndFinalWithRespToEIni = false; - kspringFinal = force->numeric(FLERR,arg[iarg+2]); - } else if (strcmp(arg[iarg+1],"last/efirst") == 0) { - FreeEndFinal = false; - FinalAndInterWithRespToEIni = false; - FreeEndFinalWithRespToEIni = true; - kspringFinal = force->numeric(FLERR,arg[iarg+2]); - } else if (strcmp(arg[iarg+1],"last/efirst/middle") == 0) { - FreeEndFinal = false; - FinalAndInterWithRespToEIni = true; - FreeEndFinalWithRespToEIni = true; - kspringFinal = force->numeric(FLERR,arg[iarg+2]); - } else error->all(FLERR,"Illegal fix neb command"); - iarg += 3; - + } else if (strcmp (arg[iarg],"lattice") == 0) { + iarg += 2; } else error->all(FLERR,"Illegal fix neb command"); } - */ - + // nreplica = number of partitions // ireplica = which world I am in universe // nprocs_universe = # of procs in all replicase @@ -172,10 +132,6 @@ FixNEB_spin::FixNEB_spin(LAMMPS *lmp, int narg, char **arg) : modify->add_compute(3,newarg); delete [] newarg; - // might need a test - // => check if pe does not compute mech potentials - - // initialize local storage maxlocal = -1; @@ -374,14 +330,12 @@ void FixNEB_spin::min_post_force(int /*vflag*/) pe->addstep(update->ntimestep+1); double **x = atom->x; - // spin quantities double **sp = atom->sp; int *mask = atom->mask; double dot = 0.0; double prefactor = 0.0; - double **f = atom->f; - // spin quantities + //double **f = atom->f; double **fm = atom->fm; int nlocal = atom->nlocal; @@ -397,9 +351,10 @@ void FixNEB_spin::min_post_force(int /*vflag*/) // computation of the tangent vector - // final replica if (ireplica == nreplica-1) { + // final replica + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { @@ -470,8 +425,10 @@ void FixNEB_spin::min_post_force(int /*vflag*/) //} } - // initial replica } else if (ireplica == 0) { + + // initial replica + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { @@ -537,7 +494,6 @@ void FixNEB_spin::min_post_force(int /*vflag*/) //} } - // in-between replica } else { // not the first or last replica @@ -770,7 +726,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) //prefactor = -2.0*dot; } else { if (NEBLongRange) { - error->all(FLERR,"NEB_spin climber option not yet active"); + error->all(FLERR,"Long Range NEB_spin climber option not yet active"); //prefactor = -dot - kspring*(lenuntilIm-idealPos)/(2*meanDist); } else if (StandardNEB) { prefactor = -dot + kspring*(nlen-plen); diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index 6249797e95..e82b08e354 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -72,7 +72,8 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, double delspx,delspy,delspz; etol = etol_in; - ftol = ftol_in; + //ftol = ftol_in; + ttol = ftol_in; n1steps = n1steps_in; n2steps = n2steps_in; nevery = nevery_in; @@ -85,12 +86,10 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, uworld = universe->uworld; MPI_Comm_rank(world,&me); - // generate linear interpolate replica + // fraction to interpolate intermediate replica double fraction = ireplica/(nreplica-1.0); - double **x = atom->x; - // spin quantitites double **sp = atom->sp; int nlocal = atom->nlocal; @@ -111,19 +110,11 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, sp[i][1] = spfinal[1]; sp[i][2] = spfinal[2]; - //delx = buf_final[ii] - buf_init[ii]; - //dely = buf_final[ii+1] - buf_init[ii+1]; - //delz = buf_final[ii+2] - buf_init[ii+2]; - // adjust distance if pbc - // not implemented yet //domain->minimum_image(delx,dely,delz); - // need to define a procedure for circular initialization - - //x[i][0] = buf_init[ii] + fraction*delx; - //x[i][1] = buf_init[ii+1] + fraction*dely; - //x[i][2] = buf_init[ii+2] + fraction*delz; + // need to define a better procedure for circular initialization + ii += 3; } } @@ -143,22 +134,14 @@ NEB_spin::~NEB_spin() void NEB_spin::command(int narg, char **arg) { - - //printf("test 1 \n"); - - // test 1 - double **sp1 = atom->sp; - //printf("test 1 atom: i=%d,%g,%g,%g \n",1,sp1[1][0],sp1[1][1],sp1[1][2]); - //error->all(FLERR,"end neb_spin test"); - - if (domain->box_exist == 0) error->all(FLERR,"NEB_spin command before simulation box is defined"); if (narg < 6) error->universe_all(FLERR,"Illegal NEB_spin command"); etol = force->numeric(FLERR,arg[0]); - ftol = force->numeric(FLERR,arg[1]); + //ftol = force->numeric(FLERR,arg[1]); + ttol = force->numeric(FLERR,arg[1]); n1steps = force->inumeric(FLERR,arg[2]); n2steps = force->inumeric(FLERR,arg[3]); nevery = force->inumeric(FLERR,arg[4]); @@ -166,7 +149,8 @@ void NEB_spin::command(int narg, char **arg) // error checks if (etol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); - if (ftol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); + //if (ftol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); + if (ttol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); if (nevery <= 0) error->universe_all(FLERR,"Illegal NEB_spin command"); if (n1steps % nevery || n2steps % nevery) error->universe_all(FLERR,"Illegal NEB_spin command"); @@ -209,14 +193,6 @@ void NEB_spin::command(int narg, char **arg) verbose=false; if (strcmp(arg[narg-1],"verbose") == 0) verbose=true; - - - // test 1 - double **sp = atom->sp; - //printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); - //error->all(FLERR,"end neb_spin test"); - - // run the NEB_spin calculation run(); } @@ -250,22 +226,24 @@ void NEB_spin::run() update->whichflag = 2; update->etol = etol; - update->ftol = ftol; + //update->ftol = ftol; + update->ftol = ttol; // update->ftol is a torque tolerance update->multireplica = 1; lmp->init(); - // put flag to check gilbert damping procedure is set + // check if correct minimizer is setup - //if (update->minimize->searchflag) - // error->all(FLERR,"NEB_spin requires damped dynamics minimizer"); + if (update->minimize->searchflag) + error->all(FLERR,"NEB_spin requires damped dynamics minimizer"); + if (strcmp(update->minimize_style,"spinmin") != 0) + error->all(FLERR,"NEB_spin requires spinmin minimizer"); // setup regular NEB_spin minimization + FILE *uscreen = universe->uscreen; FILE *ulogfile = universe->ulogfile; - //printf("test before run 1 \n"); - if (me_universe == 0 && uscreen) fprintf(uscreen,"Setting up regular NEB_spin ...\n"); @@ -276,22 +254,23 @@ void NEB_spin::run() if (update->laststep < 0) error->all(FLERR,"Too many timesteps for NEB_spin"); - //printf("test before run 2 \n"); - update->minimize->setup(); - //printf("test before run 3 \n"); - if (me_universe == 0) { if (uscreen) { if (verbose) { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - "... ReplicaForceN MaxAtomForceN\n"); + "... ReplicaTorqueN MaxAtomTorqueN\n"); + //fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + // "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " + // "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " + // "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " + // "... ReplicaForceN MaxAtomForceN\n"); } else { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " "RDN PEN\n"); } @@ -299,21 +278,19 @@ void NEB_spin::run() if (ulogfile) { if (verbose) { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - "... ReplicaForceN MaxAtomForceN\n"); + "... ReplicaTorqueN MaxAtomTorqueN\n"); } else { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " "RDN PEN\n"); } } } - //printf("test before run 4 \n"); print_status(); - //printf("test before run 5 \n"); // perform regular NEB_spin for n1steps or until replicas converge // retrieve PE values from fix NEB_spin and print every nevery iterations @@ -323,35 +300,11 @@ void NEB_spin::run() timer->init(); timer->barrier_start(); - // test import fix_nve scheme - - //printf("test 2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); - //error->all(FLERR,"end neb_spin test"); - double dts; while (update->minimize->niter < n1steps) { - //dts = evaluate_dt(); - //advance_spins(dts); - //fneb-> - - //dts = fneb->evaluate_dt(); - //fneb->advance_spins(dts); - - // no minimizer for spins update->minimize->run(nevery); - - - // no minimizer for spins - //update->minimize->run(nevery); - // - // evaluate dts - // loop on spins, damped advance - // print_status(); if (update->minimize->stop_condition) break; } - - // test neb end - //error->all(FLERR,"end neb_spin test"); timer->barrier_stop(); @@ -393,22 +346,19 @@ void NEB_spin::run() update->minimize->init(); fneb->rclimber = top; - printf("test print 6.2 \n"); update->minimize->setup(); - printf("test print 6.3 \n"); - if (me_universe == 0) { if (uscreen) { if (verbose) { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT " "RD1 PE1 RD2 PE2 ... RDN PEN " "pathangle1 angletangrad1 anglegrad1 gradV1 " "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " "... ReplicaForceN MaxAtomForceN\n"); } else { - fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " + fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc " "EBF EBR RDT " "RD1 PE1 RD2 PE2 ... RDN PEN\n"); @@ -416,14 +366,14 @@ void NEB_spin::run() } if (ulogfile) { if (verbose) { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT " "RD1 PE1 RD2 PE2 ... RDN PEN " "pathangle1 angletangrad1 anglegrad1 gradV1 " "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " "... ReplicaForceN MaxAtomForceN\n"); } else { - fprintf(ulogfile,"Step MaxReplicaForce MaxAtomForce " + fprintf(ulogfile,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc " "EBF EBR RDT " "RD1 PE1 RD2 PE2 ... RDN PEN\n"); @@ -441,10 +391,6 @@ void NEB_spin::run() timer->barrier_start(); while (update->minimize->niter < n2steps) { - //dts = evaluate_dt(); - //advance_spins(dts); - //dts = fneb->evaluate_dt(); - //fneb->advance_spins(dts); update->minimize->run(nevery); print_status(); if (update->minimize->stop_condition) break; @@ -462,174 +408,6 @@ void NEB_spin::run() update->beginstep = update->endstep = 0; } -/* ---------------------------------------------------------------------- - geodesic distance calculation (Vincenty's formula) -------------------------------------------------------------------------- */ - -//double NEB_spin::geodesic_distance2(double spi[3], double spj[3]) -//{ -// double dist; -// double crossx,crossy,crossz; -// double dotx,doty,dotz; -// double crosslen,dots; -// -// crossx = spi[1]*spj[2]-spi[2]*spj[1]; -// crossy = spi[2]*spj[0]-spi[0]*spj[2]; -// crossz = spi[0]*spj[1]-spi[1]*spj[0]; -// crosslen = sqrt(crossx*crossx + crossy*crossy + crossz*crossz); -// dotx = spi[0]*spj[0]; -// doty = spi[1]*spj[1]; -// dotz = spi[2]*spj[2]; -// dots = dotx+doty+dotz; -// -// dist = atan2(crosslen,dots); -// -// return dist; -//} - -/* ---------------------------------------------------------------------- - evaluate max timestep ----------------------------------------------------------------------- */ - -//double NEB_spin::evaluate_dt() -//{ -// double dtmax; -// double fmsq; -// double fmaxsqone,fmaxsqloc,fmaxsqall; -// int nlocal = atom->nlocal; -// int *mask = atom->mask; -// double **fm = atom->fm; -// -// // finding max fm on this proc. -// -// fmsq = fmaxsqone = fmaxsqloc = fmaxsqall = 0.0; -// for (int i = 0; i < nlocal; i++) -// if (mask[i] & groupbit) { -// fmsq = fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]; -// fmaxsqone = MAX(fmaxsqone,fmsq); -// } -// -// // finding max fm on this replica -// -// fmaxsqloc = fmaxsqone; -// MPI_Allreduce(&fmaxsqone,&fmaxsqloc,1,MPI_DOUBLE,MPI_MAX,world); -// -// // finding max fm over all replicas, if necessary -// // this communicator would be invalid for multiprocess replicas -// -// if (update->multireplica == 1) { -// fmaxsqall = fmaxsqloc; -// MPI_Allreduce(&fmaxsqloc,&fmaxsqall,1,MPI_DOUBLE,MPI_MAX,universe->uworld); -// } -// -// if (fmaxsqall < fmaxsqloc) -// error->all(FLERR,"Incorrect fmaxall calc."); -// -// // define max timestep -// // dividing by 10 the inverse of max frequency -// -// dtmax = MY_2PI/(10.0*sqrt(fmaxsqall)); -// -// return dtmax; -//} - -/* ---------------------------------------------------------------------- - geometric damped advance os spins ----------------------------------------------------------------------- */ - -//void NEB_spin::advance_spins(double dts) -//{ -// //int j=0; -// //int *sametag = atom->sametag; -// int nlocal = atom->nlocal; -// int *mask = atom->mask; -// double **sp = atom->sp; -// double **fm = atom->fm; -// double tdampx,tdampy,tdampz; -// double msq,scale,fm2,energy,dts2; -// double alpha; -// double spi[3],fmi[3]; -// double cp[3],g[3]; -// -// //cp[0] = cp[1] = cp[2] = 0.0; -// //g[0] = g[1] = g[2] = 0.0; -// dts2 = dts*dts; -// -// // fictitious Gilbert damping of 1 -// alpha = 1.0; -// -// // loop on all spins on proc. -// -// if (ireplica != nreplica-1 && ireplica != 0) -// for (int i = 0; i < nlocal; i++) -// if (mask[i] & groupbit) { -// -// spi[0] = sp[i][0]; -// spi[1] = sp[i][1]; -// spi[2] = sp[i][2]; -// -// fmi[0] = fm[i][0]; -// fmi[1] = fm[i][1]; -// fmi[2] = fm[i][2]; -// -// // calc. damping torque -// -// tdampx = -alpha*(fmi[1]*spi[2] - fmi[2]*spi[1]); -// tdampy = -alpha*(fmi[2]*spi[0] - fmi[0]*spi[2]); -// tdampz = -alpha*(fmi[0]*spi[1] - fmi[1]*spi[0]); -// -// // apply advance algorithm (geometric, norm preserving) -// -// fm2 = (tdampx*tdampx+tdampy*tdampy+tdampz*tdampz); -// energy = (sp[i][0]*tdampx)+(sp[i][1]*tdampy)+(sp[i][2]*tdampz); -// -// cp[0] = tdampy*sp[i][2]-tdampz*sp[i][1]; -// cp[1] = tdampz*sp[i][0]-tdampx*sp[i][2]; -// cp[2] = tdampx*sp[i][1]-tdampy*sp[i][0]; -// -// g[0] = sp[i][0]+cp[0]*dts; -// g[1] = sp[i][1]+cp[1]*dts; -// g[2] = sp[i][2]+cp[2]*dts; -// -// g[0] += (fm[i][0]*energy-0.5*sp[i][0]*fm2)*0.5*dts2; -// g[1] += (fm[i][1]*energy-0.5*sp[i][1]*fm2)*0.5*dts2; -// g[2] += (fm[i][2]*energy-0.5*sp[i][2]*fm2)*0.5*dts2; -// -// g[0] /= (1+0.25*fm2*dts2); -// g[1] /= (1+0.25*fm2*dts2); -// g[2] /= (1+0.25*fm2*dts2); -// -// sp[i][0] = g[0]; -// sp[i][1] = g[1]; -// sp[i][2] = g[2]; -// -// // renormalization (check if necessary) -// -// msq = g[0]*g[0] + g[1]*g[1] + g[2]*g[2]; -// scale = 1.0/sqrt(msq); -// sp[i][0] *= scale; -// sp[i][1] *= scale; -// sp[i][2] *= scale; -// -// // comm. sp[i] to atoms with same tag (for serial algo) -// -// // no need for simplecticity -// //if (sector_flag == 0) { -// // if (sametag[i] >= 0) { -// // j = sametag[i]; -// // while (j >= 0) { -// // sp[j][0] = sp[i][0]; -// // sp[j][1] = sp[i][1]; -// // sp[j][2] = sp[i][2]; -// // j = sametag[j]; -// // } -// // } -// //} -// // -// -// } -//} - /* ---------------------------------------------------------------------- read initial config atom coords from file flag = 0 @@ -654,7 +432,6 @@ void NEB_spin::readfile(char *file, int flag) double xx,yy,zz,delx,dely,delz; // spin quantities double musp,spx,spy,spz; - //,delx,dely,delz; if (me_universe == 0 && screen) fprintf(screen,"Reading NEB_spin coordinate file(s) ...\n"); @@ -703,12 +480,6 @@ void NEB_spin::readfile(char *file, int flag) double spinit[3],spfinal[3]; int nlocal = atom->nlocal; - // test 1.2 - //double **sp = atom->sp; - //printf("test 1.2 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); - //error->all(FLERR,"end neb_spin test"); - - // loop over chunks of lines read from file // two versions of read_lines_from_file() for world vs universe bcast // count # of atom coords changed so can check for invalid atom IDs in file @@ -765,44 +536,27 @@ void NEB_spin::readfile(char *file, int flag) spx = atof(values[5]); spy = atof(values[6]); spz = atof(values[7]); - //xx = atof(values[1]); - //yy = atof(values[2]); - //zz = atof(values[3]); if (flag == 0) { - // here, function interp. spin states - - //spinit[0] = x[m][0]; - //spinit[1] = x[m][1]; - //spinit[2] = x[m][2]; spinit[0] = sp[m][0]; spinit[1] = sp[m][1]; spinit[2] = sp[m][2]; spfinal[0] = spx; spfinal[1] = spy; spfinal[2] = spz; - //domain->minimum_image(delx,dely,delz); + + // to be used it atomic displacements with pbc + //domain->minimum_image(delx,dely,delz); - // test - //printf("spinit: %g %g %g \n",spinit[0],spinit[1],spinit[2]); - //printf("spfinal bef: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); + // interpolate intermediate spin states initial_rotation(spinit,spfinal,fraction); - - // test - //printf("spfinal aft: %g %g %g \n",spfinal[0],spfinal[1],spfinal[2]); sp[m][0] = spfinal[0]; sp[m][1] = spfinal[1]; sp[m][2] = spfinal[2]; sp[m][3] = musp; - //delx = xx - x[m][0]; - //dely = yy - x[m][1]; - //delz = zz - x[m][2]; - //x[m][0] += fraction*delx; - //x[m][1] += fraction*dely; - //x[m][2] += fraction*delz; } else { sp[m][3] = musp; x[m][0] = xx; @@ -820,12 +574,6 @@ void NEB_spin::readfile(char *file, int flag) nread += nchunk; } - // test 1.3 - //double **sp = atom->sp; - //printf("test 1.3 atom: i=%d,%g,%g,%g \n",1,sp[1][0],sp[1][1],sp[1][2]); - //error->all(FLERR,"end neb_spin test"); - - // check that all atom IDs in file were found by a proc if (flag == 0) { @@ -867,13 +615,11 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) { // implementing initial rotation using atan2 - //atan2(crosslen,dots); - // this is not a sufficient routine, // we need more accurate verifications - // initial and final and inter ang. values + // initial, final and inter ang. values double itheta,iphi,ftheta,fphi,ktheta,kphi; double spix,spiy,spiz,spfx,spfy,spfz; double spkx,spky,spkz,iknorm; @@ -909,58 +655,6 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) sploc[1] = spky; sploc[2] = spkz; - //double theta,spdot; - //double inormdot,ispinorm; - //double kix,kiy,kiz; - //double kinorm, ikinorm; - //double crossx,crossy,crossz; - - ////printf("inside rot, spi %g, spf %g \n",spi[0],sploc[0]); - - //spdot = spi[0]*sploc[0]+spi[1]*sploc[1]+spi[2]*sploc[2]; - //theta = fraction*acos(spdot); - - //printf("inside rot, theta %g \n",theta); - - //kix = spi[1]*sploc[2]-spi[2]*sploc[1]; - //kiy = spi[2]*sploc[0]-spi[0]*sploc[2]; - //kiz = spi[0]*sploc[1]-spi[1]*sploc[0]; - // - ////printf("inside rot1.1, ki %g %g %g \n",kix,kiy,kiz); - - //inormdot = 1.0/sqrt(spdot); - //kinorm = kix*kix+kiy*kiy+kiz*kiz; - //if (kinorm == 0.0) { - // kix = 0.0; - // kiy = 0.0; - // kiz = 0.0; - //} else { - // ikinorm = 1.0/kinorm; - // kix *= ikinorm; - // kiy *= ikinorm; - // kiz *= ikinorm; - //} - - ////printf("inside rot1.2, kin %g %g %g \n",kix,kiy,kiz); - - //crossx = kiy*spi[2]-kiz*spi[1]; - //crossy = kiz*spi[0]-kix*spi[2]; - //crossz = kix*spi[1]-kiy*spi[0]; - // - ////printf("inside rot1.3, cross %g %g %g \n",crossx,crossy,crossz); - - //sploc[0] = spi[0]*cos(theta)+crossx*sin(theta); - //sploc[1] = spi[1]*cos(theta)+crossy*sin(theta); - //sploc[2] = spi[2]*cos(theta)+crossz*sin(theta); - // - ////printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); - - //ispinorm = 1.0/sqrt(sploc[0]*sploc[0]+sploc[1]*sploc[1]+sploc[2]*sploc[2]); - - //sploc[0] *= ispinorm; - //sploc[1] *= ispinorm; - //sploc[2] *= ispinorm; - //printf("inside rot2, spf %g %g %g \n",sploc[0],sploc[1],sploc[2]); } /* ---------------------------------------------------------------------- @@ -1007,30 +701,43 @@ void NEB_spin::print_status() //double fnorm2 = sqrt(update->minimize->fnorm_sqr()); - // test fmax spin int nlocal = atom->nlocal; + double tx,ty,tz; + double tnorm2,local_norm_inf,temp_inf; + double **sp = atom->sp; double **fm = atom->fm; - double fnorm2; - for (int i = 0; i < nlocal; i++) - fnorm2 += (fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]); - //for (int i = 0; i < nlocal; i++) - // if (mask[i] & groupbit) { - // fnorm2 += (fm[i][0]*fm[i][0]+fm[i][1]*fm[i][1]+fm[i][2]*fm[i][2]); - // } + + // calc. magnetic torques + tnorm2 = local_norm_inf = temp_inf = 0.0; + for (int i = 0; i < nlocal; i++) { + tx = (fm[i][1]*sp[i][2] - fm[i][2]*sp[i][1]); + ty = (fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); + tz = (fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); + tnorm2 += tx*tx + ty*ty + tz*tz; + + temp_inf = MAX(fabs(tx),fabs(ty)); + temp_inf = MAX(fabs(tz),temp_inf); + local_norm_inf = MAX(temp_inf,local_norm_inf); + + } + double fmaxreplica; - MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); + //MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); + MPI_Allreduce(&tnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); - // no minimize->fnorm_inf for spins //double fnorminf = update->minimize->fnorm_inf(); //double fmaxatom; //MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots); double fnorminf = 0.0; - double fmaxatom = 0.0; + MPI_Allreduce(&local_norm_inf,&fnorminf,1,MPI_DOUBLE,MPI_MAX,world); + double fmaxatom; + MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots); if (verbose) { freplica = new double[nreplica]; - MPI_Allgather(&fnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots); + //MPI_Allgather(&fnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots); + MPI_Allgather(&tnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots); fmaxatomInRepl = new double[nreplica]; MPI_Allgather(&fnorminf,1,MPI_DOUBLE,&fmaxatomInRepl[0],1,MPI_DOUBLE,roots); } diff --git a/src/REPLICA/neb_spin.h b/src/REPLICA/neb_spin.h index 6541658fd7..f6d742c46c 100644 --- a/src/REPLICA/neb_spin.h +++ b/src/REPLICA/neb_spin.h @@ -45,7 +45,8 @@ class NEB_spin : protected Pointers { FILE *fp; int compressed; double etol; // energy tolerance convergence criterion - double ftol; // force tolerance convergence criterion + //double ftol; // force tolerance convergence criterion + double ttol; // torque tolerance convergence criterion int n1steps, n2steps; // number of steps in stage 1 and 2 int nevery; // output interval char *infile; // name of file containing final state @@ -57,9 +58,6 @@ class NEB_spin : protected Pointers { double *freplica; // force on an image double *fmaxatomInRepl; // force on an image - //double geodesic_distance2(double *, double *); - //double evaluate_dt(); - //void advance_spins(double); void readfile(char *, int); void initial_rotation(double *, double *, double); void open(char *); -- GitLab From 5608f87c15a94fc4ab1ce4b0302b5a2ecc2dcd37 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Wed, 13 Mar 2019 21:55:17 -0600 Subject: [PATCH 0240/1243] bond/react:unfix_deletes_internal_groups --- doc/src/fix_bond_react.txt | 4 ++++ src/USER-MISC/fix_bond_react.cpp | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/src/fix_bond_react.txt b/doc/src/fix_bond_react.txt index 5da0f33e3a..af443ede92 100644 --- a/doc/src/fix_bond_react.txt +++ b/doc/src/fix_bond_react.txt @@ -385,6 +385,10 @@ 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. +When fix bond/react is 'unfixed,' all internally-created groups are +deleted. Therefore, fix bond/react can only be unfixed after unfixing +all other fixes that use any group created by fix bond/react. + [Restrictions:] This fix is part of the USER-MISC package. It is only enabled if diff --git a/src/USER-MISC/fix_bond_react.cpp b/src/USER-MISC/fix_bond_react.cpp index c5df3ed438..5d624ad7f4 100644 --- a/src/USER-MISC/fix_bond_react.cpp +++ b/src/USER-MISC/fix_bond_react.cpp @@ -457,8 +457,6 @@ FixBondReact::~FixBondReact() memory->destroy(global_mega_glove); if (stabilization_flag == 1) { - delete [] exclude_group; - // check nfix in case all fixes have already been deleted if (id_fix1 && modify->nfix) modify->delete_fix(id_fix1); delete [] id_fix1; @@ -473,6 +471,18 @@ FixBondReact::~FixBondReact() delete [] statted_id; delete [] guess_branch; delete [] pioneer_count; + + char **newarg; + newarg = new char*[2]; + newarg[0] = master_group; + newarg[1] = (char *) "delete"; + group->assign(2,newarg); + if (stabilization_flag == 1) { + newarg[0] = exclude_group; + group->assign(2,newarg); + delete [] exclude_group; + } + delete [] newarg; } /* ---------------------------------------------------------------------- */ -- GitLab From 033a5c27210d5bfd443a9e5c42fbfdb4e0c4f61b Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 14 Mar 2019 11:07:24 -0600 Subject: [PATCH 0241/1243] Commit JT 031419 - cleaned fix_neb_spin - first working version --- examples/SPIN/gneb/in.gneb.iron | 35 +++- src/REPLICA/fix_neb_spin.cpp | 334 ++++++++------------------------ src/REPLICA/neb_spin.cpp | 6 - src/REPLICA/neb_spin.h | 1 - 4 files changed, 110 insertions(+), 266 deletions(-) diff --git a/examples/SPIN/gneb/in.gneb.iron b/examples/SPIN/gneb/in.gneb.iron index 80ab698c16..7aab0c04c3 100644 --- a/examples/SPIN/gneb/in.gneb.iron +++ b/examples/SPIN/gneb/in.gneb.iron @@ -3,7 +3,6 @@ units metal dimension 3 boundary p p f - atom_style spin # necessary for the serial algorithm (sametag) @@ -14,7 +13,7 @@ region box block 0.0 4.0 0.0 4.0 0.0 1.0 #create_box 1 box #create_atoms 1 box -read_data ../examples/SPIN/gneb_bfo/initial.iron_spin +read_data initial.iron_spin # setting mass, mag. moments, and interactions for bcc iron @@ -27,16 +26,36 @@ pair_coeff * * exchange 3.4 0.02726 0.2171 1.841 neighbor 0.1 bin neigh_modify every 10 check yes delay 20 -fix 1 all precession/spin zeeman 0.001 0.0 0.0 1.0 anisotropy 0.01 1.0 0.0 0.0 -fix 2 all langevin/spin 0.1 0.0 21 -fix 3 all neb/spin 1.0 +fix 1 all precession/spin zeeman 0.1 0.0 0.0 1.0 anisotropy 0.0001 1.0 0.0 0.0 +fix_modify 1 energy yes +fix 2 all langevin/spin 0.0 0.0 21 +fix 3 all neb/spin 1.0 #fix 4 all nve/spin lattice no -#parallel ideal timestep 0.0001 thermo 100 +compute out_mag all spin +compute out_pe all pe +compute out_ke all ke +compute out_temp all temp + +variable magx equal c_out_mag[1] +variable magy equal c_out_mag[2] +variable magz equal c_out_mag[3] +variable magnorm equal c_out_mag[4] +variable emag equal c_out_mag[5] + +thermo 100 +thermo_style custom step time v_magx v_magz v_magnorm etotal +thermo_modify format float %20.15g + +compute outsp all property/atom spx spy spz sp fmx fmy fmz +variable u universe 1 2 3 4 +#dump 1 all custom 100 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] +dump 1 all custom 200 dump.$u type x y z c_outsp[1] c_outsp[2] c_outsp[3] min_style spinmin -neb/spin 0.0 0.1 100 10 10 final ../examples/SPIN/gneb_bfo/final.iron_spin -#neb/spin 0.0 0.1 1000 1000 100 final ../examples/SPIN/gneb_bfo/final.iron_spin +min_modify alpha_damp 1.0 discret_factor 10.0 +neb/spin 1.0e-12 1.0e-12 50000 50000 10 final final.iron_spin +#neb/spin 1.0e-6 1.0e-6 1000 10 10 final final.iron_spin diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index 015ff1a313..95d5e19f25 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -15,7 +15,6 @@ #include #include #include -//#include "fix_neb.h" #include "fix_neb_spin.h" #include "universe.h" #include "update.h" @@ -41,18 +40,13 @@ enum{SINGLE_PROC_DIRECT,SINGLE_PROC_MAP,MULTI_PROC}; /* ---------------------------------------------------------------------- */ FixNEB_spin::FixNEB_spin(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), - id_pe(NULL), pe(NULL), nlenall(NULL), xprev(NULL), xnext(NULL), - fnext(NULL), - spprev(NULL), spnext(NULL), fmnext(NULL), - springF(NULL), tangent(NULL), - xsend(NULL), xrecv(NULL), fsend(NULL), frecv(NULL), - spsend(NULL), sprecv(NULL), fmsend(NULL), fmrecv(NULL), - tagsend(NULL), tagrecv(NULL), - xsendall(NULL), xrecvall(NULL), fsendall(NULL), frecvall(NULL), - spsendall(NULL), sprecvall(NULL), fmsendall(NULL), fmrecvall(NULL), - tagsendall(NULL), tagrecvall(NULL), counts(NULL), - displacements(NULL) + Fix(lmp, narg, arg), id_pe(NULL), pe(NULL), nlenall(NULL), xprev(NULL), + xnext(NULL), fnext(NULL), spprev(NULL), spnext(NULL), fmnext(NULL), springF(NULL), + tangent(NULL), xsend(NULL), xrecv(NULL), fsend(NULL), frecv(NULL), spsend(NULL), + sprecv(NULL), fmsend(NULL), fmrecv(NULL), tagsend(NULL), tagrecv(NULL), + xsendall(NULL), xrecvall(NULL), fsendall(NULL), frecvall(NULL), spsendall(NULL), + sprecvall(NULL), fmsendall(NULL), fmrecvall(NULL), tagsendall(NULL), tagrecvall(NULL), + counts(NULL), displacements(NULL) { if (narg < 4) error->all(FLERR,"Illegal fix neb_spin command"); @@ -145,11 +139,12 @@ FixNEB_spin::~FixNEB_spin() modify->delete_compute(id_pe); delete [] id_pe; + // memory destroy of all spin and lattice arrays + memory->destroy(xprev); memory->destroy(xnext); memory->destroy(tangent); memory->destroy(fnext); - // spin quantities memory->destroy(spprev); memory->destroy(spnext); memory->destroy(fmnext); @@ -158,7 +153,6 @@ FixNEB_spin::~FixNEB_spin() memory->destroy(xrecv); memory->destroy(fsend); memory->destroy(frecv); - // spin quantities memory->destroy(spsend); memory->destroy(sprecv); memory->destroy(fmsend); @@ -170,7 +164,6 @@ FixNEB_spin::~FixNEB_spin() memory->destroy(xrecvall); memory->destroy(fsendall); memory->destroy(frecvall); - // spin quantities memory->destroy(spsendall); memory->destroy(sprecvall); memory->destroy(fmsendall); @@ -237,7 +230,6 @@ void FixNEB_spin::init() memory->create(frecvall,ntotal,3,"neb:frecvall"); memory->create(tagsendall,ntotal,"neb:tagsendall"); memory->create(tagrecvall,ntotal,"neb:tagrecvall"); - // spin quantities memory->create(spsendall,ntotal,3,"neb:xsendall"); memory->create(sprecvall,ntotal,3,"neb:xrecvall"); memory->create(fmsendall,ntotal,3,"neb:fsendall"); @@ -263,14 +255,10 @@ void FixNEB_spin::min_setup(int vflag) void FixNEB_spin::min_post_force(int /*vflag*/) { double vprev,vnext; - //double delxp,delyp,delzp,delxn,delyn,delzn; - // spin quantities double delspxp,delspyp,delspzp; double delspxn,delspyn,delspzn; double templen; double vIni=0.0; - - // local spin values for geo. dist. calc. double spi[3],spj[3]; vprev = vnext = veng = pe->compute_scalar(); @@ -290,36 +278,17 @@ void FixNEB_spin::min_post_force(int /*vflag*/) MPI_Bcast(&vnext,1,MPI_DOUBLE,0,world); } - //printf("test veng: %g / %g / %g \n",veng,vprev,vnext); - //error->universe_all(FLERR,"End test"); - if (FreeEndFinal && ireplica == nreplica-1 && (update->ntimestep == 0)) - EFinalIni = veng; + error->all(FLERR,"NEB_spin Free End option not yet active"); if (ireplica == 0) vIni=veng; - if (FreeEndFinalWithRespToEIni) { - if (cmode == SINGLE_PROC_DIRECT || cmode == SINGLE_PROC_MAP) { - int procFirst; - procFirst=universe->root_proc[0]; - MPI_Bcast(&vIni,1,MPI_DOUBLE,procFirst,uworld); - } else { - if (me == 0) - MPI_Bcast(&vIni,1,MPI_DOUBLE,0,rootworld); + if (FreeEndFinalWithRespToEIni) + error->all(FLERR,"NEB_spin Free End option not yet active"); - MPI_Bcast(&vIni,1,MPI_DOUBLE,0,world); - } - } + if (FreeEndIni && ireplica == 0 && (update->ntimestep == 0)) + error->all(FLERR,"NEB_spin Free End option not yet active"); - if (FreeEndIni && ireplica == 0 && (update->ntimestep == 0)) EIniIni = veng; - /* if (FreeEndIni && ireplica == 0) { - // if (me == 0 ) - if (update->ntimestep == 0) { - EIniIni = veng; - // if (cmode == MULTI_PROC) - // MPI_Bcast(&EIniIni,1,MPI_DOUBLE,0,world); - } - }*/ // communicate atoms to/from adjacent replicas to fill xprev,xnext @@ -329,15 +298,13 @@ void FixNEB_spin::min_post_force(int /*vflag*/) pe->addstep(update->ntimestep+1); + int nlocal = atom->nlocal; + int *mask = atom->mask; double **x = atom->x; double **sp = atom->sp; - int *mask = atom->mask; double dot = 0.0; double prefactor = 0.0; - - //double **f = atom->f; double **fm = atom->fm; - int nlocal = atom->nlocal; //calculating separation between images @@ -351,10 +318,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) // computation of the tangent vector - if (ireplica == nreplica-1) { - - // final replica - + if (ireplica == nreplica-1) { // final replica for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { @@ -371,64 +335,26 @@ void FixNEB_spin::min_post_force(int /*vflag*/) delspyp -= delpdots*sp[i][1]; delspzp -= delpdots*sp[i][2]; - // adjust distance if pbc - //domain->minimum_image(delspxp,delspyp,delspzp); - // calc. geodesic length - spi[0]=sp[i][0]; - spi[1]=sp[i][1]; - spi[2]=sp[i][2]; - spj[0]=spprev[i][0]; - spj[1]=spprev[i][1]; - spj[2]=spprev[i][2]; - templen = geodesic_distance(spi, spj); + spi[0] = sp[i][0]; + spi[1] = sp[i][1]; + spi[2] = sp[i][2]; + spj[0] = spprev[i][0]; + spj[1] = spprev[i][1]; + spj[2] = spprev[i][2]; + templen = geodesic_distance(spi,spj); plen += templen*templen; dottangrad += delspxp*fm[i][0]+ delspyp*fm[i][1]+delspzp*fm[i][2]; gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; - - //plen += delxp*delxp + delyp*delyp + delzp*delzp; - //dottangrad += delxp* f[i][0]+ delyp*f[i][1]+delzp*f[i][2]; - //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; - // final replica, no need for the tangent vector - // (unless FreeEnd option) - if (FreeEndFinal||FreeEndFinalWithRespToEIni) { - error->all(FLERR,"Free End option not yet active"); - //tangent[i][0]=delspxp; - //tangent[i][1]=delspyp; - //tangent[i][2]=delspzp; - //// if needed, tlen has to be modified - //tlen += tangent[i][0]*tangent[i][0] + - // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - //dot += fm[i][0]*tangent[i][0] + fm[i][1]*tangent[i][1] + - // fm[i][2]*tangent[i][2]; - } - - - //delxp = x[i][0] - xprev[i][0]; - //delyp = x[i][1] - xprev[i][1]; - //delzp = x[i][2] - xprev[i][2]; - //domain->minimum_image(delxp,delyp,delzp); + // no free end option for now - //plen += delxp*delxp + delyp*delyp + delzp*delzp; - //dottangrad += delxp* f[i][0]+ delyp*f[i][1]+delzp*f[i][2]; - //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; - //if (FreeEndFinal||FreeEndFinalWithRespToEIni) { - // tangent[i][0]=delxp; - // tangent[i][1]=delyp; - // tangent[i][2]=delzp; - // tlen += tangent[i][0]*tangent[i][0] + - // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - // dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + - // f[i][2]*tangent[i][2]; - //} + if (FreeEndFinal||FreeEndFinalWithRespToEIni) + error->all(FLERR,"Free End option not yet active"); + } - - } else if (ireplica == 0) { - - // initial replica - + } else if (ireplica == 0) { // initial replica for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { @@ -444,9 +370,6 @@ void FixNEB_spin::min_post_force(int /*vflag*/) delspxn -= delndots*sp[i][0]; delspyn -= delndots*sp[i][1]; delspzn -= delndots*sp[i][2]; - - // adjust del. if pbc - //domain->minimum_image(delspxn,delspyn,delspzn); // calc. geodesic length @@ -456,70 +379,40 @@ void FixNEB_spin::min_post_force(int /*vflag*/) spj[0]=spnext[i][0]; spj[1]=spnext[i][1]; spj[2]=spnext[i][2]; - templen = geodesic_distance(spi, spj); + templen = geodesic_distance(spi,spj); nlen += templen*templen; dottangrad += delspxn*fm[i][0] + delspyn*fm[i][1] + delspzn*fm[i][2]; gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; - if (FreeEndIni) { + + // no free end option for now + + if (FreeEndIni) error->all(FLERR,"Free End option not yet active"); - //tangent[i][0]=delxn; - //tangent[i][1]=delyn; - //tangent[i][2]=delzn; - //// if needed, tlen has to be modified - //tlen += tangent[i][0]*tangent[i][0] + - // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - //dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + - // f[i][2]*tangent[i][2]; - } - //delxn = xnext[i][0] - x[i][0]; - //delyn = xnext[i][1] - x[i][1]; - //delzn = xnext[i][2] - x[i][2]; - //domain->minimum_image(delxn,delyn,delzn); - //nlen += delxn*delxn + delyn*delyn + delzn*delzn; - //gradnextlen += fnext[i][0]*fnext[i][0] - // + fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2]; - //dotgrad += f[i][0]*fnext[i][0] - // + f[i][1]*fnext[i][1] + f[i][2]*fnext[i][2]; - //dottangrad += delxn*f[i][0]+ delyn*f[i][1] + delzn*f[i][2]; - //gradlen += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2]; - //if (FreeEndIni) { - // tangent[i][0]=delxn; - // tangent[i][1]=delyn; - // tangent[i][2]=delzn; - // tlen += tangent[i][0]*tangent[i][0] + - // tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; - // dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + - // f[i][2]*tangent[i][2]; - //} } - - } else { - - // not the first or last replica + } else { // intermediate replica double vmax = MAX(fabs(vnext-veng),fabs(vprev-veng)); double vmin = MIN(fabs(vnext-veng),fabs(vprev-veng)); - for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { // calc. delp vector + delspxp = sp[i][0] - spprev[i][0]; delspyp = sp[i][1] - spprev[i][1]; delspzp = sp[i][2] - spprev[i][2]; // project delp vector on tangent space + delndots = delspxp*sp[i][0]+delspyp*sp[i][1]+delspzp*sp[i][2]; delspxp -= delpdots*sp[i][0]; delspyp -= delpdots*sp[i][1]; delspzp -= delpdots*sp[i][2]; - - // adjust distance if pbc - //domain->minimum_image(delspxp,delspyp,delspzp); - // calc. geodesic length + // calc. prev. geodesic length + spi[0]=sp[i][0]; spi[1]=sp[i][1]; spi[2]=sp[i][2]; @@ -530,18 +423,19 @@ void FixNEB_spin::min_post_force(int /*vflag*/) plen += templen*templen; // calc. deln vector - delspxn = spnext[i][0] - sp[i][0]; + + delspxn = spnext[i][0] - sp[i][0]; delspyn = spnext[i][1] - sp[i][1]; delspzn = spnext[i][2] - sp[i][2]; // project deln vector on tangent space + delndots = delspxn*sp[i][0]+delspyn*sp[i][1]+delspzn*sp[i][2]; delspxn -= delndots*sp[i][0]; delspyn -= delndots*sp[i][1]; delspzn -= delndots*sp[i][2]; - - // adjust distance if pbc - //domain->minimum_image(delspxn,delspyn,delspzn); + + // evaluate best path tangent if (vnext > veng && veng > vprev) { tangent[i][0] = delspxn; @@ -567,7 +461,8 @@ void FixNEB_spin::min_post_force(int /*vflag*/) } } - // calc. geodesic length + // calc. next geodesic length + spi[0]=sp[i][0]; spi[1]=sp[i][1]; spi[2]=sp[i][2]; @@ -576,27 +471,26 @@ void FixNEB_spin::min_post_force(int /*vflag*/) spj[2]=spnext[i][2]; templen = geodesic_distance(spi, spj); nlen += templen*templen; - //nlen += delxn*delxn + delyn*delyn + delzn*delzn; - tlen += tangent[i][0]*tangent[i][0] + - tangent[i][1]*tangent[i][1] + tangent[i][2]*tangent[i][2]; + + tlen += tangent[i][0]*tangent[i][0] + tangent[i][1]*tangent[i][1] + + tangent[i][2]*tangent[i][2]; gradlen += fm[i][0]*fm[i][0] + fm[i][1]*fm[i][1] + fm[i][2]*fm[i][2]; dotpath += delspxp*delspxn + delspyp*delspyn + delspzp*delspzn; - dottangrad += tangent[i][0]*fm[i][0] + - tangent[i][1]*fm[i][1] + tangent[i][2]*fm[i][2]; - gradnextlen += fnext[i][0]*fnext[i][0] + - fnext[i][1]*fnext[i][1] +fnext[i][2] * fnext[i][2]; + dottangrad += tangent[i][0]*fm[i][0] + tangent[i][1]*fm[i][1] + + tangent[i][2]*fm[i][2]; + gradnextlen += fnext[i][0]*fnext[i][0] + fnext[i][1]*fnext[i][1] + + fnext[i][2]*fnext[i][2]; dotgrad += fm[i][0]*fnext[i][0] + fm[i][1]*fnext[i][1] + fm[i][2]*fnext[i][2]; // no Perpendicular nudging force option active yet - // see fix_neb for example - if (kspringPerp != 0.0) + + if (kspringPerp != 0.0) error->all(FLERR,"NEB_spin Perpendicular nudging force not yet active"); } } - // MPI reduce if more than one proc for world double bufin[BUFSIZE], bufout[BUFSIZE]; @@ -618,8 +512,7 @@ void FixNEB_spin::min_post_force(int /*vflag*/) dottangrad = bufout[6]; dotgrad = bufout[7]; - - // project tangent vector on tangent space + // project tangent vector on tangent space and normalize it double buftan[3]; double tandots; @@ -633,20 +526,14 @@ void FixNEB_spin::min_post_force(int /*vflag*/) tangent[i][0] = buftan[0]; tangent[i][1] = buftan[1]; tangent[i][2] = buftan[2]; - } - - // normalize tangent vector - - if (tlen > 0.0) { - double tleninv = 1.0/tlen; - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) { + if (tlen > 0.0) { + double tleninv = 1.0/tlen; tangent[i][0] *= tleninv; tangent[i][1] *= tleninv; tangent[i][2] *= tleninv; } - } + } // first or last replica has no change to forces, just return @@ -659,32 +546,21 @@ void FixNEB_spin::min_post_force(int /*vflag*/) if (ireplica < nreplica-1) dotgrad = dotgrad /(gradlen*gradnextlen); - // no Free End option active yet - // see fix_neb for example - if (FreeEndIni && ireplica == 0) { + // no Free End options active yet + + if (FreeEndIni && ireplica == 0) error->all(FLERR,"NEB_spin Free End option not yet active"); - } - - // no Free End option active yet - // see fix_neb for example - if (FreeEndFinal && ireplica == nreplica -1) { + if (FreeEndFinal && ireplica == nreplica -1) error->all(FLERR,"NEB_spin Free End option not yet active"); - } - - // no Free End option active yet - // see fix_neb for example - if (FreeEndFinalWithRespToEIni&&ireplica == nreplica -1) { + if (FreeEndFinalWithRespToEIni&&ireplica == nreplica -1) error->all(FLERR,"NEB_spin Free End option not yet active"); - } // no NEB_spin long range option - // see fix_neb for example - double lentot = 0; - double meanDist,idealPos,lenuntilIm,lenuntilClimber; - lenuntilClimber=0; - if (NEBLongRange) { + + if (NEBLongRange) error->all(FLERR,"NEB_spin long range option not yet active"); - } + + // exit calc. if first or last replica (no gneb force) if (ireplica == 0 || ireplica == nreplica-1) return ; @@ -692,47 +568,30 @@ void FixNEB_spin::min_post_force(int /*vflag*/) dotpath = dotpath/(plen*nlen); AngularContr = 0.5 *(1+cos(MY_PI * dotpath)); - double dotSpringTangent; - dotSpringTangent=0; - for (int i = 0; i < nlocal; i++) { + for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { dot += fm[i][0]*tangent[i][0] + fm[i][1]*tangent[i][1] + fm[i][2]*tangent[i][2]; - // springF defined for perp. spring option - // not defined here - //dotSpringTangent += springF[i][0]*tangent[i][0] + - springF[i][1]*tangent[i][1] + springF[i][2]*tangent[i][2];} - //dot += f[i][0]*tangent[i][0] + f[i][1]*tangent[i][1] + - // f[i][2]*tangent[i][2]; - //dotSpringTangent += springF[i][0]*tangent[i][0] + - // springF[i][1]*tangent[i][1] + springF[i][2]*tangent[i][2];} - } + } - // gather all dot and dotSpring for this replica (world) - double dotSpringTangentall; - MPI_Allreduce(&dotSpringTangent,&dotSpringTangentall,1, - MPI_DOUBLE,MPI_SUM,world); - dotSpringTangent=dotSpringTangentall; + // gather all dot for this replica + double dotall; MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world); dot=dotall; + // calc. GNEB force prefactor - // implement climbing image here - - if (ireplica == rclimber) { - error->all(FLERR,"NEB_spin climber option not yet active"); - //prefactor = -2.0*dot; - } else { - if (NEBLongRange) { + if (ireplica == rclimber) prefactor = -2.0*dot; // for climbing replica + else { + if (NEBLongRange) { // for intermediate replica error->all(FLERR,"Long Range NEB_spin climber option not yet active"); - //prefactor = -dot - kspring*(lenuntilIm-idealPos)/(2*meanDist); } else if (StandardNEB) { prefactor = -dot + kspring*(nlen-plen); } - if (FinalAndInterWithRespToEIni&& vengall(FLERR,"Incorrect calc. of geodesic_distance in Fix NEB/spin"); + + dist = atan2(normcross,dots); return dist; } @@ -818,7 +672,6 @@ void FixNEB_spin::inter_replica_comm() double **x = atom->x; double **f = atom->f; - // spin quantities double **sp = atom->sp; double **fm = atom->fm; tagint *tag = atom->tag; @@ -880,7 +733,6 @@ void FixNEB_spin::inter_replica_comm() fsend[m][0] = f[i][0]; fsend[m][1] = f[i][1]; fsend[m][2] = f[i][2]; - // spin quantities spsend[m][0] = sp[i][0]; spsend[m][1] = sp[i][1]; spsend[m][2] = sp[i][2]; @@ -892,13 +744,11 @@ void FixNEB_spin::inter_replica_comm() if (ireplica > 0) { MPI_Irecv(xrecv[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); - // spin quantities MPI_Irecv(sprecv[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); MPI_Irecv(tagrecv,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld,&requests[1]); } if (ireplica < nreplica-1) { MPI_Send(xsend[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); - // spin quantities MPI_Send(spsend[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); MPI_Send(tagsend,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld); } @@ -910,7 +760,6 @@ void FixNEB_spin::inter_replica_comm() xprev[m][0] = xrecv[i][0]; xprev[m][1] = xrecv[i][1]; xprev[m][2] = xrecv[i][2]; - // spin quantities spprev[m][0] = sprecv[i][0]; spprev[m][1] = sprecv[i][1]; spprev[m][2] = sprecv[i][2]; @@ -919,7 +768,6 @@ void FixNEB_spin::inter_replica_comm() if (ireplica < nreplica-1) { MPI_Irecv(xrecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); MPI_Irecv(frecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); - // spin quantities MPI_Irecv(sprecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); MPI_Irecv(fmrecv[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); MPI_Irecv(tagrecv,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld,&requests[1]); @@ -927,7 +775,6 @@ void FixNEB_spin::inter_replica_comm() if (ireplica > 0) { MPI_Send(xsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); MPI_Send(fsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); - // spin quantities MPI_Send(spsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); MPI_Send(fmsend[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); MPI_Send(tagsend,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld); @@ -943,7 +790,6 @@ void FixNEB_spin::inter_replica_comm() fnext[m][0] = frecv[i][0]; fnext[m][1] = frecv[i][1]; fnext[m][2] = frecv[i][2]; - // spin quantities spnext[m][0] = sprecv[i][0]; spnext[m][1] = sprecv[i][1]; spnext[m][2] = sprecv[i][2]; @@ -972,7 +818,6 @@ void FixNEB_spin::inter_replica_comm() fsend[m][0] = f[i][0]; fsend[m][1] = f[i][1]; fsend[m][2] = f[i][2]; - // spin quantities spsend[m][0] = sp[i][0]; spsend[m][1] = sp[i][1]; spsend[m][2] = sp[i][2]; @@ -1002,7 +847,6 @@ void FixNEB_spin::inter_replica_comm() MPI_Gatherv(NULL,3*m,MPI_DOUBLE, fsendall[0],counts,displacements,MPI_DOUBLE,0,world); } - // spin quantities if (spsend) { MPI_Gatherv(spsend[0],3*m,MPI_DOUBLE, spsendall[0],counts,displacements,MPI_DOUBLE,0,world); @@ -1017,14 +861,12 @@ void FixNEB_spin::inter_replica_comm() if (ireplica > 0 && me == 0) { MPI_Irecv(xrecvall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); - // spin quantities MPI_Irecv(sprecvall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld,&requests[0]); MPI_Irecv(tagrecvall,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld, &requests[1]); } if (ireplica < nreplica-1 && me == 0) { MPI_Send(xsendall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); - // spin quantities MPI_Send(spsendall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld); MPI_Send(tagsendall,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld); } @@ -1034,7 +876,6 @@ void FixNEB_spin::inter_replica_comm() MPI_Bcast(tagrecvall,nebatoms,MPI_INT,0,world); MPI_Bcast(xrecvall[0],3*nebatoms,MPI_DOUBLE,0,world); - // spin quantities MPI_Bcast(sprecvall[0],3*nebatoms,MPI_DOUBLE,0,world); for (i = 0; i < nebatoms; i++) { @@ -1043,7 +884,6 @@ void FixNEB_spin::inter_replica_comm() xprev[m][0] = xrecvall[i][0]; xprev[m][1] = xrecvall[i][1]; xprev[m][2] = xrecvall[i][2]; - // spin quantities spprev[m][0] = sprecvall[i][0]; spprev[m][1] = sprecvall[i][1]; spprev[m][2] = sprecvall[i][2]; @@ -1053,7 +893,6 @@ void FixNEB_spin::inter_replica_comm() if (ireplica < nreplica-1 && me == 0) { MPI_Irecv(xrecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); MPI_Irecv(frecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); - // spin quantities MPI_Irecv(sprecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); MPI_Irecv(sprecvall[0],3*nebatoms,MPI_DOUBLE,procnext,0,uworld,&requests[0]); MPI_Irecv(tagrecvall,nebatoms,MPI_LMP_TAGINT,procnext,0,uworld, @@ -1062,7 +901,6 @@ void FixNEB_spin::inter_replica_comm() if (ireplica > 0 && me == 0) { MPI_Send(xsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); MPI_Send(fsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); - // spin quantities MPI_Send(spsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); MPI_Send(fmsendall[0],3*nebatoms,MPI_DOUBLE,procprev,0,uworld); MPI_Send(tagsendall,nebatoms,MPI_LMP_TAGINT,procprev,0,uworld); @@ -1074,7 +912,6 @@ void FixNEB_spin::inter_replica_comm() MPI_Bcast(tagrecvall,nebatoms,MPI_INT,0,world); MPI_Bcast(xrecvall[0],3*nebatoms,MPI_DOUBLE,0,world); MPI_Bcast(frecvall[0],3*nebatoms,MPI_DOUBLE,0,world); - // spin quantities MPI_Bcast(sprecvall[0],3*nebatoms,MPI_DOUBLE,0,world); MPI_Bcast(fmrecvall[0],3*nebatoms,MPI_DOUBLE,0,world); @@ -1087,7 +924,6 @@ void FixNEB_spin::inter_replica_comm() fnext[m][0] = frecvall[i][0]; fnext[m][1] = frecvall[i][1]; fnext[m][2] = frecvall[i][2]; - // spin quantities spnext[m][0] = sprecvall[i][0]; spnext[m][1] = sprecvall[i][1]; spnext[m][2] = sprecvall[i][2]; @@ -1112,7 +948,6 @@ void FixNEB_spin::reallocate() memory->destroy(tangent); memory->destroy(fnext); memory->destroy(springF); - // spin quantities memory->destroy(spprev); memory->destroy(spnext); memory->destroy(fmnext); @@ -1122,7 +957,6 @@ void FixNEB_spin::reallocate() memory->create(tangent,maxlocal,3,"neb:tangent"); memory->create(fnext,maxlocal,3,"neb:fnext"); memory->create(springF,maxlocal,3,"neb:springF"); - // spin quantities memory->create(spprev,maxlocal,3,"neb:xprev"); memory->create(spnext,maxlocal,3,"neb:xnext"); memory->create(fmnext,maxlocal,3,"neb:fnext"); @@ -1132,7 +966,6 @@ void FixNEB_spin::reallocate() memory->destroy(fsend); memory->destroy(xrecv); memory->destroy(frecv); - // spin quantities memory->destroy(spsend); memory->destroy(fmsend); memory->destroy(sprecv); @@ -1143,7 +976,6 @@ void FixNEB_spin::reallocate() memory->create(fsend,maxlocal,3,"neb:fsend"); memory->create(xrecv,maxlocal,3,"neb:xrecv"); memory->create(frecv,maxlocal,3,"neb:frecv"); - // spin quantities memory->create(spsend,maxlocal,3,"neb:xsend"); memory->create(fmsend,maxlocal,3,"neb:fsend"); memory->create(sprecv,maxlocal,3,"neb:xrecv"); diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index e82b08e354..680d4a373b 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -20,12 +20,9 @@ #include #include #include -//#include "neb.h" -// test spin #include "neb_spin.h" #include "compute.h" #include "force.h" - #include "universe.h" #include "atom.h" #include "update.h" @@ -34,10 +31,7 @@ #include "min.h" #include "modify.h" #include "fix.h" -//#include "fix_neb.h" -// test spin #include "fix_neb_spin.h" - #include "output.h" #include "thermo.h" #include "finish.h" diff --git a/src/REPLICA/neb_spin.h b/src/REPLICA/neb_spin.h index f6d742c46c..b579793fe6 100644 --- a/src/REPLICA/neb_spin.h +++ b/src/REPLICA/neb_spin.h @@ -45,7 +45,6 @@ class NEB_spin : protected Pointers { FILE *fp; int compressed; double etol; // energy tolerance convergence criterion - //double ftol; // force tolerance convergence criterion double ttol; // torque tolerance convergence criterion int n1steps, n2steps; // number of steps in stage 1 and 2 int nevery; // output interval -- GitLab From a3c936d2839329bfd9a0dd4c3cafb5220879d84a Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 14 Mar 2019 15:13:02 -0600 Subject: [PATCH 0242/1243] bug fixes for new local hyperdynamics reduced comm --- src/REPLICA/fix_hyper_local.cpp | 2 +- src/comm_brick.cpp | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/REPLICA/fix_hyper_local.cpp b/src/REPLICA/fix_hyper_local.cpp index a2af3dff6e..21ad2cd86a 100644 --- a/src/REPLICA/fix_hyper_local.cpp +++ b/src/REPLICA/fix_hyper_local.cpp @@ -1197,7 +1197,7 @@ int FixHyperLocal::pack_reverse_comm(int n, int first, double *buf) int nonzero = 0; m++; // placeholder for count of atoms for (i = first; i < last; i++) { - if (maxstrain[i] == 0.0) continue; + if (maxstrain_domain[i] == 0.0) continue; nonzero++; buf[m++] = ubuf(i-first).d; // which atom is next buf[m++] = maxstrain_domain[i]; // value diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index bf7f3e2f8f..64b21e41c9 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -1046,6 +1046,10 @@ void CommBrick::reverse_comm_fix(Fix *fix, int size) reverse communication invoked by a Fix with variable size data query fix for pack size to insure buf_send is big enough handshake sizes before each Irecv/Send to insure buf_recv is big enough + this removes the if tests on sendnum and recvnum to make MPI calls, + as in reverse_comm_fix(), b/c the caller may still want to + exchange a message even if the send/recv swap has no atoms, + e.g. a reduced count = 0 of atoms to send/recv, as in fix hyper/local ------------------------------------------------------------------------- */ void CommBrick::reverse_comm_fix_variable(Fix *fix) @@ -1069,14 +1073,13 @@ void CommBrick::reverse_comm_fix_variable(Fix *fix) MPI_Sendrecv(&nsend,1,MPI_INT,recvproc[iswap],0, &nrecv,1,MPI_INT,sendproc[iswap],0,world, MPI_STATUS_IGNORE); - if (sendnum[iswap]) { - if (nrecv > maxrecv) grow_recv(nrecv); - MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0, - world,&request); - } - if (recvnum[iswap]) - MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world); - if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); + + if (nrecv > maxrecv) grow_recv(nrecv); + MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0, + world,&request); + + MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world); + MPI_Wait(&request,MPI_STATUS_IGNORE); buf = buf_recv; } else buf = buf_send; -- GitLab From d66b07dabeb0d4804826b8e396e298b95eba1ddb Mon Sep 17 00:00:00 2001 From: julient31 Date: Thu, 14 Mar 2019 15:39:45 -0600 Subject: [PATCH 0243/1243] Commit2 JT 031419 - commit before solo tests --- src/REPLICA/neb_spin.cpp | 42 ++++++---------------------------------- src/REPLICA/neb_spin.h | 1 - 2 files changed, 6 insertions(+), 37 deletions(-) diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index 680d4a373b..6681bf56ad 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -46,7 +46,6 @@ using namespace MathConst; #define MAXLINE 256 #define CHUNK 1024 -//#define ATTRIBUTE_PERLINE 4 // 8 attributes: tag, spin norm, position (3), spin direction (3) #define ATTRIBUTE_PERLINE 8 @@ -62,11 +61,9 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, int n2steps_in, int nevery_in, double *buf_init, double *buf_final) : Pointers(lmp) { - //double delx,dely,delz; double delspx,delspy,delspz; etol = etol_in; - //ftol = ftol_in; ttol = ftol_in; n1steps = n1steps_in; n2steps = n2steps_in; @@ -98,16 +95,14 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, spfinal[1] = buf_final[ii+1]; spfinal[2] = buf_final[ii+2]; + // circular initialization + // a better procedure may be developed + initial_rotation(spinit,spfinal,fraction); sp[i][0] = spfinal[0]; sp[i][1] = spfinal[1]; sp[i][2] = spfinal[2]; - - // adjust distance if pbc - //domain->minimum_image(delx,dely,delz); - - // need to define a better procedure for circular initialization ii += 3; } @@ -134,7 +129,6 @@ void NEB_spin::command(int narg, char **arg) if (narg < 6) error->universe_all(FLERR,"Illegal NEB_spin command"); etol = force->numeric(FLERR,arg[0]); - //ftol = force->numeric(FLERR,arg[1]); ttol = force->numeric(FLERR,arg[1]); n1steps = force->inumeric(FLERR,arg[2]); n2steps = force->inumeric(FLERR,arg[3]); @@ -143,7 +137,6 @@ void NEB_spin::command(int narg, char **arg) // error checks if (etol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); - //if (ftol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); if (ttol < 0.0) error->all(FLERR,"Illegal NEB_spin command"); if (nevery <= 0) error->universe_all(FLERR,"Illegal NEB_spin command"); if (n1steps % nevery || n2steps % nevery) @@ -172,7 +165,6 @@ void NEB_spin::command(int narg, char **arg) // process file-style setting to setup initial configs for all replicas - // check what options are available if (strcmp(arg[5],"final") == 0) { if (narg != 7 && narg !=8) error->universe_all(FLERR,"Illegal NEB_spin command"); infile = arg[6]; @@ -205,6 +197,7 @@ void NEB_spin::run() MPI_Comm_split(uworld,color,0,&roots); // search for neb_spin fix, allocate it + int ineb; for (ineb = 0; ineb < modify->nfix; ineb++) if (strcmp(modify->fix[ineb]->style,"neb/spin") == 0) break; @@ -220,7 +213,6 @@ void NEB_spin::run() update->whichflag = 2; update->etol = etol; - //update->ftol = ftol; update->ftol = ttol; // update->ftol is a torque tolerance update->multireplica = 1; @@ -258,11 +250,6 @@ void NEB_spin::run() "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " "... ReplicaTorqueN MaxAtomTorqueN\n"); - //fprintf(uscreen,"Step MaxReplicaForce MaxAtomForce " - // "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " - // "RDN PEN pathangle1 angletangrad1 anglegrad1 gradV1 " - // "ReplicaForce1 MaxAtomForce1 pathangle2 angletangrad2 " - // "... ReplicaForceN MaxAtomForceN\n"); } else { fprintf(uscreen,"Step MaxReplicaTorque MaxAtomTorque " "GradV0 GradV1 GradVc EBF EBR RDT RD1 PE1 RD2 PE2 ... " @@ -424,7 +411,6 @@ void NEB_spin::readfile(char *file, int flag) char *eof,*start,*next,*buf; char line[MAXLINE]; double xx,yy,zz,delx,dely,delz; - // spin quantities double musp,spx,spy,spz; if (me_universe == 0 && screen) @@ -469,7 +455,6 @@ void NEB_spin::readfile(char *file, int flag) double fraction = ireplica/(nreplica-1.0); double **x = atom->x; - // spin quantities double **sp = atom->sp; double spinit[3],spfinal[3]; int nlocal = atom->nlocal; @@ -539,9 +524,6 @@ void NEB_spin::readfile(char *file, int flag) spfinal[0] = spx; spfinal[1] = spy; spfinal[2] = spz; - - // to be used it atomic displacements with pbc - //domain->minimum_image(delx,dely,delz); // interpolate intermediate spin states @@ -609,11 +591,10 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) { // implementing initial rotation using atan2 - // this is not a sufficient routine, - // we need more accurate verifications - + // this may not be a sufficient routine, need more accurate verifications // initial, final and inter ang. values + double itheta,iphi,ftheta,fphi,ktheta,kphi; double spix,spiy,spiz,spfx,spfy,spfz; double spkx,spky,spkz,iknorm; @@ -648,7 +629,6 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) sploc[0] = spkx; sploc[1] = spky; sploc[2] = spkz; - } /* ---------------------------------------------------------------------- @@ -692,9 +672,6 @@ void NEB_spin::open(char *file) void NEB_spin::print_status() { - - //double fnorm2 = sqrt(update->minimize->fnorm_sqr()); - int nlocal = atom->nlocal; double tx,ty,tz; double tnorm2,local_norm_inf,temp_inf; @@ -709,20 +686,14 @@ void NEB_spin::print_status() ty = (fm[i][2]*sp[i][0] - fm[i][0]*sp[i][2]); tz = (fm[i][0]*sp[i][1] - fm[i][1]*sp[i][0]); tnorm2 += tx*tx + ty*ty + tz*tz; - temp_inf = MAX(fabs(tx),fabs(ty)); temp_inf = MAX(fabs(tz),temp_inf); local_norm_inf = MAX(temp_inf,local_norm_inf); - } double fmaxreplica; - //MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); MPI_Allreduce(&tnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots); - //double fnorminf = update->minimize->fnorm_inf(); - //double fmaxatom; - //MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots); double fnorminf = 0.0; MPI_Allreduce(&local_norm_inf,&fnorminf,1,MPI_DOUBLE,MPI_MAX,world); double fmaxatom; @@ -730,7 +701,6 @@ void NEB_spin::print_status() if (verbose) { freplica = new double[nreplica]; - //MPI_Allgather(&fnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots); MPI_Allgather(&tnorm2,1,MPI_DOUBLE,&freplica[0],1,MPI_DOUBLE,roots); fmaxatomInRepl = new double[nreplica]; MPI_Allgather(&fnorminf,1,MPI_DOUBLE,&fmaxatomInRepl[0],1,MPI_DOUBLE,roots); diff --git a/src/REPLICA/neb_spin.h b/src/REPLICA/neb_spin.h index b579793fe6..5988c04a3a 100644 --- a/src/REPLICA/neb_spin.h +++ b/src/REPLICA/neb_spin.h @@ -14,7 +14,6 @@ #ifdef COMMAND_CLASS CommandStyle(neb/spin,NEB_spin) -//CommandStyle(neb,NEB_spin) #else -- GitLab From 71a622724042151cb2c861a69ce1209cc0de58ff Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 14 Mar 2019 15:43:50 -0600 Subject: [PATCH 0244/1243] Optimize KOKKOS package for small system sizes --- src/KOKKOS/atom_vec_atomic_kokkos.cpp | 5 ++- src/KOKKOS/domain_kokkos.cpp | 12 ++++++ src/KOKKOS/npair_kokkos.cpp | 58 ++++++++++++++++----------- src/KOKKOS/npair_kokkos.h | 30 +++++++------- src/KOKKOS/pair_kokkos.h | 13 +++--- src/neighbor.h | 4 +- 6 files changed, 73 insertions(+), 49 deletions(-) diff --git a/src/KOKKOS/atom_vec_atomic_kokkos.cpp b/src/KOKKOS/atom_vec_atomic_kokkos.cpp index 6aba49e5f3..e3c1bee956 100644 --- a/src/KOKKOS/atom_vec_atomic_kokkos.cpp +++ b/src/KOKKOS/atom_vec_atomic_kokkos.cpp @@ -24,7 +24,7 @@ using namespace LAMMPS_NS; -#define DELTA 10000 +#define DELTA 10 /* ---------------------------------------------------------------------- */ @@ -55,7 +55,8 @@ AtomVecAtomicKokkos::AtomVecAtomicKokkos(LAMMPS *lmp) : AtomVecKokkos(lmp) void AtomVecAtomicKokkos::grow(int n) { - if (n == 0) nmax += DELTA; + int step = MAX(DELTA,nmax*0.01); + if (n == 0) nmax += step; else nmax = n; atomKK->nmax = nmax; if (nmax < 0 || nmax > MAXSMALLINT) diff --git a/src/KOKKOS/domain_kokkos.cpp b/src/KOKKOS/domain_kokkos.cpp index d9c1332778..4cf3e6ab52 100644 --- a/src/KOKKOS/domain_kokkos.cpp +++ b/src/KOKKOS/domain_kokkos.cpp @@ -17,6 +17,7 @@ #include "error.h" #include "force.h" #include "kspace.h" +#include "kokkos.h" using namespace LAMMPS_NS; @@ -339,6 +340,17 @@ struct DomainPBCFunctor { void DomainKokkos::pbc() { + + if (lmp->kokkos->exchange_comm_classic) { + + // reduce GPU data movement + + atomKK->sync(Host,X_MASK|V_MASK|MASK_MASK|IMAGE_MASK); + Domain::pbc(); + atomKK->modified(Host,X_MASK|V_MASK|MASK_MASK|IMAGE_MASK); + return; + } + double *lo,*hi,*period; int nlocal = atomKK->nlocal; diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index 5e1b7b0414..f2e73ac6e6 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -15,6 +15,7 @@ #include "atom_kokkos.h" #include "atom_masks.h" #include "domain_kokkos.h" +#include "update.h" #include "neighbor_kokkos.h" #include "nbin_kokkos.h" #include "nstencil.h" @@ -27,6 +28,16 @@ namespace LAMMPS_NS { template NPairKokkos::NPairKokkos(LAMMPS *lmp) : NPair(lmp) { + // use 1D view for scalars to reduce GPU memory operations + + d_scalars = typename AT::t_int_1d("neighbor:scalars",2); + h_scalars = HAT::t_int_1d("neighbor:scalars_mirror",2); + + d_resize = Kokkos::subview(d_scalars,0); + d_new_maxneighs = Kokkos::subview(d_scalars,1); + + h_resize = Kokkos::subview(h_scalars,0); + h_new_maxneighs = Kokkos::subview(h_scalars,1); } /* ---------------------------------------------------------------------- @@ -84,27 +95,30 @@ template void NPairKokkos::copy_stencil_info() { NPair::copy_stencil_info(); - nstencil = ns->nstencil; - int maxstencil = ns->get_maxstencil(); - - if (maxstencil > k_stencil.extent(0)) - k_stencil = DAT::tdual_int_1d("neighlist:stencil",maxstencil); - for (int k = 0; k < maxstencil; k++) - k_stencil.h_view(k) = ns->stencil[k]; - k_stencil.modify(); - k_stencil.sync(); - if (GHOST) { - if (maxstencil > k_stencilxyz.extent(0)) - k_stencilxyz = DAT::tdual_int_1d_3("neighlist:stencilxyz",maxstencil); - for (int k = 0; k < maxstencil; k++) { - k_stencilxyz.h_view(k,0) = ns->stencilxyz[k][0]; - k_stencilxyz.h_view(k,1) = ns->stencilxyz[k][1]; - k_stencilxyz.h_view(k,2) = ns->stencilxyz[k][2]; + if (neighbor->last_setup_bins == update->ntimestep) { + // copy stencil to device as it may have changed + + int maxstencil = ns->get_maxstencil(); + + if (maxstencil > k_stencil.extent(0)) + k_stencil = DAT::tdual_int_1d("neighlist:stencil",maxstencil); + for (int k = 0; k < maxstencil; k++) + k_stencil.h_view(k) = ns->stencil[k]; + k_stencil.modify(); + k_stencil.sync(); + if (GHOST) { + if (maxstencil > k_stencilxyz.extent(0)) + k_stencilxyz = DAT::tdual_int_1d_3("neighlist:stencilxyz",maxstencil); + for (int k = 0; k < maxstencil; k++) { + k_stencilxyz.h_view(k,0) = ns->stencilxyz[k][0]; + k_stencilxyz.h_view(k,1) = ns->stencilxyz[k][1]; + k_stencilxyz.h_view(k,2) = ns->stencilxyz[k][2]; + } + k_stencilxyz.modify(); + k_stencilxyz.sync(); } - k_stencilxyz.modify(); - k_stencilxyz.sync(); } } @@ -157,7 +171,7 @@ void NPairKokkos::build(NeighList *list_) bboxhi,bboxlo, domain->xperiodic,domain->yperiodic,domain->zperiodic, domain->xprd_half,domain->yprd_half,domain->zprd_half, - skin); + skin,d_resize,h_resize,d_new_maxneighs,h_new_maxneighs); k_cutneighsq.sync(); k_ex1_type.sync(); @@ -185,8 +199,7 @@ void NPairKokkos::build(NeighList *list_) data.h_new_maxneighs() = list->maxneighs; data.h_resize() = 0; - Kokkos::deep_copy(data.resize, data.h_resize); - Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); + Kokkos::deep_copy(d_scalars, h_scalars); #ifdef KOKKOS_ENABLE_CUDA #define BINS_PER_BLOCK 2 const int factor = atoms_per_bin<64?2:1; @@ -245,10 +258,9 @@ void NPairKokkos::build(NeighList *list_) } } } - deep_copy(data.h_resize, data.resize); + Kokkos::deep_copy(h_scalars, d_scalars); if(data.h_resize()) { - deep_copy(data.h_new_maxneighs, data.new_maxneighs); list->maxneighs = data.h_new_maxneighs() * 1.2; list->d_neighbors = typename ArrayTypes::t_neighbors_2d("neighbors", list->d_neighbors.extent(0), list->maxneighs); data.neigh_list.d_neighbors = list->d_neighbors; diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h index 6986fc5849..edf3d2a59f 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -95,6 +95,8 @@ namespace LAMMPS_NS { template class NPairKokkos : public NPair { + typedef ArrayTypes AT; + public: NPairKokkos(class LAMMPS *); ~NPairKokkos() {} @@ -105,6 +107,12 @@ class NPairKokkos : public NPair { private: int newton_pair; + typename AT::t_int_1d d_scalars; + HAT::t_int_1d h_scalars; + typename AT::t_int_scalar d_resize; + typename AT::t_int_scalar d_new_maxneighs; + HAT::t_int_scalar h_resize; + HAT::t_int_scalar h_new_maxneighs; // data from Neighbor class @@ -251,7 +259,11 @@ class NeighborKokkosExecute const X_FLOAT *_bboxhi, const X_FLOAT* _bboxlo, const int & _xperiodic, const int & _yperiodic, const int & _zperiodic, const int & _xprd_half, const int & _yprd_half, const int & _zprd_half, - const X_FLOAT _skin): + const X_FLOAT _skin, + const typename AT::t_int_scalar _resize, + const typename ArrayTypes::t_int_scalar _h_resize, + const typename AT::t_int_scalar _new_maxneighs, + const typename ArrayTypes::t_int_scalar _h_new_maxneighs): neigh_list(_neigh_list), cutneighsq(_cutneighsq), bincount(_bincount),c_bincount(_bincount),bins(_bins),c_bins(_bins), atom2bin(_atom2bin),c_atom2bin(_atom2bin), @@ -272,7 +284,8 @@ class NeighborKokkosExecute ex_mol_intra(_ex_mol_intra), xperiodic(_xperiodic),yperiodic(_yperiodic),zperiodic(_zperiodic), xprd_half(_xprd_half),yprd_half(_yprd_half),zprd_half(_zprd_half), - skin(_skin) { + skin(_skin),resize(_resize),h_resize(_h_resize), + new_maxneighs(_new_maxneighs),h_new_maxneighs(_h_new_maxneighs) { if (molecular == 2) moltemplate = 1; else moltemplate = 0; @@ -280,20 +293,7 @@ class NeighborKokkosExecute bboxlo[0] = _bboxlo[0]; bboxlo[1] = _bboxlo[1]; bboxlo[2] = _bboxlo[2]; bboxhi[0] = _bboxhi[0]; bboxhi[1] = _bboxhi[1]; bboxhi[2] = _bboxhi[2]; - resize = typename AT::t_int_scalar(Kokkos::view_alloc("NeighborKokkosFunctor::resize",Kokkos::WithoutInitializing)); -#ifndef KOKKOS_USE_CUDA_UVM - h_resize = Kokkos::create_mirror_view(resize); -#else - h_resize = resize; -#endif h_resize() = 1; - new_maxneighs = typename AT:: - t_int_scalar(Kokkos::view_alloc("NeighborKokkosFunctor::new_maxneighs",Kokkos::WithoutInitializing)); -#ifndef KOKKOS_USE_CUDA_UVM - h_new_maxneighs = Kokkos::create_mirror_view(new_maxneighs); -#else - h_new_maxneighs = new_maxneighs; -#endif h_new_maxneighs() = neigh_list.maxneighs; }; diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 8758b2f03c..63502a1e27 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -274,7 +274,7 @@ struct PairComputeFunctor { const X_FLOAT ytmp = c.x(i,1); const X_FLOAT ztmp = c.x(i,2); const int itype = c.type(i); - + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; @@ -388,13 +388,12 @@ struct PairComputeFunctor { const int lastatom = firstatom + atoms_per_team < inum ? firstatom + atoms_per_team : inum; Kokkos::parallel_for(Kokkos::TeamThreadRange(team, firstatom, lastatom), [&] (const int &ii) { - const int i = list.d_ilist[ii]; const X_FLOAT xtmp = c.x(i,0); const X_FLOAT ytmp = c.x(i,1); const X_FLOAT ztmp = c.x(i,2); const int itype = c.type(i); - + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; @@ -875,14 +874,14 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable PairComputeFunctor ff(fpair,list); atoms_per_team = GetTeamSize(ff, atoms_per_team, vector_length); Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); - else Kokkos::parallel_for(policy,ff); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(Kokkos::Experimental::require(policy,Kokkos::Experimental::WorkItemProperty::HintLightWeight),ff,ev); + else Kokkos::parallel_for(Kokkos::Experimental::require(policy,Kokkos::Experimental::WorkItemProperty::HintLightWeight),ff); } else { PairComputeFunctor ff(fpair,list); atoms_per_team = GetTeamSize(ff, atoms_per_team, vector_length); Kokkos::TeamPolicy > policy(list->inum,atoms_per_team,vector_length); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(policy,ff,ev); - else Kokkos::parallel_for(policy,ff); + if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(Kokkos::Experimental::require(policy,Kokkos::Experimental::WorkItemProperty::HintLightWeight),ff,ev); + else Kokkos::parallel_for(Kokkos::Experimental::require(policy,Kokkos::Experimental::WorkItemProperty::HintLightWeight),ff); } } else { if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { diff --git a/src/neighbor.h b/src/neighbor.h index 751beeae4b..6184731b61 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -126,6 +126,8 @@ class Neighbor : protected Pointers { bigint memory_usage(); + bigint last_setup_bins; // step of last neighbor::setup_bins() call + protected: int me,nprocs; int firsttime; // flag for calling init_styles() only once @@ -139,8 +141,6 @@ class Neighbor : protected Pointers { int fix_check; // # of fixes that induce reneigh int *fixchecklist; // which fixes to check - bigint last_setup_bins; // step of last neighbor::setup_bins() call - double triggersq; // trigger = build when atom moves this dist double **xhold; // atom coords at last neighbor build -- GitLab From 179026dd44108f78b600ecb957be5039bdcb7c82 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 14 Mar 2019 17:13:12 -0600 Subject: [PATCH 0245/1243] Reduce GPU data movement in npair_kokkos --- src/KOKKOS/npair_kokkos.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index f2e73ac6e6..ecf4b2d5a5 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -187,7 +187,18 @@ void NPairKokkos::build(NeighList *list_) k_bincount.sync(); k_bins.sync(); k_atom2bin.sync(); - atomKK->sync(Device,X_MASK|RADIUS_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK); + + if (atom->molecular) { + if (exclude) + atomKK->sync(Device,X_MASK|RADIUS_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK); + else + atomKK->sync(Device,X_MASK|RADIUS_MASK|TYPE_MASK|TAG_MASK|SPECIAL_MASK); + } else { + if (exclude) + atomKK->sync(Device,X_MASK|RADIUS_MASK|TYPE_MASK|MASK_MASK); + else + atomKK->sync(Device,X_MASK|RADIUS_MASK|TYPE_MASK); + } data.special_flag[0] = special_flag[0]; data.special_flag[1] = special_flag[1]; -- GitLab From 3abfce01caab080498564eaa99b093af04bfc57f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 14:06:03 -0400 Subject: [PATCH 0246/1243] remove diverged fix wall/gran/omp --- src/Purge.list | 3 + src/USER-OMP/fix_wall_gran_omp.cpp | 186 ----------------------------- src/USER-OMP/fix_wall_gran_omp.h | 38 ------ 3 files changed, 3 insertions(+), 224 deletions(-) delete mode 100644 src/USER-OMP/fix_wall_gran_omp.cpp delete mode 100644 src/USER-OMP/fix_wall_gran_omp.h diff --git a/src/Purge.list b/src/Purge.list index 6cfc580c25..430f842d7c 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -24,6 +24,9 @@ style_nstencil.h style_ntopo.h # other auto-generated files lmpinstalledpkgs.h +# removed on 15 March 2019 +fix_wall_gran_omp.h +fix_wall_gran_omp.cpp # renamed on 25 September 2018 compute_smd_triangle_mesh_vertices.h compute_smd_triangle_mesh_vertices.cpp diff --git a/src/USER-OMP/fix_wall_gran_omp.cpp b/src/USER-OMP/fix_wall_gran_omp.cpp deleted file mode 100644 index d45e748b6a..0000000000 --- a/src/USER-OMP/fix_wall_gran_omp.cpp +++ /dev/null @@ -1,186 +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 -#include "fix_wall_gran_omp.h" -#include "atom.h" -#include "memory.h" -#include "neighbor.h" -#include "update.h" - -using namespace LAMMPS_NS; -using namespace FixConst; - -enum{XPLANE=0,YPLANE=1,ZPLANE=2,ZCYLINDER,REGION}; // XYZ PLANE need to be 0,1,2 -enum{HOOKE,HOOKE_HISTORY,HERTZ_HISTORY,BONDED_HISTORY}; - -#define BIG 1.0e20 - -/* ---------------------------------------------------------------------- */ - -FixWallGranOMP::FixWallGranOMP(LAMMPS *lmp, int narg, char **arg) : - FixWallGran(lmp, narg, arg) { } - -/* ---------------------------------------------------------------------- */ - -void FixWallGranOMP::post_force(int vflag) -{ - double vwall[3]; - - // if just reneighbored: - // update rigid body masses for owned atoms if using FixRigid - // body[i] = which body atom I is in, -1 if none - // mass_body = mass of each rigid body - - if (neighbor->ago == 0 && fix_rigid) { - int tmp; - const int * const body = (const int * const) fix_rigid->extract("body",tmp); - double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); - if (atom->nmax > nmax) { - memory->destroy(mass_rigid); - nmax = atom->nmax; - memory->create(mass_rigid,nmax,"wall/gran:mass_rigid"); - } - const int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - if (body[i] >= 0) mass_rigid[i] = mass_body[body[i]]; - else mass_rigid[i] = 0.0; - } - } - - // set position of wall to initial settings and velocity to 0.0 - // if wiggle or shear, set wall position and velocity accordingly - - double wlo = lo; - double whi = hi; - vwall[0] = vwall[1] = vwall[2] = 0.0; - if (wiggle) { - double arg = omega * (update->ntimestep - time_origin) * dt; - if (wallstyle == axis) { - wlo = lo + amplitude - amplitude*cos(arg); - whi = hi + amplitude - amplitude*cos(arg); - } - vwall[axis] = amplitude*omega*sin(arg); - } else if (wshear) vwall[axis] = vshear; - - // loop over all my atoms - // rsq = distance from wall - // dx,dy,dz = signed distance from wall - // for rotating cylinder, reset vwall based on particle position - // skip atom if not close enough to wall - // if wall was set to NULL, it's skipped since lo/hi are infinity - // compute force and torque on atom if close enough to wall - // via wall potential matched to pair potential - // set shear if pair potential stores history - - double * const * const x = atom->x; - double * const * const v = atom->v; - double * const * const f = atom->f; - double * const * const omega = atom->omega; - double * const * const torque = atom->torque; - double * const radius = atom->radius; - double * const rmass = atom->rmass; - const int * const mask = atom->mask; - const int nlocal = atom->nlocal; - - shearupdate = (update->setupflag) ? 0 : 1; - - int i; -#if defined(_OPENMP) -#pragma omp parallel for private(i) default(none) firstprivate(vwall,wlo,whi) -#endif - for (i = 0; i < nlocal; i++) { - - if (mask[i] & groupbit) { - double dx,dy,dz,del1,del2,delxy,delr,rsq; - double rwall = 0.0; - - dx = dy = dz = 0.0; - - if (wallstyle == XPLANE) { - del1 = x[i][0] - wlo; - del2 = whi - x[i][0]; - if (del1 < del2) dx = del1; - else dx = -del2; - } else if (wallstyle == YPLANE) { - del1 = x[i][1] - wlo; - del2 = whi - x[i][1]; - if (del1 < del2) dy = del1; - else dy = -del2; - } else if (wallstyle == ZPLANE) { - del1 = x[i][2] - wlo; - del2 = whi - x[i][2]; - if (del1 < del2) dz = del1; - else dz = -del2; - } else if (wallstyle == ZCYLINDER) { - delxy = sqrt(x[i][0]*x[i][0] + x[i][1]*x[i][1]); - delr = cylradius - delxy; - if (delr > radius[i]) { - dz = cylradius; - rwall = 0.0; - } else { - dx = -delr/delxy * x[i][0]; - dy = -delr/delxy * x[i][1]; - rwall = (delxy < cylradius) ? -2*cylradius : 2*cylradius; - if (wshear && axis != 2) { - vwall[0] += vshear * x[i][1]/delxy; - vwall[1] += -vshear * x[i][0]/delxy; - vwall[2] = 0.0; - } - } - } - - rsq = dx*dx + dy*dy + dz*dz; - - if (rsq > radius[i]*radius[i]) { - if (history) - for (int j = 0; j < sheardim; j++) - shearone[i][j] = 0.0; - - } else { - - // meff = effective mass of sphere - // if I is part of rigid body, use body mass - - double meff = rmass[i]; - if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; - - // invoke sphere/wall interaction - - if (pairstyle == HOOKE) - hooke(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff); - else if (pairstyle == HOOKE_HISTORY) - hooke_history(rsq,dx,dy,dz,vwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i]); - else if (pairstyle == HERTZ_HISTORY) - hertz_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i]); - else if (pairstyle == BONDED_HISTORY) - bonded_history(rsq,dx,dy,dz,vwall,rwall,v[i],f[i], - omega[i],torque[i],radius[i],meff,shearone[i]); - } - } - } -} - -/* ---------------------------------------------------------------------- */ - -void FixWallGranOMP::post_force_respa(int vflag, int ilevel, int iloop) -{ - if (ilevel == nlevels_respa-1) post_force(vflag); -} diff --git a/src/USER-OMP/fix_wall_gran_omp.h b/src/USER-OMP/fix_wall_gran_omp.h deleted file mode 100644 index cd26a7b40a..0000000000 --- a/src/USER-OMP/fix_wall_gran_omp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- 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 FIX_CLASS - -FixStyle(wall/gran/omp,FixWallGranOMP) - -#else - -#ifndef LMP_FIX_WALL_GRAN_OMP_H -#define LMP_FIX_WALL_GRAN_OMP_H - -#include "fix_wall_gran.h" - -namespace LAMMPS_NS { - -class FixWallGranOMP : public FixWallGran { - - public: - FixWallGranOMP(class LAMMPS *, int, char **); - virtual void post_force(int); - virtual void post_force_respa(int, int, int); -}; - -} - -#endif -#endif -- GitLab From 3f0f2383b460d219bdadb36773b9d70f6097f2ea Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 14:18:04 -0400 Subject: [PATCH 0247/1243] fix spelling and record false positives --- doc/src/pair_granular.txt | 21 ++++++++++----------- doc/utils/sphinx-config/false_positives.txt | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 7a58435a83..5854a8faf6 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -111,8 +111,7 @@ For the {hertz/material} model, the force is given by: Here, \(E_\{eff\} = E = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\}\) is the effective Young's modulus, with \(\nu_i, \nu_j \) the Poisson ratios of the particles of types {i} and {j}. Note that -if the elastic and shear moduli of the -two particles are the same, the {hertz/material} +if the elastic modulus and the shear modulus of the two particles are the same, the {hertz/material} model is equivalent to the {hertz} model with \(k_N = 4/3 E_\{eff\}\) The {dmt} model corresponds to the "(Derjaguin-Muller-Toporov)"_#DMT1975 cohesive model, @@ -188,7 +187,7 @@ for all models except {jkr}, for which it is given implicitly according to \(del In this case, \eta_\{n0\}\ is in units of 1/({time}*{distance}). The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the -damping coefficient specified as part of the normal model is intepreted +damping coefficient specified as part of the normal model is interpreted as a restitution coefficient \(e\). The damping constant \(\eta_n\) is given by: \begin\{equation\} @@ -242,7 +241,7 @@ The tangential damping force \(\mathbf\{F\}_\mathrm\{t,damp\}\) is given by: \mathbf\{F\}_\mathrm\{t,damp\} = -\eta_t \mathbf\{v\}_\{t,rel\} \end\{equation\} -The tangetial damping prefactor \(\eta_t\) is calculated by scaling the normal damping \(\eta_n\) (see above): +The tangential damping prefactor \(\eta_t\) is calculated by scaling the normal damping \(\eta_n\) (see above): \begin\{equation\} \eta_t = -x_\{\gamma,t\} \eta_n \end\{equation\} @@ -292,7 +291,7 @@ duration of the contact: \mathbf\{\xi\} = \int_\{t0\}^t \mathbf\{v\}_\{t,rel\}(\tau) \mathrm\{d\}\tau \end\{equation\} -This accumlated tangential displacement must be adjusted to account for changes +This accumulated tangential displacement must be adjusted to account for changes in the frame of reference of the contacting pair of particles during contact. This occurs due to the overall motion of the contacting particles in a rigid-body-like fashion during the duration of the contact. There are two modes of motion @@ -304,7 +303,7 @@ made by rotating the accumulated displacement into the plane that is tangential to the contact vector at each step, or equivalently removing any component of the tangential displacement that lies along \(\mathbf\{n\}\), and rescaling to preserve the magnitude. -This folllows the discussion in "Luding"_#Luding2008, see equation 17 and +This follows the discussion in "Luding"_#Luding2008, see equation 17 and relevant discussion in that work: \begin\{equation\} @@ -350,7 +349,7 @@ see discussion above. To match the Mindlin solution, one should set \(k_t = 8G\) \(G\) is the shear modulus, related to Young's modulus \(E\) by \(G = E/(2(1+\nu))\), where \(\nu\) is Poisson's ratio. This can also be achieved by specifying {NULL} for \(k_t\), in which case a normal contact model that specifies material parameters \(E\) and \(\nu\) is required (e.g. {hertz/material}, -{dmt} or {jkr}). In this case, mixing of shear moduli for different particle types {i} and {j} is done according +{dmt} or {jkr}). In this case, mixing of the shear modulus for different particle types {i} and {j} is done according to: \begin\{equation\} 1/G = 2(2-\nu_i)(1+\nu_i)/E_i + 2(2-\nu_j)(1+\nu_j)/E_j @@ -381,7 +380,7 @@ If the {rolling} keyword is not specified, the model defaults to {none}. For {rolling sds}, rolling friction is computed via a spring-dashpot-slider, using a 'pseudo-force' formulation, as detailed by "Luding"_#Luding2008. Unlike the formulation in "Marshall"_#Marshall2009, this allows for the required adjustment of -rolling displacement due to changes in the frame of referenece of the contacting pair. +rolling displacement due to changes in the frame of reference of the contacting pair. The rolling pseudo-force is computed analogously to the tangential force: \begin\{equation\} @@ -487,7 +486,7 @@ Finally, the twisting torque on each particle is given by: :line LAMMPS automatically sets pairwise cutoff values for {pair_style granular} based on particle radii (and in the case -of {jkr} pulloff distances). In the vast majority of situations, this is adequate. +of {jkr} pull-off distances). In the vast majority of situations, this is adequate. However, a cutoff value can optionally be appended to the {pair_style granular} command to specify a global cutoff (i.e. a cutoff for all atom types). Additionally, the optional {cutoff} keyword can be passed to the {pair_coeff} command, followed by a cutoff value. @@ -533,7 +532,7 @@ Mixing of coefficients is carried out using geometric averaging for most quantities, e.g. if friction coefficient for type 1-type 1 interactions is set to \(\mu_1\), and friction coefficient for type 2-type 2 interactions is set to \(\mu_2\), the friction coefficient for type1-type2 interactions -is computed as \(\sqrt\{\mu_1\mu_2\}\) (unless explictly specified to +is computed as \(\sqrt\{\mu_1\mu_2\}\) (unless explicitly specified to a different value by a {pair_coeff 1 2 ...} command. The exception to this is elastic modulus, only applicable to {hertz/material}, {dmt} and {jkr} normal contact models. In that case, the effective elastic modulus is computed as: @@ -542,7 +541,7 @@ contact models. In that case, the effective elastic modulus is computed as: E_\{eff,ij\} = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\} \end\{equation\} -If the {i-j} coefficients \(E_\{ij\}\) and \(\nu_\{ij\}\) are explictly specified, +If the {i-j} coefficients \(E_\{ij\}\) and \(\nu_\{ij\}\) are explicitly specified, the effective modulus is computed as: \begin\{equation\} diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 08e106f6d7..c55378826e 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -155,6 +155,8 @@ ba Babadi backcolor Baczewski +Bagi +Bagnold Bal balancer Balankura @@ -343,6 +345,7 @@ Cij cis civ clearstore +Cleary Clebsch clemson Clermont @@ -369,6 +372,7 @@ Coeff CoefficientN coeffs Coeffs +cohesionless Coker Colberg coleman @@ -442,6 +446,7 @@ cuda Cuda CUDA CuH +Cummins Curk customIDs cutbond @@ -485,6 +490,7 @@ darkturquoise darkviolet Das Dasgupta +dashpot dat datafile datums @@ -521,6 +527,7 @@ Dequidt der derekt Derjagin +Derjaguin Derlet Deserno Destree @@ -1065,6 +1072,7 @@ Hyoungki hyperdynamics hyperradius hyperspherical +hysteretic Ibanez ibar ibm @@ -1124,6 +1132,7 @@ interconvert interial interlayer intermolecular +Interparticle interstitials Intr intra @@ -1141,6 +1150,7 @@ IPython Isele isenthalpic ish +Ishida iso isodemic isoenergetic @@ -1430,6 +1440,7 @@ logfile logfreq logicals Lomdahl +Lond lookups Lookups LoopVar @@ -1444,6 +1455,7 @@ lsfftw ltbbmalloc lubricateU lucy +Luding Lussetti Lustig lwsock @@ -1482,6 +1494,7 @@ manybody MANYBODY Maras Marrink +Marroquin Marsaglia Marseille Martyna @@ -1493,6 +1506,7 @@ masstotal Masuhiro Matchett Materias +mathbf matlab matplotlib Mattox @@ -1580,6 +1594,7 @@ Mie Mikami Militzer Minary +Mindlin mincap mingw minima @@ -2260,6 +2275,7 @@ rg Rg Rhaphson rheological +rheology rhodo Rhodo rhodopsin @@ -2572,6 +2588,7 @@ Tait taitwater Tajkhorshid Tamaskovics +Tanaka tanh Tartakovsky taskset @@ -2659,6 +2676,7 @@ tokyo tol toolchain topologies +Toporov Torder torsions Tosi @@ -2703,6 +2721,7 @@ Tsrd Tstart tstat Tstop +Tsuji Tsuzuki tt Tt -- GitLab From 8845a1a0ae8847a175a36520e88363574276cca4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 14:20:10 -0400 Subject: [PATCH 0248/1243] whitespace cleanup (remove ctrl-m, trailing whitespace) --- doc/src/pair_granular.txt | 1332 ++++++++++++++++++------------------- 1 file changed, 666 insertions(+), 666 deletions(-) diff --git a/doc/src/pair_granular.txt b/doc/src/pair_granular.txt index 5854a8faf6..73c2bbdd3b 100644 --- a/doc/src/pair_granular.txt +++ b/doc/src/pair_granular.txt @@ -1,666 +1,666 @@ - - - -"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c - -:link(lws,http://lammps.sandia.gov) -:link(ld,Manual.html) -:link(lc,Commands_all.html) - -:line - -pair_style granular command :h3 - -[Syntax:] - -pair_style granular cutoff :pre - -cutoff = global cutoff (optional). See discussion below. :l -:ule - -[Examples:] - -pair_style granular -pair_coeff * * hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 :pre - -pair_style granular -pair_coeff * * hertz 1000.0 50.0 tangential mindlin NULL 1.0 0.4 :pre - -pair_style granular -pair_coeff * * hertz/material 1e8 0.3 tangential mindlin_rescale NULL 1.0 0.4 damping tsuji :pre - -pair_style granular -pair_coeff 1 1 jkr 1000.0 50.0 tangential mindlin 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair_coeff 2 2 hertz 200.0 20.0 tangential linear_history 300.0 1.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre - -pair_style granular -pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 0.5 0.5 rolling sds 500.0 200.0 0.5 twisting marshall -pair_coeff 2 2 dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall -pair_coeff 1 2 dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre - -[Description:] - -The {granular} styles support a variety of options for the normal, tangential, rolling and twisting -forces resulting from contact between two granular particles. This expands on the options offered -by the "pair gran/*"_pair_gran.html pair styles. The total computed forces and torques are the -sum of various models selected for the normal, tangential, rolling and twisting modes of motion. - -All model choices and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. -Unlike e.g. "pair gran/hooke"_pair_gran.html, coefficient values are not global, but can be set to different values for -different combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. -If the contact model choice is the same for two particle types, the mixing for the cross-coefficients can be carried out -automatically. This is shown in the second example, where model choices are the same for type 1 - type 1 as for type 2 - type2 -interactions, but coefficients are different. In this case, the coefficients for type 2 - type interactions can be -determined from mixing rules discussed below. -For additional flexibility, coefficients as well as model forms can vary between particle types, -as shown in the third example: -type 1- type 1 interactions are based on a Hertzian normal contact model and 2-2 interactions are based on a DMT cohesive model (see below). -In that example, 1-1 and 2-2 interactions have different model forms, in which case -mixing of coefficients cannot be determined, so 1-2 interactions must be explicitly defined via the -{pair_coeff 1 2} command, otherwise an error would result. - -:line - -The first required keyword for the {pair_coeff} command is the normal contact model. Currently supported options -for normal contact models and their required arguments are: - -{hooke} : \(k_n\), \(\eta_\{n0\}\) (or \(e\)) -{hertz} : \(k_n\), \(\eta_\{n0\}\) (or \(e\)) -{hertz/material} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\) -{dmt} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\), \(\gamma\) -{jkr} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\), \(\gamma\) :ol - -Here, \(k_n\) is spring stiffness (with units that depend on model choice, see below); -\(\eta_\{n0\}\) is a damping prefactor (or, in its place a coefficient of restitution -\(e\), depending on the choice of damping mode, see below); E is Young's modulus -in units of {force}/{length}^2, i.e. {pressure}; \(\nu\) is Poisson's ratio -and \(\gamma\) is a surface energy density, in units of {energy}/{length}^2. - -For the {hooke} model, the normal, elastic component of force acting on particle {i} due to -contact with particle {j} is given by: -\begin\{equation\} -\mathbf\{F\}_\{ne, Hooke\} = k_N \delta_\{ij\} \mathbf\{n\} -\end\{equation\} - -Where \(\delta = R_i + R_j - \|\mathbf\{r\}_\{ij\}\|\) is the particle overlap, -\(R_i, R_j\) are the particle radii, -\(\mathbf\{r\}_\{ij\} = \mathbf\{r\}_i - \mathbf\{r\}_j\) is the vector separating the -two particle centers (note the i-j ordering so that \(F_\{ne\}\) is positive for repulsion), -and \(\mathbf\{n\} = \frac\{\mathbf\{r\}_\{ij\}\}\{\|\mathbf\{r\}_\{ij\}\|\}\). -Therefore, for {hooke}, the units of the spring constant \(k_n\) are {force}/{distance}, -or equivalently {mass}/{time^2}. - -For the {hertz} model, the normal component of force is given by: -\begin\{equation\} -\mathbf\{F\}_\{ne, Hertz\} = k_N R_\{eff\}^\{1/2\}\delta_\{ij\}^\{3/2\} \mathbf\{n\} -\end\{equation\} - -Here, \(R_\{eff\} = \frac\{R_i R_j\}\{R_i + R_j\}\) is the effective radius, denoted for simplicity as {R} from here on. -For {hertz}, the units of the spring constant \(k_n\) are {force}/{length}^2, or equivalently -{pressure}. - -For the {hertz/material} model, the force is given by: -\begin\{equation\} -\mathbf\{F\}_\{ne, Hertz/material\} = \frac\{4\}\{3\} E_\{eff\} R_\{eff\}^\{1/2\}\delta_\{ij\}^\{3/2\} \mathbf\{n\} -\end\{equation\} - -Here, \(E_\{eff\} = E = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\}\) -is the effective Young's modulus, -with \(\nu_i, \nu_j \) the Poisson ratios of the particles of types {i} and {j}. Note that -if the elastic modulus and the shear modulus of the two particles are the same, the {hertz/material} -model is equivalent to the {hertz} model with \(k_N = 4/3 E_\{eff\}\) - -The {dmt} model corresponds to the "(Derjaguin-Muller-Toporov)"_#DMT1975 cohesive model, -where the force is simply Hertz with an additional attractive cohesion term: -\begin\{equation\} -\mathbf\{F\}_\{ne, dmt\} = \left(\frac\{4\}\{3\} E R^\{1/2\}\delta_\{ij\}^\{3/2\} - 4\pi\gamma R\right)\mathbf\{n\} -\end\{equation\} - -The {jkr} model is the "(Johnson-Kendall-Roberts)"_#JKR1971 model, where the force is computed as: -\begin\{equation\} -\label\{eq:force_jkr\} -\mathbf\{F\}_\{ne, jkr\} = \left(\frac\{4Ea^3\}\{3R\} - 2\pi a^2\sqrt\{\frac\{4\gamma E\}\{\pi a\}\}\right)\mathbf\{n\} -\end\{equation\} - -Here, {a} is the radius of the contact zone, related to the overlap \(\delta\) according to: -\begin\{equation\} -\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\} -\end\{equation\} - -LAMMPS internally inverts the equation above to solve for {a} in terms of \(\delta\), then solves for -the force in the previous equation. Additionally, note that the JKR model allows for a tensile force beyond -contact (i.e. for \(\delta < 0\)), up to a maximum of \(3\pi\gamma R\) (also known as -the 'pull-off' force). -Note that this is a hysteretic effect, where particles that are not contacting initially -will not experience force until they come into contact \(\delta \geq 0\); as they move apart -and (\(\delta < 0\)), they experience a tensile force up to \(3\pi\gamma R\), -at which point they lose contact. - -:line - -In addition, the normal force is augmented by a damping term of the following -general form: - -\begin\{equation\} -\mathbf\{F\}_\{n,damp\} = -\eta_n \mathbf\{v\}_\{n,rel\} -\end\{equation\} - -Here, \(\mathbf\{v\}_\{n,rel\} = (\mathbf\{v\}_j - \mathbf\{v\}_i) \cdot \mathbf\{n\}\) -is the component of relative velocity along \(\mathbf\{n\}\). - -The optional {damping} keyword to the {pair_coeff} command followed by a keyword -determines the model form of the damping factor \(\eta_n\), and the interpretation -of the \(\eta_\{n0\}\) or \(e\) coefficients specified as part of the normal contact -model settings. The {damping} keyword and corresponding -model form selection may be appended anywhere in the {pair coeff} command. -Note that the choice of damping model affects both the -normal and tangential damping (and depending on other settings, potentially also the twisting damping). -The options for the damping model currently supported are: - -{velocity} -{viscoelastic} -{tsuji} :ol - -If the {damping} keyword is not specified, the {viscoelastic} model is used by default. - -For {damping velocity}, the normal damping is simply equal to the user-specified damping -coefficient in the {normal} model: - -\begin\{equation\} -\eta_n = \eta_\{n0\}\ -\end\{equation\} - -Here, \(\gamma_n\) is the damping coefficient specified for the normal contact model, in units of {mass}/{time}, - -The {damping viscoelastic} model is based on the viscoelastic treatment of "(Brilliantov et al)"_#Brill1996, -where the normal damping is given by: -\begin\{equation\} -\eta_n = \eta_\{n0\}\ a m_\{eff\} -\end\{equation\} - -Here, \(m_\{eff\} = m_i m_j/(m_i + m_j)\) is the effective mass, {a} is the contact radius, given by \(a =\sqrt\{R\delta\}\) -for all models except {jkr}, for which it is given implicitly according to \(delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\). -In this case, \eta_\{n0\}\ is in units of 1/({time}*{distance}). - -The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the -damping coefficient specified as part of the normal model is interpreted -as a restitution coefficient \(e\). The damping constant \(\eta_n\) is given by: - -\begin\{equation\} -\eta_n = \alpha (m_\{eff\}k_n)^\{1/2\} -\end\{equation\} - -For normal contact models based on material parameters, \(k_n = 4/3Ea\). -The parameter \(\alpha\) is related to the restitution coefficient {e} according to: - -\begin\{equation\} -\alpha = 1.2728-4.2783e+11.087e^2-22.348e^3+27.467e^4-18.022e^5+4.8218e^6 -\end\{equation\} - -The dimensionless coefficient of restitution \(e\) specified as part of the normal contact model -parameters should be between 0 and 1, but no error check is performed on this. - -The total normal force is computed as the sum of the elastic and damping components: - -\begin\{equation\} -\mathbf\{F\}_n = \mathbf\{F\}_\{ne\} + \mathbf\{F\}_\{n,damp\} -\end\{equation\} - - :line - -The {pair_coeff} command also requires specification -of the tangential contact model. The required keyword {tangential} is expected, followed by the model -choice and associated parameters. Currently supported tangential model choices and their -expected parameters are as follows: - -{linear_nohistory} : \(x_\{\gamma,t\}\), \(\mu_s\) -{linear_history} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) -{mindlin} : \(k_t\) or NULL, \(x_\{\gamma,t\}\), \(\mu_s\) -{mindlin_rescale} : \(k_t\) or NULL, \(x_\{\gamma,t\}\), \(\mu_s\) :ol - -Here, \(x_\{\gamma,t\}\) is a dimensionless multiplier for the normal damping \(\eta_n\) -that determines the magnitude of the -tangential damping, \(\mu_t\) is the tangential (or sliding) friction -coefficient, and \(k_t\) is the tangential stiffness coefficient. - -For {tangential linear_nohistory}, a simple velocity-dependent Coulomb friction criterion is used, -which mimics the behavior -of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: - -\begin\{equation\} -\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|\mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} -\end\{equation\} - -The tangential damping force \(\mathbf\{F\}_\mathrm\{t,damp\}\) is given by: - -\begin\{equation\} -\mathbf\{F\}_\mathrm\{t,damp\} = -\eta_t \mathbf\{v\}_\{t,rel\} -\end\{equation\} - -The tangential damping prefactor \(\eta_t\) is calculated by scaling the normal damping \(\eta_n\) (see above): -\begin\{equation\} -\eta_t = -x_\{\gamma,t\} \eta_n -\end\{equation\} - -The normal damping prefactor \(\eta_n\) is determined by the choice of the {damping} keyword, as discussed above. -Thus, the {damping} keyword also affects the tangential damping. -The parameter \(x_\{\gamma,t\}\) is a scaling coefficient. Several works in the literature use -\(x_\{\gamma,t\} = 1\) ("Marshall"_#Marshall2009, "Tsuji et al"_#Tsuji1992, "Silbert et al"_#Silbert2001). -The relative tangential velocity at the point of contact is given by -\(\mathbf\{v\}_\{t, rel\} = \mathbf\{v\}_\{t\} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf\{n\}\), -where \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_r - \mathbf\{v\}_r\cdot\mathbf\{n\}\), -\(\mathbf\{v\}_r = \mathbf\{v\}_j - \mathbf\{v\}_i\). The direction of the applied force is -\(\mathbf\{t\} = \mathbf\{v_\{t,rel\}\}/\|\mathbf\{v_\{t,rel\}\}\|\). - -The normal force value \(F_\{n0\}\) used to compute the critical force -depends on the form of the contact model. For non-cohesive models -({hertz}, {hertz/material}, {hooke}), it is given by the magnitude of the normal force: - -\begin\{equation\} -F_\{n0\} = \|\mathbf\{F\}_n\| -\end\{equation\} - -For cohesive models such as {jkr} and {dmt}, the critical force is adjusted so that the critical tangential -force approaches \(\mu_t F_\{pulloff\}\), see "Marshall"_#Marshall2009, equation 43, and "Thornton"_#Thornton1991. -For both models, \(F_\{n0\}\) takes the form: - -\begin\{equation\} -F_\{n0\} = \|\mathbf\{F\}_ne + 2 F_\{pulloff\}\| -\end\{equation\} - -Where \(F_\{pulloff\} = 3\pi \gamma R \) for {jkr}, and \(F_\{pulloff\} = 4\pi \gamma R \) for {dmt}. - -The remaining tangential options all use accumulated tangential displacement (i.e. contact history). This -is discussed below in the context of the {linear_history} option, but the same treatment of the -accumulated displacement applies to the other options as well. - -For {tangential linear_history}, the tangential force is given by: - -\begin\{equation\} -\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|-k_t\mathbf\{\xi\} + \mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} -\end\{equation\} - -Here, \(\mathbf\{\xi\}\) is the tangential displacement accumulated during the entire -duration of the contact: - -\begin\{equation\} -\mathbf\{\xi\} = \int_\{t0\}^t \mathbf\{v\}_\{t,rel\}(\tau) \mathrm\{d\}\tau -\end\{equation\} - -This accumulated tangential displacement must be adjusted to account for changes -in the frame of reference -of the contacting pair of particles during contact. This occurs due to the overall motion of the contacting particles -in a rigid-body-like fashion during the duration of the contact. There are two modes of motion -that are relevant: the 'tumbling' rotation of the contacting pair, which changes the orientation of the -plane in which tangential displacement occurs; and 'spinning' rotation of the contacting pair -about the vector connecting their centers of mass (\(\mathbf\{n\}\)). -Corrections due to the former mode of motion are -made by rotating the accumulated displacement into the plane that is tangential -to the contact vector at each step, -or equivalently removing any component of the tangential displacement -that lies along \(\mathbf\{n\}\), and rescaling to preserve the magnitude. -This follows the discussion in "Luding"_#Luding2008, see equation 17 and -relevant discussion in that work: - -\begin\{equation\} -\mathbf\{\xi\} = \left(\mathbf\{\xi'\} - (\mathbf\{n\} \cdot \mathbf\{\xi'\})\mathbf\{n\}\right) \frac\{\|\mathbf\{\xi'\}\|\}\{\|\mathbf\{\xi'\}\| - \mathbf\{n\}\cdot\mathbf\{\xi'\}\} -\label\{eq:rotate_displacements\} -\end\{equation\} - -Here, \(\mathbf\{\xi'\}\) is the accumulated displacement prior to the current time step and -\(\mathbf\{\xi\}\) is the corrected displacement. Corrections to the displacement -due to the second mode of motion described above (rotations about \(\mathbf\{n\}\)) -are not currently implemented, but are expected to be minor for most simulations. - -Furthermore, when the tangential force exceeds the critical force, -the tangential displacement is re-scaled to match the value for the critical force (see "Luding"_#Luding2008, -equation 20 and related discussion): - -\begin\{equation\} -\mathbf\{\xi\} = -\frac\{1\}\{k_t\}\left(\mu_t F_\{n0\}\mathbf\{t\} + \mathbf\{F\}_\{t,damp\}\right) -\end\{equation\} - -The tangential force is added to the total normal force (elastic plus damping) to produce the total force -on the particle. The tangential force also acts at the contact point (defined as the center of the overlap region) -to induce a torque on each particle according to: - -\begin\{equation\} -\mathbf\{\tau\}_i = -(R_i - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t -\end\{equation\} - -\begin\{equation\} -\mathbf\{\tau\}_j = -(R_j - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t -\end\{equation\} - -For {tangential mindlin}, the "Mindlin"_#Mindlin1949 no-slip solution is used, which differs from the {linear_history} -option by an additional factor of {a}, the radius of the contact region. The tangential force is given by: - -\begin\{equation\} -\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|-k_t a \mathbf\{\xi\} + \mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} -\end\{equation\} - -Here, {a} is the radius of the contact region, given by \(a = \delta R\) for all normal contact models, -except for {jkr}, where it is given implicitly by \(\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\), -see discussion above. To match the Mindlin solution, one should set \(k_t = 8G\), where -\(G\) is the shear modulus, related to Young's modulus \(E\) by \(G = E/(2(1+\nu))\), where \(\nu\) -is Poisson's ratio. This can also be achieved by specifying {NULL} for \(k_t\), in which case -a normal contact model that specifies material parameters \(E\) and \(\nu\) is required (e.g. {hertz/material}, -{dmt} or {jkr}). In this case, mixing of the shear modulus for different particle types {i} and {j} is done according -to: -\begin\{equation\} -1/G = 2(2-\nu_i)(1+\nu_i)/E_i + 2(2-\nu_j)(1+\nu_j)/E_j -\end\{equation\} - -The {mindlin_rescale} option uses the same form as {mindlin}, but the magnitude of the tangential -displacement is re-scaled as the contact unloads, i.e. if \(a < a_\{t_\{n-1\}\}\): -\begin\{equation\} -\mathbf\{\xi\} = \mathbf\{\xi_\{t_\{n-1\}\}\} \frac\{a\}\{a_\{t_\{n-1\}\}\} -\end\{equation\} - -Here, \(t_\{n-1\}\) indicates the value at the previous time step. This rescaling -accounts for the fact that a decrease in the contact area upon unloading leads to the contact -being unable to support the previous tangential loading, and spurious energy is created -without the rescaling above ("Walton"_#WaltonPC ). See also discussion in "Thornton et al, 2013"_#Thornton2013 -, particularly equation 18(b) of that work and associated discussion. - -:line - -The optional {rolling} keyword enables rolling friction, which resists pure rolling -motion of particles. The options currently supported are: - -{none} -{sds} : \(k_\{roll\}\), \(\gamma_\{roll\}\), \(\mu_\{roll\}\) :ol - -If the {rolling} keyword is not specified, the model defaults to {none}. - -For {rolling sds}, rolling friction is computed via a spring-dashpot-slider, using a -'pseudo-force' formulation, as detailed by "Luding"_#Luding2008. Unlike the formulation -in "Marshall"_#Marshall2009, this allows for the required adjustment of -rolling displacement due to changes in the frame of reference of the contacting pair. -The rolling pseudo-force is computed analogously to the tangential force: - -\begin\{equation\} -\mathbf\{F\}_\{roll,0\} = k_\{roll\} \mathbf\{\xi\}_\{roll\} - \gamma_\{roll\} \mathbf\{v\}_\{roll\} -\end\{equation\} - -Here, \(\mathbf\{v\}_\{roll\} = -R(\mathbf\{\Omega\}_i - \mathbf\{\Omega\}_j) \times \mathbf\{n\}\) is the -relative rolling velocity, as given in "Wang et al"_#Wang2015 and "Luding"_#Luding2008. This differs -from the expressions given by "Kuhn and Bagi"_#Kuhn2004 and used in "Marshall"_#Marshall2009; -see "Wang et al"_#Wang2015 for details. The rolling displacement is given by: - -\begin\{equation\} -\mathbf\{\xi\}_\{roll\} = \int_\{t_0\}^t \mathbf\{v\}_\{roll\} (\tau) \mathrm\{d\} \tau -\end\{equation\} - -A Coulomb friction criterion truncates the rolling pseudo-force if it exceeds a critical value: -\begin\{equation\} -\mathbf\{F\}_\{roll\} = min(\mu_\{roll\} F_\{n,0\}, \|\mathbf\{F\}_\{roll,0\}\|)\mathbf\{k\} -\end\{equation\} - -Here, \(\mathbf\{k\} = \mathbf\{v\}_\{roll\}/\|\mathbf\{v\}_\{roll\}\|\) is the direction of the pseudo-force. -As with tangential displacement, the rolling displacement is rescaled when the critical -force is exceeded, so that the spring length corresponds the critical force. Additionally, the -displacement is adjusted to account for rotations of the frame of reference of the two -contacting particles in a manner analogous to the tangential displacement. - -The rolling pseudo-force does not contribute to the total force on either particle (hence 'pseudo'), -but acts only to induce an equal and opposite torque on each particle, according to: - -\begin\{equation\} -\tau_\{roll,i\} = R_\{eff\} \mathbf\{n\} \times \mathbf\{F\}_\{roll\} -\end\{equation\} - -\begin\{equation\} -\tau_\{roll,j\} = -\tau_\{roll,i\} -\end\{equation\} - -:line - -The optional {twisting} keyword enables twisting friction, which resists -rotation of two contacting particles about the vector \(\mathbf\{n\}\) that connects their -centers. The options currently supported are: - -{none} -{sds} : \(k_\{twist\}\), \(\gamma_\{twist\}\), \(\mu_\{twist\}\) -{marshall} :ol - -If the {twisting} keyword is not specified, the model defaults to {none}. - -For both {twisting sds} and {twisting marshall}, a history-dependent spring-dashpot-slider is used to compute the twisting -torque. Because twisting displacement is a scalar, there is no need to adjust for changes -in the frame of reference due to rotations of the particle pair. The formulation in -"Marshall"_#Marshall2009 therefore provides the most straightforward treatment: - -\begin\{equation\} -\tau_\{twist,0\} = -k_\{twist\}\xi_\{twist\} - \gamma_\{twist\}\Omega_\{twist\} -\end\{equation\} - -Here \(\xi_\{twist\} = \int_\{t_0\}^t \Omega_\{twist\} (\tau) \mathrm\{d\}\tau\) is the twisting -angular displacement, and \(\Omega_\{twist\} = (\mathbf\{\Omega\}_i - \mathbf\{\Omega\}_j) \cdot \mathbf\{n\}\) -is the relative twisting angular velocity. The torque is then truncated according to: - -\begin\{equation\} -\tau_\{twist\} = min(\mu_\{twist\} F_\{n,0\}, \tau_\{twist,0\}) -\end\{equation\} - -Similar to the sliding and rolling displacement, the angular displacement is -rescaled so that it corresponds to the critical value if the twisting torque -exceeds this critical value: - -\begin\{equation\} -\xi_\{twist\} = \frac\{1\}\{k_\{twist\}\} (\mu_\{twist\} F_\{n,0\}sgn(\Omega_\{twist\}) - \gamma_\{twist\}\Omega_\{twist\}) -\end\{equation\} - -For {twisting sds}, the coefficients \(k_\{twist\}, \gamma_\{twist\}\) and \(\mu_\{twist\}\) are -simply the user input parameters that follow the {twisting sds} keywords in the {pair_coeff} command. - -For {twisting_marshall}, the coefficients are expressed in terms of sliding friction coefficients, -as discussed in "Marshall"_#Marshall2009 (see equations 32 and 33 of that work): - -\begin\{equation\} -k_\{twist\} = 0.5k_ta^2 -\end\{equation\} - -\begin\{equation\} -\eta_\{twist\} = 0.5\eta_ta^2 -\end\{equation\} - -\begin\{equation\} -\mu_\{twist\} = \frac\{2\}\{3\}a\mu_t -\end\{equation\} - -Finally, the twisting torque on each particle is given by: - -\begin\{equation\} -\mathbf\{\tau\}_\{twist,i\} = \tau_\{twist\}\mathbf\{n\} -\end\{equation\} - -\begin\{equation\} -\mathbf\{\tau\}_\{twist,j\} = -\mathbf\{\tau\}_\{twist,i\} -\end\{equation\} - -:line - -LAMMPS automatically sets pairwise cutoff values for {pair_style granular} based on particle radii (and in the case -of {jkr} pull-off distances). In the vast majority of situations, this is adequate. -However, a cutoff value can optionally be appended to the {pair_style granular} command to specify -a global cutoff (i.e. a cutoff for all atom types). Additionally, the optional {cutoff} keyword -can be passed to the {pair_coeff} command, followed by a cutoff value. -This will set a pairwise cutoff for the atom types in the {pair_coeff} command. -These options may be useful in some rare cases where the automatic cutoff determination is not sufficient, e.g. -if particle diameters are being modified via the {fix adapt} command. In that case, the global cutoff -specified as part of the {pair_style granular} command is applied to all atom types, unless it is -overridden for a given atom type combination by the {cutoff} value specified in the {pair coeff} command. -If {cutoff} is only specified in the {pair coeff} command and no global -cutoff is appended to the {pair_style granular} command, then LAMMPS will use that cutoff for the specified -atom type combination, and automatically set pairwise cutoffs for the remaining atom types. - -:line - -Styles with a {gpu}, {intel}, {kk}, {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 on the "Speed packages"_Speed_packages.html doc -page. 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 GPU, USER-INTEL, KOKKOS, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the "Build -package"_Build_package.html doc page 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"_Run_options.html when you invoke LAMMPS, or you can use the -"suffix"_suffix.html command in your input script. - -See the "Speed packages"_Speed_packages.html doc page for more -instructions on how to use the accelerated styles effectively. - -:line - -[Mixing, shift, table, tail correction, restart, rRESPA info]: - -The "pair_modify"_pair_modify.html mix, shift, table, and tail options -are not relevant for granular pair styles. - -Mixing of coefficients is carried out using geometric averaging for -most quantities, e.g. if friction coefficient for type 1-type 1 interactions -is set to \(\mu_1\), and friction coefficient for type 2-type 2 interactions -is set to \(\mu_2\), the friction coefficient for type1-type2 interactions -is computed as \(\sqrt\{\mu_1\mu_2\}\) (unless explicitly specified to -a different value by a {pair_coeff 1 2 ...} command. The exception to this is -elastic modulus, only applicable to {hertz/material}, {dmt} and {jkr} normal -contact models. In that case, the effective elastic modulus is computed as: - -\begin\{equation\} -E_\{eff,ij\} = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\} -\end\{equation\} - -If the {i-j} coefficients \(E_\{ij\}\) and \(\nu_\{ij\}\) are explicitly specified, -the effective modulus is computed as: - -\begin\{equation\} -E_\{eff,ij\} = \left(\frac\{1-\nu_\{ij\}^2\}\{E_\{ij\}\} + \frac\{1-\nu_\{ij\}^2\}\{E_\{ij\}\}\right)^\{-1\} -\end\{equation\} - -or - -\begin\{equation\} -E_\{eff,ij\} = \frac\{E_\{ij\}\}\{2(1-\nu_\{ij\})\} -\end\{equation\} - -These pair styles write their information to "binary restart -files"_restart.html, so a pair_style command does not need to be -specified in an input script that reads a restart file. - -These pair styles can only be used via the {pair} keyword of the -"run_style respa"_run_style.html command. They do not support the -{inner}, {middle}, {outer} keywords. - -The single() function of these pair styles returns 0.0 for the energy -of a pairwise interaction, since energy is not conserved in these -dissipative potentials. It also returns only the normal component of -the pairwise interaction force. However, the single() function also -calculates 10 extra pairwise quantities. The first 3 are the -components of the tangential force between particles I and J, acting -on particle I. The 4th is the magnitude of this tangential force. -The next 3 (5-7) are the components of the rolling torque acting on -particle I. The next entry (8) is the magnitude of the rolling torque. -The next entry (9) is the magnitude of the twisting torque acting -about the vector connecting the two particle centers. -The last 3 (10-12) are the components of the vector connecting -the centers of the two particles (x_I - x_J). - -These extra quantities can be accessed by the "compute -pair/local"_compute_pair_local.html command, as {p1}, {p2}, ..., -{p12}. - -:line - -[Restrictions:] - -All the granular pair styles are part of the GRANULAR package. It is -only enabled if LAMMPS was built with that package. See the "Build -package"_Build_package.html doc page for more info. - -These pair styles require that atoms store torque and angular velocity -(omega) as defined by the "atom_style"_atom_style.html. They also -require a per-particle radius is stored. The {sphere} atom style does -all of this. - -This pair style requires you to use the "comm_modify vel -yes"_comm_modify.html command so that velocities are stored by ghost -atoms. - -These pair styles will not restart exactly when using the -"read_restart"_read_restart.html command, though they should provide -statistically similar results. This is because the forces they -compute depend on atom velocities. See the -"read_restart"_read_restart.html command for more details. - -[Related commands:] - -"pair_coeff"_pair_coeff.html -"pair gran/*"_pair_gran.html - -[Default:] - -For the {pair_coeff} settings: {damping viscoelastic}, {rolling none}, {twisting none} - -[References:] - -:link(Brill1996) -[(Brilliantov et al, 1996)] Brilliantov, N. V., Spahn, F., Hertzsch, J. M., & Poschel, T. (1996). -Model for collisions in granular gases. Physical review E, 53(5), 5382. - -:link(Tsuji1992) -[(Tsuji et al, 1992)] Tsuji, Y., Tanaka, T., & Ishida, T. (1992). Lagrangian numerical simulation of plug flow of -cohesionless particles in a horizontal pipe. Powder technology, 71(3), 239-250. - -:link(JKR1971) -[(Johnson et al, 1971)] Johnson, K. L., Kendall, K., & Roberts, A. D. (1971). -Surface energy and the contact of elastic solids. Proc. R. Soc. Lond. A, 324(1558), 301-313. - -:link(DMT1975) -[Derjaguin et al, 1975)] Derjaguin, B. V., Muller, V. M., & Toporov, Y. P. (1975). Effect of contact deformations on the -adhesion of particles. Journal of Colloid and interface science, 53(2), 314-326. - -:link(Luding2008) -[(Luding, 2008)] Luding, S. (2008). Cohesive, frictional powders: contact models for tension. Granular matter, 10(4), 235. - -:link(Marshall2009) -[(Marshall, 2009)] Marshall, J. S. (2009). Discrete-element modeling of particulate aerosol flows. -Journal of Computational Physics, 228(5), 1541-1561. - -:link(Silbert2001) -[(Silbert, 2001)] Silbert, L. E., Ertas, D., Grest, G. S., Halsey, T. C., Levine, D., & Plimpton, S. J. (2001). -Granular flow down an inclined plane: Bagnold scaling and rheology. Physical Review E, 64(5), 051302. - -:link(Kuhn2004) -[(Kuhn and Bagi, 2005)] Kuhn, M. R., & Bagi, K. (2004). Contact rolling and deformation in granular media. -International journal of solids and structures, 41(21), 5793-5820. - -:link(Wang2015) -[(Wang et al, 2015)] Wang, Y., Alonso-Marroquin, F., & Guo, W. W. (2015). -Rolling and sliding in 3-D discrete element models. Particuology, 23, 49-55. - -:link(Thornton1991) -[(Thornton, 1991)] Thornton, C. (1991). Interparticle sliding in the presence of adhesion. -J. Phys. D: Appl. Phys. 24 1942 - -:link(Mindlin1949) -[(Mindlin, 1949)] Mindlin, R. D. (1949). Compliance of elastic bodies in contact. -J. Appl. Mech., ASME 16, 259-268. - -:link(Thornton2013) -[(Thornton et al, 2013)] Thornton, C., Cummins, S. J., & Cleary, P. W. (2013). -An investigation of the comparative behaviour of alternative contact force models -during inelastic collisions. Powder Technology, 233, 30-46. - -:link(WaltonPC) -[(Otis R. Walton)] Walton, O.R., Personal Communication + + + +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +pair_style granular command :h3 + +[Syntax:] + +pair_style granular cutoff :pre + +cutoff = global cutoff (optional). See discussion below. :l +:ule + +[Examples:] + +pair_style granular +pair_coeff * * hooke 1000.0 50.0 tangential linear_nohistory 1.0 0.4 :pre + +pair_style granular +pair_coeff * * hertz 1000.0 50.0 tangential mindlin NULL 1.0 0.4 :pre + +pair_style granular +pair_coeff * * hertz/material 1e8 0.3 tangential mindlin_rescale NULL 1.0 0.4 damping tsuji :pre + +pair_style granular +pair_coeff 1 1 jkr 1000.0 50.0 tangential mindlin 800.0 1.0 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 2 2 hertz 200.0 20.0 tangential linear_history 300.0 1.0 0.1 rolling sds 200.0 100.0 0.1 twisting marshall :pre + +pair_style granular +pair_coeff 1 1 hertz 1000.0 50.0 tangential mindlin 800.0 0.5 0.5 rolling sds 500.0 200.0 0.5 twisting marshall +pair_coeff 2 2 dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall +pair_coeff 1 2 dmt 1000.0 50.0 0.3 10.0 tangential mindlin 800.0 0.5 0.1 roll sds 500.0 200.0 0.1 twisting marshall :pre + +[Description:] + +The {granular} styles support a variety of options for the normal, tangential, rolling and twisting +forces resulting from contact between two granular particles. This expands on the options offered +by the "pair gran/*"_pair_gran.html pair styles. The total computed forces and torques are the +sum of various models selected for the normal, tangential, rolling and twisting modes of motion. + +All model choices and parameters are entered in the "pair_coeff"_pair_coeff.html command, as described below. +Unlike e.g. "pair gran/hooke"_pair_gran.html, coefficient values are not global, but can be set to different values for +different combinations of particle types, as determined by the "pair_coeff"_pair_coeff.html command. +If the contact model choice is the same for two particle types, the mixing for the cross-coefficients can be carried out +automatically. This is shown in the second example, where model choices are the same for type 1 - type 1 as for type 2 - type2 +interactions, but coefficients are different. In this case, the coefficients for type 2 - type interactions can be +determined from mixing rules discussed below. +For additional flexibility, coefficients as well as model forms can vary between particle types, +as shown in the third example: +type 1- type 1 interactions are based on a Hertzian normal contact model and 2-2 interactions are based on a DMT cohesive model (see below). +In that example, 1-1 and 2-2 interactions have different model forms, in which case +mixing of coefficients cannot be determined, so 1-2 interactions must be explicitly defined via the +{pair_coeff 1 2} command, otherwise an error would result. + +:line + +The first required keyword for the {pair_coeff} command is the normal contact model. Currently supported options +for normal contact models and their required arguments are: + +{hooke} : \(k_n\), \(\eta_\{n0\}\) (or \(e\)) +{hertz} : \(k_n\), \(\eta_\{n0\}\) (or \(e\)) +{hertz/material} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\) +{dmt} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\), \(\gamma\) +{jkr} : E, \(\eta_\{n0\}\) (or \(e\)), \(\nu\), \(\gamma\) :ol + +Here, \(k_n\) is spring stiffness (with units that depend on model choice, see below); +\(\eta_\{n0\}\) is a damping prefactor (or, in its place a coefficient of restitution +\(e\), depending on the choice of damping mode, see below); E is Young's modulus +in units of {force}/{length}^2, i.e. {pressure}; \(\nu\) is Poisson's ratio +and \(\gamma\) is a surface energy density, in units of {energy}/{length}^2. + +For the {hooke} model, the normal, elastic component of force acting on particle {i} due to +contact with particle {j} is given by: +\begin\{equation\} +\mathbf\{F\}_\{ne, Hooke\} = k_N \delta_\{ij\} \mathbf\{n\} +\end\{equation\} + +Where \(\delta = R_i + R_j - \|\mathbf\{r\}_\{ij\}\|\) is the particle overlap, +\(R_i, R_j\) are the particle radii, +\(\mathbf\{r\}_\{ij\} = \mathbf\{r\}_i - \mathbf\{r\}_j\) is the vector separating the +two particle centers (note the i-j ordering so that \(F_\{ne\}\) is positive for repulsion), +and \(\mathbf\{n\} = \frac\{\mathbf\{r\}_\{ij\}\}\{\|\mathbf\{r\}_\{ij\}\|\}\). +Therefore, for {hooke}, the units of the spring constant \(k_n\) are {force}/{distance}, +or equivalently {mass}/{time^2}. + +For the {hertz} model, the normal component of force is given by: +\begin\{equation\} +\mathbf\{F\}_\{ne, Hertz\} = k_N R_\{eff\}^\{1/2\}\delta_\{ij\}^\{3/2\} \mathbf\{n\} +\end\{equation\} + +Here, \(R_\{eff\} = \frac\{R_i R_j\}\{R_i + R_j\}\) is the effective radius, denoted for simplicity as {R} from here on. +For {hertz}, the units of the spring constant \(k_n\) are {force}/{length}^2, or equivalently +{pressure}. + +For the {hertz/material} model, the force is given by: +\begin\{equation\} +\mathbf\{F\}_\{ne, Hertz/material\} = \frac\{4\}\{3\} E_\{eff\} R_\{eff\}^\{1/2\}\delta_\{ij\}^\{3/2\} \mathbf\{n\} +\end\{equation\} + +Here, \(E_\{eff\} = E = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\}\) +is the effective Young's modulus, +with \(\nu_i, \nu_j \) the Poisson ratios of the particles of types {i} and {j}. Note that +if the elastic modulus and the shear modulus of the two particles are the same, the {hertz/material} +model is equivalent to the {hertz} model with \(k_N = 4/3 E_\{eff\}\) + +The {dmt} model corresponds to the "(Derjaguin-Muller-Toporov)"_#DMT1975 cohesive model, +where the force is simply Hertz with an additional attractive cohesion term: +\begin\{equation\} +\mathbf\{F\}_\{ne, dmt\} = \left(\frac\{4\}\{3\} E R^\{1/2\}\delta_\{ij\}^\{3/2\} - 4\pi\gamma R\right)\mathbf\{n\} +\end\{equation\} + +The {jkr} model is the "(Johnson-Kendall-Roberts)"_#JKR1971 model, where the force is computed as: +\begin\{equation\} +\label\{eq:force_jkr\} +\mathbf\{F\}_\{ne, jkr\} = \left(\frac\{4Ea^3\}\{3R\} - 2\pi a^2\sqrt\{\frac\{4\gamma E\}\{\pi a\}\}\right)\mathbf\{n\} +\end\{equation\} + +Here, {a} is the radius of the contact zone, related to the overlap \(\delta\) according to: +\begin\{equation\} +\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\} +\end\{equation\} + +LAMMPS internally inverts the equation above to solve for {a} in terms of \(\delta\), then solves for +the force in the previous equation. Additionally, note that the JKR model allows for a tensile force beyond +contact (i.e. for \(\delta < 0\)), up to a maximum of \(3\pi\gamma R\) (also known as +the 'pull-off' force). +Note that this is a hysteretic effect, where particles that are not contacting initially +will not experience force until they come into contact \(\delta \geq 0\); as they move apart +and (\(\delta < 0\)), they experience a tensile force up to \(3\pi\gamma R\), +at which point they lose contact. + +:line + +In addition, the normal force is augmented by a damping term of the following +general form: + +\begin\{equation\} +\mathbf\{F\}_\{n,damp\} = -\eta_n \mathbf\{v\}_\{n,rel\} +\end\{equation\} + +Here, \(\mathbf\{v\}_\{n,rel\} = (\mathbf\{v\}_j - \mathbf\{v\}_i) \cdot \mathbf\{n\}\) +is the component of relative velocity along \(\mathbf\{n\}\). + +The optional {damping} keyword to the {pair_coeff} command followed by a keyword +determines the model form of the damping factor \(\eta_n\), and the interpretation +of the \(\eta_\{n0\}\) or \(e\) coefficients specified as part of the normal contact +model settings. The {damping} keyword and corresponding +model form selection may be appended anywhere in the {pair coeff} command. +Note that the choice of damping model affects both the +normal and tangential damping (and depending on other settings, potentially also the twisting damping). +The options for the damping model currently supported are: + +{velocity} +{viscoelastic} +{tsuji} :ol + +If the {damping} keyword is not specified, the {viscoelastic} model is used by default. + +For {damping velocity}, the normal damping is simply equal to the user-specified damping +coefficient in the {normal} model: + +\begin\{equation\} +\eta_n = \eta_\{n0\}\ +\end\{equation\} + +Here, \(\gamma_n\) is the damping coefficient specified for the normal contact model, in units of {mass}/{time}, + +The {damping viscoelastic} model is based on the viscoelastic treatment of "(Brilliantov et al)"_#Brill1996, +where the normal damping is given by: +\begin\{equation\} +\eta_n = \eta_\{n0\}\ a m_\{eff\} +\end\{equation\} + +Here, \(m_\{eff\} = m_i m_j/(m_i + m_j)\) is the effective mass, {a} is the contact radius, given by \(a =\sqrt\{R\delta\}\) +for all models except {jkr}, for which it is given implicitly according to \(delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\). +In this case, \eta_\{n0\}\ is in units of 1/({time}*{distance}). + +The {tsuji} model is based on the work of "(Tsuji et al)"_#Tsuji1992. Here, the +damping coefficient specified as part of the normal model is interpreted +as a restitution coefficient \(e\). The damping constant \(\eta_n\) is given by: + +\begin\{equation\} +\eta_n = \alpha (m_\{eff\}k_n)^\{1/2\} +\end\{equation\} + +For normal contact models based on material parameters, \(k_n = 4/3Ea\). +The parameter \(\alpha\) is related to the restitution coefficient {e} according to: + +\begin\{equation\} +\alpha = 1.2728-4.2783e+11.087e^2-22.348e^3+27.467e^4-18.022e^5+4.8218e^6 +\end\{equation\} + +The dimensionless coefficient of restitution \(e\) specified as part of the normal contact model +parameters should be between 0 and 1, but no error check is performed on this. + +The total normal force is computed as the sum of the elastic and damping components: + +\begin\{equation\} +\mathbf\{F\}_n = \mathbf\{F\}_\{ne\} + \mathbf\{F\}_\{n,damp\} +\end\{equation\} + + :line + +The {pair_coeff} command also requires specification +of the tangential contact model. The required keyword {tangential} is expected, followed by the model +choice and associated parameters. Currently supported tangential model choices and their +expected parameters are as follows: + +{linear_nohistory} : \(x_\{\gamma,t\}\), \(\mu_s\) +{linear_history} : \(k_t\), \(x_\{\gamma,t\}\), \(\mu_s\) +{mindlin} : \(k_t\) or NULL, \(x_\{\gamma,t\}\), \(\mu_s\) +{mindlin_rescale} : \(k_t\) or NULL, \(x_\{\gamma,t\}\), \(\mu_s\) :ol + +Here, \(x_\{\gamma,t\}\) is a dimensionless multiplier for the normal damping \(\eta_n\) +that determines the magnitude of the +tangential damping, \(\mu_t\) is the tangential (or sliding) friction +coefficient, and \(k_t\) is the tangential stiffness coefficient. + +For {tangential linear_nohistory}, a simple velocity-dependent Coulomb friction criterion is used, +which mimics the behavior +of the {pair gran/hooke} style. The tangential force (\mathbf\{F\}_t\) is given by: + +\begin\{equation\} +\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|\mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} +\end\{equation\} + +The tangential damping force \(\mathbf\{F\}_\mathrm\{t,damp\}\) is given by: + +\begin\{equation\} +\mathbf\{F\}_\mathrm\{t,damp\} = -\eta_t \mathbf\{v\}_\{t,rel\} +\end\{equation\} + +The tangential damping prefactor \(\eta_t\) is calculated by scaling the normal damping \(\eta_n\) (see above): +\begin\{equation\} +\eta_t = -x_\{\gamma,t\} \eta_n +\end\{equation\} + +The normal damping prefactor \(\eta_n\) is determined by the choice of the {damping} keyword, as discussed above. +Thus, the {damping} keyword also affects the tangential damping. +The parameter \(x_\{\gamma,t\}\) is a scaling coefficient. Several works in the literature use +\(x_\{\gamma,t\} = 1\) ("Marshall"_#Marshall2009, "Tsuji et al"_#Tsuji1992, "Silbert et al"_#Silbert2001). +The relative tangential velocity at the point of contact is given by +\(\mathbf\{v\}_\{t, rel\} = \mathbf\{v\}_\{t\} - (R_i\Omega_i + R_j\Omega_j) \times \mathbf\{n\}\), +where \(\mathbf\{v\}_\{t\} = \mathbf\{v\}_r - \mathbf\{v\}_r\cdot\mathbf\{n\}\), +\(\mathbf\{v\}_r = \mathbf\{v\}_j - \mathbf\{v\}_i\). The direction of the applied force is +\(\mathbf\{t\} = \mathbf\{v_\{t,rel\}\}/\|\mathbf\{v_\{t,rel\}\}\|\). + +The normal force value \(F_\{n0\}\) used to compute the critical force +depends on the form of the contact model. For non-cohesive models +({hertz}, {hertz/material}, {hooke}), it is given by the magnitude of the normal force: + +\begin\{equation\} +F_\{n0\} = \|\mathbf\{F\}_n\| +\end\{equation\} + +For cohesive models such as {jkr} and {dmt}, the critical force is adjusted so that the critical tangential +force approaches \(\mu_t F_\{pulloff\}\), see "Marshall"_#Marshall2009, equation 43, and "Thornton"_#Thornton1991. +For both models, \(F_\{n0\}\) takes the form: + +\begin\{equation\} +F_\{n0\} = \|\mathbf\{F\}_ne + 2 F_\{pulloff\}\| +\end\{equation\} + +Where \(F_\{pulloff\} = 3\pi \gamma R \) for {jkr}, and \(F_\{pulloff\} = 4\pi \gamma R \) for {dmt}. + +The remaining tangential options all use accumulated tangential displacement (i.e. contact history). This +is discussed below in the context of the {linear_history} option, but the same treatment of the +accumulated displacement applies to the other options as well. + +For {tangential linear_history}, the tangential force is given by: + +\begin\{equation\} +\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|-k_t\mathbf\{\xi\} + \mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} +\end\{equation\} + +Here, \(\mathbf\{\xi\}\) is the tangential displacement accumulated during the entire +duration of the contact: + +\begin\{equation\} +\mathbf\{\xi\} = \int_\{t0\}^t \mathbf\{v\}_\{t,rel\}(\tau) \mathrm\{d\}\tau +\end\{equation\} + +This accumulated tangential displacement must be adjusted to account for changes +in the frame of reference +of the contacting pair of particles during contact. This occurs due to the overall motion of the contacting particles +in a rigid-body-like fashion during the duration of the contact. There are two modes of motion +that are relevant: the 'tumbling' rotation of the contacting pair, which changes the orientation of the +plane in which tangential displacement occurs; and 'spinning' rotation of the contacting pair +about the vector connecting their centers of mass (\(\mathbf\{n\}\)). +Corrections due to the former mode of motion are +made by rotating the accumulated displacement into the plane that is tangential +to the contact vector at each step, +or equivalently removing any component of the tangential displacement +that lies along \(\mathbf\{n\}\), and rescaling to preserve the magnitude. +This follows the discussion in "Luding"_#Luding2008, see equation 17 and +relevant discussion in that work: + +\begin\{equation\} +\mathbf\{\xi\} = \left(\mathbf\{\xi'\} - (\mathbf\{n\} \cdot \mathbf\{\xi'\})\mathbf\{n\}\right) \frac\{\|\mathbf\{\xi'\}\|\}\{\|\mathbf\{\xi'\}\| - \mathbf\{n\}\cdot\mathbf\{\xi'\}\} +\label\{eq:rotate_displacements\} +\end\{equation\} + +Here, \(\mathbf\{\xi'\}\) is the accumulated displacement prior to the current time step and +\(\mathbf\{\xi\}\) is the corrected displacement. Corrections to the displacement +due to the second mode of motion described above (rotations about \(\mathbf\{n\}\)) +are not currently implemented, but are expected to be minor for most simulations. + +Furthermore, when the tangential force exceeds the critical force, +the tangential displacement is re-scaled to match the value for the critical force (see "Luding"_#Luding2008, +equation 20 and related discussion): + +\begin\{equation\} +\mathbf\{\xi\} = -\frac\{1\}\{k_t\}\left(\mu_t F_\{n0\}\mathbf\{t\} + \mathbf\{F\}_\{t,damp\}\right) +\end\{equation\} + +The tangential force is added to the total normal force (elastic plus damping) to produce the total force +on the particle. The tangential force also acts at the contact point (defined as the center of the overlap region) +to induce a torque on each particle according to: + +\begin\{equation\} +\mathbf\{\tau\}_i = -(R_i - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t +\end\{equation\} + +\begin\{equation\} +\mathbf\{\tau\}_j = -(R_j - 0.5 \delta) \mathbf\{n\} \times \mathbf\{F\}_t +\end\{equation\} + +For {tangential mindlin}, the "Mindlin"_#Mindlin1949 no-slip solution is used, which differs from the {linear_history} +option by an additional factor of {a}, the radius of the contact region. The tangential force is given by: + +\begin\{equation\} +\mathbf\{F\}_t = -min(\mu_t F_\{n0\}, \|-k_t a \mathbf\{\xi\} + \mathbf\{F\}_\mathrm\{t,damp\}\|) \mathbf\{t\} +\end\{equation\} + +Here, {a} is the radius of the contact region, given by \(a = \delta R\) for all normal contact models, +except for {jkr}, where it is given implicitly by \(\delta = a^2/R - 2\sqrt\{\pi \gamma a/E\}\), +see discussion above. To match the Mindlin solution, one should set \(k_t = 8G\), where +\(G\) is the shear modulus, related to Young's modulus \(E\) by \(G = E/(2(1+\nu))\), where \(\nu\) +is Poisson's ratio. This can also be achieved by specifying {NULL} for \(k_t\), in which case +a normal contact model that specifies material parameters \(E\) and \(\nu\) is required (e.g. {hertz/material}, +{dmt} or {jkr}). In this case, mixing of the shear modulus for different particle types {i} and {j} is done according +to: +\begin\{equation\} +1/G = 2(2-\nu_i)(1+\nu_i)/E_i + 2(2-\nu_j)(1+\nu_j)/E_j +\end\{equation\} + +The {mindlin_rescale} option uses the same form as {mindlin}, but the magnitude of the tangential +displacement is re-scaled as the contact unloads, i.e. if \(a < a_\{t_\{n-1\}\}\): +\begin\{equation\} +\mathbf\{\xi\} = \mathbf\{\xi_\{t_\{n-1\}\}\} \frac\{a\}\{a_\{t_\{n-1\}\}\} +\end\{equation\} + +Here, \(t_\{n-1\}\) indicates the value at the previous time step. This rescaling +accounts for the fact that a decrease in the contact area upon unloading leads to the contact +being unable to support the previous tangential loading, and spurious energy is created +without the rescaling above ("Walton"_#WaltonPC ). See also discussion in "Thornton et al, 2013"_#Thornton2013 +, particularly equation 18(b) of that work and associated discussion. + +:line + +The optional {rolling} keyword enables rolling friction, which resists pure rolling +motion of particles. The options currently supported are: + +{none} +{sds} : \(k_\{roll\}\), \(\gamma_\{roll\}\), \(\mu_\{roll\}\) :ol + +If the {rolling} keyword is not specified, the model defaults to {none}. + +For {rolling sds}, rolling friction is computed via a spring-dashpot-slider, using a +'pseudo-force' formulation, as detailed by "Luding"_#Luding2008. Unlike the formulation +in "Marshall"_#Marshall2009, this allows for the required adjustment of +rolling displacement due to changes in the frame of reference of the contacting pair. +The rolling pseudo-force is computed analogously to the tangential force: + +\begin\{equation\} +\mathbf\{F\}_\{roll,0\} = k_\{roll\} \mathbf\{\xi\}_\{roll\} - \gamma_\{roll\} \mathbf\{v\}_\{roll\} +\end\{equation\} + +Here, \(\mathbf\{v\}_\{roll\} = -R(\mathbf\{\Omega\}_i - \mathbf\{\Omega\}_j) \times \mathbf\{n\}\) is the +relative rolling velocity, as given in "Wang et al"_#Wang2015 and "Luding"_#Luding2008. This differs +from the expressions given by "Kuhn and Bagi"_#Kuhn2004 and used in "Marshall"_#Marshall2009; +see "Wang et al"_#Wang2015 for details. The rolling displacement is given by: + +\begin\{equation\} +\mathbf\{\xi\}_\{roll\} = \int_\{t_0\}^t \mathbf\{v\}_\{roll\} (\tau) \mathrm\{d\} \tau +\end\{equation\} + +A Coulomb friction criterion truncates the rolling pseudo-force if it exceeds a critical value: +\begin\{equation\} +\mathbf\{F\}_\{roll\} = min(\mu_\{roll\} F_\{n,0\}, \|\mathbf\{F\}_\{roll,0\}\|)\mathbf\{k\} +\end\{equation\} + +Here, \(\mathbf\{k\} = \mathbf\{v\}_\{roll\}/\|\mathbf\{v\}_\{roll\}\|\) is the direction of the pseudo-force. +As with tangential displacement, the rolling displacement is rescaled when the critical +force is exceeded, so that the spring length corresponds the critical force. Additionally, the +displacement is adjusted to account for rotations of the frame of reference of the two +contacting particles in a manner analogous to the tangential displacement. + +The rolling pseudo-force does not contribute to the total force on either particle (hence 'pseudo'), +but acts only to induce an equal and opposite torque on each particle, according to: + +\begin\{equation\} +\tau_\{roll,i\} = R_\{eff\} \mathbf\{n\} \times \mathbf\{F\}_\{roll\} +\end\{equation\} + +\begin\{equation\} +\tau_\{roll,j\} = -\tau_\{roll,i\} +\end\{equation\} + +:line + +The optional {twisting} keyword enables twisting friction, which resists +rotation of two contacting particles about the vector \(\mathbf\{n\}\) that connects their +centers. The options currently supported are: + +{none} +{sds} : \(k_\{twist\}\), \(\gamma_\{twist\}\), \(\mu_\{twist\}\) +{marshall} :ol + +If the {twisting} keyword is not specified, the model defaults to {none}. + +For both {twisting sds} and {twisting marshall}, a history-dependent spring-dashpot-slider is used to compute the twisting +torque. Because twisting displacement is a scalar, there is no need to adjust for changes +in the frame of reference due to rotations of the particle pair. The formulation in +"Marshall"_#Marshall2009 therefore provides the most straightforward treatment: + +\begin\{equation\} +\tau_\{twist,0\} = -k_\{twist\}\xi_\{twist\} - \gamma_\{twist\}\Omega_\{twist\} +\end\{equation\} + +Here \(\xi_\{twist\} = \int_\{t_0\}^t \Omega_\{twist\} (\tau) \mathrm\{d\}\tau\) is the twisting +angular displacement, and \(\Omega_\{twist\} = (\mathbf\{\Omega\}_i - \mathbf\{\Omega\}_j) \cdot \mathbf\{n\}\) +is the relative twisting angular velocity. The torque is then truncated according to: + +\begin\{equation\} +\tau_\{twist\} = min(\mu_\{twist\} F_\{n,0\}, \tau_\{twist,0\}) +\end\{equation\} + +Similar to the sliding and rolling displacement, the angular displacement is +rescaled so that it corresponds to the critical value if the twisting torque +exceeds this critical value: + +\begin\{equation\} +\xi_\{twist\} = \frac\{1\}\{k_\{twist\}\} (\mu_\{twist\} F_\{n,0\}sgn(\Omega_\{twist\}) - \gamma_\{twist\}\Omega_\{twist\}) +\end\{equation\} + +For {twisting sds}, the coefficients \(k_\{twist\}, \gamma_\{twist\}\) and \(\mu_\{twist\}\) are +simply the user input parameters that follow the {twisting sds} keywords in the {pair_coeff} command. + +For {twisting_marshall}, the coefficients are expressed in terms of sliding friction coefficients, +as discussed in "Marshall"_#Marshall2009 (see equations 32 and 33 of that work): + +\begin\{equation\} +k_\{twist\} = 0.5k_ta^2 +\end\{equation\} + +\begin\{equation\} +\eta_\{twist\} = 0.5\eta_ta^2 +\end\{equation\} + +\begin\{equation\} +\mu_\{twist\} = \frac\{2\}\{3\}a\mu_t +\end\{equation\} + +Finally, the twisting torque on each particle is given by: + +\begin\{equation\} +\mathbf\{\tau\}_\{twist,i\} = \tau_\{twist\}\mathbf\{n\} +\end\{equation\} + +\begin\{equation\} +\mathbf\{\tau\}_\{twist,j\} = -\mathbf\{\tau\}_\{twist,i\} +\end\{equation\} + +:line + +LAMMPS automatically sets pairwise cutoff values for {pair_style granular} based on particle radii (and in the case +of {jkr} pull-off distances). In the vast majority of situations, this is adequate. +However, a cutoff value can optionally be appended to the {pair_style granular} command to specify +a global cutoff (i.e. a cutoff for all atom types). Additionally, the optional {cutoff} keyword +can be passed to the {pair_coeff} command, followed by a cutoff value. +This will set a pairwise cutoff for the atom types in the {pair_coeff} command. +These options may be useful in some rare cases where the automatic cutoff determination is not sufficient, e.g. +if particle diameters are being modified via the {fix adapt} command. In that case, the global cutoff +specified as part of the {pair_style granular} command is applied to all atom types, unless it is +overridden for a given atom type combination by the {cutoff} value specified in the {pair coeff} command. +If {cutoff} is only specified in the {pair coeff} command and no global +cutoff is appended to the {pair_style granular} command, then LAMMPS will use that cutoff for the specified +atom type combination, and automatically set pairwise cutoffs for the remaining atom types. + +:line + +Styles with a {gpu}, {intel}, {kk}, {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 on the "Speed packages"_Speed_packages.html doc +page. 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 GPU, USER-INTEL, KOKKOS, +USER-OMP and OPT packages, respectively. They are only enabled if +LAMMPS was built with those packages. See the "Build +package"_Build_package.html doc page 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"_Run_options.html when you invoke LAMMPS, or you can use the +"suffix"_suffix.html command in your input script. + +See the "Speed packages"_Speed_packages.html doc page for more +instructions on how to use the accelerated styles effectively. + +:line + +[Mixing, shift, table, tail correction, restart, rRESPA info]: + +The "pair_modify"_pair_modify.html mix, shift, table, and tail options +are not relevant for granular pair styles. + +Mixing of coefficients is carried out using geometric averaging for +most quantities, e.g. if friction coefficient for type 1-type 1 interactions +is set to \(\mu_1\), and friction coefficient for type 2-type 2 interactions +is set to \(\mu_2\), the friction coefficient for type1-type2 interactions +is computed as \(\sqrt\{\mu_1\mu_2\}\) (unless explicitly specified to +a different value by a {pair_coeff 1 2 ...} command. The exception to this is +elastic modulus, only applicable to {hertz/material}, {dmt} and {jkr} normal +contact models. In that case, the effective elastic modulus is computed as: + +\begin\{equation\} +E_\{eff,ij\} = \left(\frac\{1-\nu_i^2\}\{E_i\} + \frac\{1-\nu_j^2\}\{E_j\}\right)^\{-1\} +\end\{equation\} + +If the {i-j} coefficients \(E_\{ij\}\) and \(\nu_\{ij\}\) are explicitly specified, +the effective modulus is computed as: + +\begin\{equation\} +E_\{eff,ij\} = \left(\frac\{1-\nu_\{ij\}^2\}\{E_\{ij\}\} + \frac\{1-\nu_\{ij\}^2\}\{E_\{ij\}\}\right)^\{-1\} +\end\{equation\} + +or + +\begin\{equation\} +E_\{eff,ij\} = \frac\{E_\{ij\}\}\{2(1-\nu_\{ij\})\} +\end\{equation\} + +These pair styles write their information to "binary restart +files"_restart.html, so a pair_style command does not need to be +specified in an input script that reads a restart file. + +These pair styles can only be used via the {pair} keyword of the +"run_style respa"_run_style.html command. They do not support the +{inner}, {middle}, {outer} keywords. + +The single() function of these pair styles returns 0.0 for the energy +of a pairwise interaction, since energy is not conserved in these +dissipative potentials. It also returns only the normal component of +the pairwise interaction force. However, the single() function also +calculates 10 extra pairwise quantities. The first 3 are the +components of the tangential force between particles I and J, acting +on particle I. The 4th is the magnitude of this tangential force. +The next 3 (5-7) are the components of the rolling torque acting on +particle I. The next entry (8) is the magnitude of the rolling torque. +The next entry (9) is the magnitude of the twisting torque acting +about the vector connecting the two particle centers. +The last 3 (10-12) are the components of the vector connecting +the centers of the two particles (x_I - x_J). + +These extra quantities can be accessed by the "compute +pair/local"_compute_pair_local.html command, as {p1}, {p2}, ..., +{p12}. + +:line + +[Restrictions:] + +All the granular pair styles are part of the GRANULAR package. It is +only enabled if LAMMPS was built with that package. See the "Build +package"_Build_package.html doc page for more info. + +These pair styles require that atoms store torque and angular velocity +(omega) as defined by the "atom_style"_atom_style.html. They also +require a per-particle radius is stored. The {sphere} atom style does +all of this. + +This pair style requires you to use the "comm_modify vel +yes"_comm_modify.html command so that velocities are stored by ghost +atoms. + +These pair styles will not restart exactly when using the +"read_restart"_read_restart.html command, though they should provide +statistically similar results. This is because the forces they +compute depend on atom velocities. See the +"read_restart"_read_restart.html command for more details. + +[Related commands:] + +"pair_coeff"_pair_coeff.html +"pair gran/*"_pair_gran.html + +[Default:] + +For the {pair_coeff} settings: {damping viscoelastic}, {rolling none}, {twisting none} + +[References:] + +:link(Brill1996) +[(Brilliantov et al, 1996)] Brilliantov, N. V., Spahn, F., Hertzsch, J. M., & Poschel, T. (1996). +Model for collisions in granular gases. Physical review E, 53(5), 5382. + +:link(Tsuji1992) +[(Tsuji et al, 1992)] Tsuji, Y., Tanaka, T., & Ishida, T. (1992). Lagrangian numerical simulation of plug flow of +cohesionless particles in a horizontal pipe. Powder technology, 71(3), 239-250. + +:link(JKR1971) +[(Johnson et al, 1971)] Johnson, K. L., Kendall, K., & Roberts, A. D. (1971). +Surface energy and the contact of elastic solids. Proc. R. Soc. Lond. A, 324(1558), 301-313. + +:link(DMT1975) +[Derjaguin et al, 1975)] Derjaguin, B. V., Muller, V. M., & Toporov, Y. P. (1975). Effect of contact deformations on the +adhesion of particles. Journal of Colloid and interface science, 53(2), 314-326. + +:link(Luding2008) +[(Luding, 2008)] Luding, S. (2008). Cohesive, frictional powders: contact models for tension. Granular matter, 10(4), 235. + +:link(Marshall2009) +[(Marshall, 2009)] Marshall, J. S. (2009). Discrete-element modeling of particulate aerosol flows. +Journal of Computational Physics, 228(5), 1541-1561. + +:link(Silbert2001) +[(Silbert, 2001)] Silbert, L. E., Ertas, D., Grest, G. S., Halsey, T. C., Levine, D., & Plimpton, S. J. (2001). +Granular flow down an inclined plane: Bagnold scaling and rheology. Physical Review E, 64(5), 051302. + +:link(Kuhn2004) +[(Kuhn and Bagi, 2005)] Kuhn, M. R., & Bagi, K. (2004). Contact rolling and deformation in granular media. +International journal of solids and structures, 41(21), 5793-5820. + +:link(Wang2015) +[(Wang et al, 2015)] Wang, Y., Alonso-Marroquin, F., & Guo, W. W. (2015). +Rolling and sliding in 3-D discrete element models. Particuology, 23, 49-55. + +:link(Thornton1991) +[(Thornton, 1991)] Thornton, C. (1991). Interparticle sliding in the presence of adhesion. +J. Phys. D: Appl. Phys. 24 1942 + +:link(Mindlin1949) +[(Mindlin, 1949)] Mindlin, R. D. (1949). Compliance of elastic bodies in contact. +J. Appl. Mech., ASME 16, 259-268. + +:link(Thornton2013) +[(Thornton et al, 2013)] Thornton, C., Cummins, S. J., & Cleary, P. W. (2013). +An investigation of the comparative behaviour of alternative contact force models +during inelastic collisions. Powder Technology, 233, 30-46. + +:link(WaltonPC) +[(Otis R. Walton)] Walton, O.R., Personal Communication -- GitLab From c26068a57ab28093623a0cd571064b531969b0b6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 14:24:45 -0400 Subject: [PATCH 0249/1243] use LAMMPS style indentation for class definitions --- src/GRANULAR/pair_granular.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index ebddc17ade..d85fb5ede9 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -25,8 +25,8 @@ PairStyle(granular,PairGranular) namespace LAMMPS_NS { -class PairGranular : public Pair{ -public: +class PairGranular : public Pair { + public: PairGranular(class LAMMPS *); ~PairGranular(); void compute(int, int); @@ -63,7 +63,7 @@ public: void allocate(); void transfer_history(double*, double*); -private: + private: int size_history; int *history_transfer_factors; -- GitLab From 28607f156ecb77dd0049d03c9fd18e4113fc3726 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 14:25:14 -0400 Subject: [PATCH 0250/1243] use C++ style include headers for accessing C library functions --- src/GRANULAR/pair_granular.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 97cf02676f..5bddd89ea8 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -16,10 +16,10 @@ Dan Bolintineanu (SNL), Ishan Srivastava (SNL), Jeremy Lechman(SNL) Leo Silbert (SNL), Gary Grest (SNL) ----------------------------------------------------------------------- */ -#include -#include -#include -#include +#include +#include +#include +#include #include "pair_granular.h" #include "atom.h" #include "atom_vec.h" -- GitLab From d278cfe230d58959dd89c77e7360d3d819db6486 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 15:10:44 -0400 Subject: [PATCH 0251/1243] remove pointless recursive self-include --- src/GRANULAR/pair_granular.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/GRANULAR/pair_granular.h b/src/GRANULAR/pair_granular.h index d85fb5ede9..4743d271f5 100644 --- a/src/GRANULAR/pair_granular.h +++ b/src/GRANULAR/pair_granular.h @@ -21,7 +21,6 @@ PairStyle(granular,PairGranular) #define LMP_PAIR_GRANULAR_H #include "pair.h" -#include "pair_granular.h" namespace LAMMPS_NS { -- GitLab From 27510f313c1669c0c03105c7e26fcff6eb9b888a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 15:24:16 -0400 Subject: [PATCH 0252/1243] change formatting to closer resemble LAMMPS common source code format style --- src/GRANULAR/fix_wall_gran.cpp | 186 +++++++++++++++------------------ src/GRANULAR/fix_wall_gran.h | 18 ++-- 2 files changed, 91 insertions(+), 113 deletions(-) diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp index 3a929771e9..c63a2c0ba8 100644 --- a/src/GRANULAR/fix_wall_gran.cpp +++ b/src/GRANULAR/fix_wall_gran.cpp @@ -54,7 +54,8 @@ enum{NONE,CONSTANT,EQUAL}; enum {NORMAL_HOOKE, NORMAL_HERTZ, HERTZ_MATERIAL, DMT, JKR}; enum {VELOCITY, VISCOELASTIC, TSUJI}; -enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, TANGENTIAL_MINDLIN, TANGENTIAL_MINDLIN_RESCALE}; +enum {TANGENTIAL_NOHISTORY, TANGENTIAL_HISTORY, + TANGENTIAL_MINDLIN, TANGENTIAL_MINDLIN_RESCALE}; enum {TWIST_NONE, TWIST_SDS, TWIST_MARSHALL}; enum {ROLL_NONE, ROLL_SDS}; @@ -64,7 +65,8 @@ enum {ROLL_NONE, ROLL_SDS}; /* ---------------------------------------------------------------------- */ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), idregion(NULL), history_one(NULL), fix_rigid(NULL), mass_rigid(NULL) + Fix(lmp, narg, arg), idregion(NULL), history_one(NULL), + fix_rigid(NULL), mass_rigid(NULL) { if (narg < 4) error->all(FLERR,"Illegal fix wall/gran command"); @@ -116,28 +118,25 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : kt /= force->nktv2p; } iarg = 10; - } - else { + } else { iarg = 4; damping_model = VISCOELASTIC; roll_model = twist_model = NONE; - while (iarg < narg){ - if (strcmp(arg[iarg], "hooke") == 0){ + while (iarg < narg) { + if (strcmp(arg[iarg], "hooke") == 0) { if (iarg + 2 >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hooke option"); normal_model = NORMAL_HOOKE; normal_coeffs[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += 3; - } - else if (strcmp(arg[iarg], "hertz") == 0){ + } else if (strcmp(arg[iarg], "hertz") == 0) { int num_coeffs = 2; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hertz option"); normal_model = NORMAL_HERTZ; normal_coeffs[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "hertz/material") == 0){ + } else if (strcmp(arg[iarg], "hertz/material") == 0) { int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hertz option"); normal_model = HERTZ_MATERIAL; @@ -147,8 +146,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : normal_coeffs[0] = Emod/(2*(1-poiss))*FOURTHIRDS; normal_coeffs[2] = poiss; iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "dmt") == 0){ + } else if (strcmp(arg[iarg], "dmt") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal fix wall/gran command, not enough parameters provided for Hertz option"); normal_model = DMT; Emod = force->numeric(FLERR,arg[iarg+1]); //E @@ -158,8 +156,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : normal_coeffs[2] = poiss; normal_coeffs[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; - } - else if (strcmp(arg[iarg], "jkr") == 0){ + } else if (strcmp(arg[iarg], "jkr") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal wall/gran command, not enough parameters provided for JKR option"); beyond_contact = 1; normal_model = JKR; @@ -170,67 +167,57 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : normal_coeffs[2] = poiss; normal_coeffs[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; - } - else if (strcmp(arg[iarg], "damping") == 0){ + } else if (strcmp(arg[iarg], "damping") == 0) { if (iarg+1 >= narg) error->all(FLERR, "Illegal wall/gran command, not enough parameters provided for damping model"); - if (strcmp(arg[iarg+1], "velocity") == 0){ + if (strcmp(arg[iarg+1], "velocity") == 0) { damping_model = VELOCITY; iarg += 1; - } - else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ + } else if (strcmp(arg[iarg+1], "viscoelastic") == 0) { damping_model = VISCOELASTIC; iarg += 1; - } - else if (strcmp(arg[iarg+1], "tsuji") == 0){ + } else if (strcmp(arg[iarg+1], "tsuji") == 0) { damping_model = TSUJI; iarg += 1; - } - else error->all(FLERR, "Illegal wall/gran command, unrecognized damping model"); + } else error->all(FLERR, "Illegal wall/gran command, unrecognized damping model"); iarg += 1; - } - else if (strcmp(arg[iarg], "tangential") == 0){ + } else if (strcmp(arg[iarg], "tangential") == 0) { if (iarg + 1 >= narg) error->all(FLERR,"Illegal pair_coeff command, must specify tangential model after 'tangential' keyword"); - if (strcmp(arg[iarg+1], "linear_nohistory") == 0){ + if (strcmp(arg[iarg+1], "linear_nohistory") == 0) { if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); tangential_model = TANGENTIAL_NOHISTORY; tangential_coeffs[0] = 0; tangential_coeffs[1] = force->numeric(FLERR,arg[iarg+2]); //gammat tangential_coeffs[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; - } - else if ((strcmp(arg[iarg+1], "linear_history") == 0) || + } else if ((strcmp(arg[iarg+1], "linear_history") == 0) || (strcmp(arg[iarg+1], "mindlin") == 0) || - (strcmp(arg[iarg+1], "mindlin_rescale") == 0)){ + (strcmp(arg[iarg+1], "mindlin_rescale") == 0)) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); if (strcmp(arg[iarg+1], "linear_history") == 0) tangential_model = TANGENTIAL_HISTORY; else if (strcmp(arg[iarg+1], "mindlin") == 0) tangential_model = TANGENTIAL_MINDLIN; else if (strcmp(arg[iarg+1], "mindlin_rescale") == 0) tangential_model = TANGENTIAL_MINDLIN_RESCALE; if ((tangential_model == TANGENTIAL_MINDLIN || tangential_model == TANGENTIAL_MINDLIN_RESCALE) && - (strcmp(arg[iarg+2], "NULL") == 0)){ - if (normal_model == NORMAL_HERTZ || normal_model == NORMAL_HOOKE){ + (strcmp(arg[iarg+2], "NULL") == 0)) { + if (normal_model == NORMAL_HERTZ || normal_model == NORMAL_HOOKE) { error->all(FLERR, "NULL setting for Mindlin tangential stiffness requires a normal contact model that specifies material properties"); } tangential_coeffs[0] = 4*(2-poiss)*(1+poiss)/Emod; - } - else{ + } else { tangential_coeffs[0] = force->numeric(FLERR,arg[iarg+2]); //kt } tangential_history = 1; tangential_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammat tangential_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; - } - else{ + } else { error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); } - } - else if (strcmp(arg[iarg], "rolling") == 0){ + } else if (strcmp(arg[iarg], "rolling") == 0) { if (iarg + 1 >= narg) error->all(FLERR, "Illegal wall/gran command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ + if (strcmp(arg[iarg+1], "none") == 0) { roll_model = ROLL_NONE; iarg += 2; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ + } else if (strcmp(arg[iarg+1], "sds") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal wall/gran command, not enough parameters provided for rolling model"); roll_model = ROLL_SDS; roll_history = 1; @@ -238,23 +225,19 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : roll_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR roll_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. iarg += 5; - } - else{ + } else { error->all(FLERR, "Illegal wall/gran command, rolling friction model not recognized"); } - } - else if (strcmp(arg[iarg], "twisting") == 0){ + } else if (strcmp(arg[iarg], "twisting") == 0) { if (iarg + 1 >= narg) error->all(FLERR, "Illegal wall/gran command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ + if (strcmp(arg[iarg+1], "none") == 0) { twist_model = TWIST_NONE; iarg += 2; - } - else if (strcmp(arg[iarg+1], "marshall") == 0){ + } else if (strcmp(arg[iarg+1], "marshall") == 0) { twist_model = TWIST_MARSHALL; twist_history = 1; iarg += 2; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ + } else if (strcmp(arg[iarg+1], "sds") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal wall/gran command, not enough parameters provided for twist model"); twist_model = TWIST_SDS; twist_history = 1; @@ -262,19 +245,16 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : twist_coeffs[1] = force->numeric(FLERR,arg[iarg+3]); //gammat twist_coeffs[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; - } - else{ + } else { error->all(FLERR, "Illegal wall/gran command, twisting friction model not recognized"); } - } - else if (strcmp(arg[iarg], "xplane") == 0 || + } else if (strcmp(arg[iarg], "xplane") == 0 || strcmp(arg[iarg], "yplane") == 0 || strcmp(arg[iarg], "zplane") == 0 || strcmp(arg[iarg], "zcylinder") == 0 || - strcmp(arg[iarg], "region") == 0){ + strcmp(arg[iarg], "region") == 0) { break; - } - else{ + } else { error->all(FLERR, "Illegal fix wall/gran command"); } } @@ -352,7 +332,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : vshear = force->numeric(FLERR,arg[iarg+2]); wshear = 1; iarg += 3; - } else if (strcmp(arg[iarg],"store_contacts") == 0){ + } else if (strcmp(arg[iarg],"store_contacts") == 0) { peratom_flag = 1; size_peratom_cols = 8; peratom_freq = 1; @@ -407,7 +387,7 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) : history_one[i][j] = 0.0; } - if (peratom_flag){ + if (peratom_flag) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) for (int m = 0; m < size_peratom_cols; m++) @@ -462,12 +442,12 @@ void FixWallGran::init() if (i < modify->nfix) fix_rigid = modify->fix[i]; tangential_history_index = 0; - if (roll_history){ + if (roll_history) { if (tangential_history) roll_history_index = 3; else roll_history_index = 0; } - if (twist_history){ - if (tangential_history){ + if (twist_history) { + if (tangential_history) { if (roll_history) twist_history_index = 6; else twist_history_index = 3; } @@ -476,17 +456,17 @@ void FixWallGran::init() else twist_history_index = 0; } } - if (normal_model == JKR){ + if (normal_model == JKR) { tangential_history_index += 1; roll_history_index += 1; twist_history_index += 1; } - if (tangential_model == TANGENTIAL_MINDLIN_RESCALE){ + if (tangential_model == TANGENTIAL_MINDLIN_RESCALE) { roll_history_index += 1; twist_history_index += 1; } - if (damping_model == TSUJI){ + if (damping_model == TSUJI) { double cor = normal_coeffs[1]; normal_coeffs[1] = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ 27.467*pow(cor,4)-18.022*pow(cor,5)+ @@ -622,7 +602,7 @@ void FixWallGran::post_force(int /*vflag*/) rsq = dx*dx + dy*dy + dz*dz; double rad; - if (pairstyle == GRANULAR && normal_model == JKR){ + if (pairstyle == GRANULAR && normal_model == JKR) { rad = radius[i] + pulloff_distance(radius[i]); } else @@ -634,8 +614,8 @@ void FixWallGran::post_force(int /*vflag*/) history_one[i][j] = 0.0; } else { - if (pairstyle == GRANULAR && normal_model == JKR && use_history){ - if ((history_one[i][0] == 0) && (rsq > radius[i]*radius[i])){ + if (pairstyle == GRANULAR && normal_model == JKR && use_history) { + if ((history_one[i][0] == 0) && (rsq > radius[i]*radius[i])) { // Particles have not contacted yet, and are outside of contact distance for (j = 0; j < size_history; j++) history_one[i][j] = 0.0; @@ -650,7 +630,7 @@ void FixWallGran::post_force(int /*vflag*/) if (fix_rigid && mass_rigid[i] > 0.0) meff = mass_rigid[i]; // store contact info - if (peratom_flag){ + if (peratom_flag) { array_atom[i][0] = (double)atom->tag[i]; array_atom[i][4] = x[i][0] - dx; array_atom[i][5] = x[i][1] - dy; @@ -764,7 +744,7 @@ void FixWallGran::hooke(double rsq, double dx, double dy, double dz, fy = dy*ccel + fs2; fz = dz*ccel + fs3; - if (peratom_flag){ + if (peratom_flag) { contact[1] = fx; contact[2] = fy; contact[3] = fz; @@ -891,7 +871,7 @@ void FixWallGran::hooke_history(double rsq, double dx, double dy, double dz, f[1] += fy; f[2] += fz; - if (peratom_flag){ + if (peratom_flag) { contact[1] = fx; contact[2] = fy; contact[3] = fz; @@ -1017,7 +997,7 @@ void FixWallGran::hertz_history(double rsq, double dx, double dy, double dz, fy = dy*ccel + fs2; fz = dz*ccel + fs3; - if (peratom_flag){ + if (peratom_flag) { contact[1] = fx; contact[2] = fy; contact[3] = fz; @@ -1056,7 +1036,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, double fs, fs1, fs2, fs3; double tor1,tor2,tor3; - double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3,vrlmag,vrlmaginv; + double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3; //For JKR double R2, coh, F_pulloff, a, a2, E; @@ -1106,7 +1086,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, delta = radsum - r; dR = delta*Reff; - if (normal_model == JKR){ + if (normal_model == JKR) { history[0] = 1.0; E *= THREEQUARTERS; R2=Reff*Reff; @@ -1130,7 +1110,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, else{ knfac = E; //Hooke a = sqrt(dR); - if (normal_model != HOOKE){ + if (normal_model != HOOKE) { Fne *= a; knfac *= a; } @@ -1139,13 +1119,13 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, Fne -= 4*MY_PI*normal_coeffs[3]*Reff; } - if (damping_model == VELOCITY){ + if (damping_model == VELOCITY) { damp_normal = 1; } - else if (damping_model == VISCOELASTIC){ + else if (damping_model == VISCOELASTIC) { damp_normal = a*meff; } - else if (damping_model == TSUJI){ + else if (damping_model == TSUJI) { damp_normal = sqrt(meff*knfac); } @@ -1175,11 +1155,11 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); - if (normal_model == JKR){ + if (normal_model == JKR) { F_pulloff = 3*M_PI*coh*Reff; Fncrit = fabs(Fne + 2*F_pulloff); } - else if (normal_model == DMT){ + else if (normal_model == DMT) { F_pulloff = 4*M_PI*coh*Reff; Fncrit = fabs(Fne + 2*F_pulloff); } @@ -1197,13 +1177,13 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, int thist1 = thist0 + 1; int thist2 = thist1 + 1; - if (tangential_history){ - if (tangential_model == TANGENTIAL_MINDLIN){ + if (tangential_history) { + if (tangential_model == TANGENTIAL_MINDLIN) { k_tangential *= a; } - else if (tangential_model == TANGENTIAL_MINDLIN_RESCALE){ + else if (tangential_model == TANGENTIAL_MINDLIN_RESCALE) { k_tangential *= a; - if (a < history[3]){ //On unloading, rescale the shear displacements + if (a < history[3]) { //On unloading, rescale the shear displacements double factor = a/history[thist2+1]; history[thist0] *= factor; history[thist1] *= factor; @@ -1218,7 +1198,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, if (history_update) { rsht = history[thist0]*nx + history[thist1]*ny + history[thist2]*nz; if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ + if (rsht > 0) { scalefac = shrmag/(shrmag - rsht); //if rhst == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! history[thist0] -= rsht*nx; history[thist1] -= rsht*ny; @@ -1266,7 +1246,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, // Rolling resistance //**************************************** - if (roll_model != ROLL_NONE){ + if (roll_model != ROLL_NONE) { relrot1 = omega[0]; relrot2 = omega[1]; relrot3 = omega[2]; @@ -1277,9 +1257,6 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, vrl1 = Reff*(relrot2*nz - relrot3*ny); //- 0.5*((radj-radi)/radsum)*vtr1; vrl2 = Reff*(relrot3*nx - relrot1*nz); //- 0.5*((radj-radi)/radsum)*vtr2; vrl3 = Reff*(relrot1*ny - relrot2*nx); //- 0.5*((radj-radi)/radsum)*vtr3; - vrlmag = sqrt(vrl1*vrl1+vrl2*vrl2+vrl3*vrl3); - if (vrlmag != 0.0) vrlmaginv = 1.0/vrlmag; - else vrlmaginv = 0.0; int rhist0 = roll_history_index; int rhist1 = rhist0 + 1; @@ -1292,9 +1269,9 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - if (history_update){ + if (history_update) { if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane + if (rolldotn > 0) { //Rotate into tangential plane scalefac = rollmag/(rollmag - rolldotn); history[rhist0] -= rolldotn*nx; history[rhist1] -= rolldotn*ny; @@ -1334,9 +1311,9 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, //**************************************** // Twisting torque, including history effects //**************************************** - if (twist_model != TWIST_NONE){ + if (twist_model != TWIST_NONE) { magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist_model == TWIST_MARSHALL){ + if (twist_model == TWIST_MARSHALL) { k_twist = 0.5*k_tangential*a*a;; //eq 32 of Marshall paper damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a*tangential_coeffs[2]; @@ -1346,7 +1323,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, damp_twist = twist_coeffs[1]; mu_twist = twist_coeffs[2]; } - if (history_update){ + if (history_update) { history[twist_history_index] += magtwist*dt; } magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) @@ -1363,7 +1340,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, fy = ny*Fntot + fs2; fz = nz*Fntot + fs3; - if (peratom_flag){ + if (peratom_flag) { contact[1] = fx; contact[2] = fy; contact[3] = fz; @@ -1381,7 +1358,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, torque[1] -= radius*tor2; torque[2] -= radius*tor3; - if (twist_model != TWIST_NONE){ + if (twist_model != TWIST_NONE) { tortwist1 = magtortwist * nx; tortwist2 = magtortwist * ny; tortwist3 = magtortwist * nz; @@ -1391,7 +1368,7 @@ void FixWallGran::granular(double rsq, double dx, double dy, double dz, torque[2] += tortwist3; } - if (roll_model != ROLL_NONE){ + if (roll_model != ROLL_NONE) { torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr torroll2 = Reff*(nz*fr1 - nx*fr3); torroll3 = Reff*(nx*fr2 - ny*fr1); @@ -1425,7 +1402,7 @@ double FixWallGran::memory_usage() void FixWallGran::grow_arrays(int nmax) { if (use_history) memory->grow(history_one,nmax,size_history,"fix_wall_gran:history_one"); - if (peratom_flag){ + if (peratom_flag) { memory->grow(array_atom,nmax,size_peratom_cols,"fix_wall_gran:array_atom"); } } @@ -1439,7 +1416,7 @@ void FixWallGran::copy_arrays(int i, int j, int /*delflag*/) if (use_history) for (int m = 0; m < size_history; m++) history_one[j][m] = history_one[i][m]; - if (peratom_flag){ + if (peratom_flag) { for (int m = 0; m < size_peratom_cols; m++) array_atom[j][m] = array_atom[i][m]; } @@ -1454,7 +1431,7 @@ void FixWallGran::set_arrays(int i) if (use_history) for (int m = 0; m < size_history; m++) history_one[i][m] = 0; - if (peratom_flag){ + if (peratom_flag) { for (int m = 0; m < size_peratom_cols; m++) array_atom[i][m] = 0; } @@ -1467,11 +1444,11 @@ void FixWallGran::set_arrays(int i) int FixWallGran::pack_exchange(int i, double *buf) { int n = 0; - if (use_history){ + if (use_history) { for (int m = 0; m < size_history; m++) buf[n++] = history_one[i][m]; } - if (peratom_flag){ + if (peratom_flag) { for (int m = 0; m < size_peratom_cols; m++) buf[n++] = array_atom[i][m]; } @@ -1485,11 +1462,11 @@ int FixWallGran::pack_exchange(int i, double *buf) int FixWallGran::unpack_exchange(int nlocal, double *buf) { int n = 0; - if (use_history){ + if (use_history) { for (int m = 0; m < size_history; m++) history_one[nlocal][m] = buf[n++]; } - if (peratom_flag){ + if (peratom_flag) { for (int m = 0; m < size_peratom_cols; m++) array_atom[nlocal][m] = buf[n++]; } @@ -1558,7 +1535,8 @@ void FixWallGran::reset_dt() dt = update->dt; } -double FixWallGran::pulloff_distance(double radius){ +double FixWallGran::pulloff_distance(double radius) +{ double coh, E, a, dist; coh = normal_coeffs[3]; E = normal_coeffs[0]*THREEQUARTERS; diff --git a/src/GRANULAR/fix_wall_gran.h b/src/GRANULAR/fix_wall_gran.h index 07c6c131cf..a81cdcb6c8 100644 --- a/src/GRANULAR/fix_wall_gran.h +++ b/src/GRANULAR/fix_wall_gran.h @@ -46,17 +46,17 @@ class FixWallGran : public Fix { virtual int maxsize_restart(); void reset_dt(); - void hooke(double, double, double, double, double *, - double *, double *, double *, double *, double, double, double*); + void hooke(double, double, double, double, double *, double *, + double *, double *, double *, double, double, double*); void hooke_history(double, double, double, double, double *, - double *, double *, double *, double *, double, double, - double *, double *); - void hertz_history(double, double, double, double, double *, double, - double *, double *, double *, double *, double, double, - double *, double *); + double *, double *, double *, double *, double, + double, double *, double *); + void hertz_history(double, double, double, double, double *, + double, double *, double *, double *, double *, + double, double, double *, double *); void granular(double, double, double, double, double *, double, - double *, double *, double *, double *, double, double, - double *, double *); + double *, double *, double *, double *, double, + double, double *, double *); double pulloff_distance(double); -- GitLab From 05a5ecd4d4cd17f624835602b9b221d70bdf42f6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 15:24:41 -0400 Subject: [PATCH 0253/1243] silence compiler warnings about unused parameters --- src/GRANULAR/pair_granular.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 5bddd89ea8..427bbbd7fa 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -1241,7 +1241,8 @@ void PairGranular::reset_dt() /* ---------------------------------------------------------------------- */ double PairGranular::single(int i, int j, int itype, int jtype, - double rsq, double factor_coul, double factor_lj, double &fforce) + double rsq, double /* factor_coul */, + double /* factor_lj */, double &fforce) { double radi,radj,radsum; double r,rinv,delx,dely,delz, nx, ny, nz, Reff; @@ -1604,7 +1605,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, /* ---------------------------------------------------------------------- */ int PairGranular::pack_forward_comm(int n, int *list, double *buf, - int pbc_flag, int *pbc) + int /* pbc_flag */, int * /* pbc */) { int i,j,m; -- GitLab From 4cd0ea61f24012477e58f2a315f7f280cb245af3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 15:33:15 -0400 Subject: [PATCH 0254/1243] change source code format style to be more like other LAMMPS sources --- src/GRANULAR/pair_granular.cpp | 296 ++++++++++++++------------------- 1 file changed, 122 insertions(+), 174 deletions(-) diff --git a/src/GRANULAR/pair_granular.cpp b/src/GRANULAR/pair_granular.cpp index 427bbbd7fa..b3046788e0 100644 --- a/src/GRANULAR/pair_granular.cpp +++ b/src/GRANULAR/pair_granular.cpp @@ -147,18 +147,18 @@ void PairGranular::compute(int eflag, int vflag) double mi,mj,meff; double relrot1,relrot2,relrot3,vrl1,vrl2,vrl3; - //For JKR + // For JKR double R2, coh, F_pulloff, delta_pulloff, dist_pulloff, a, a2, E; double t0, t1, t2, t3, t4, t5, t6; double sqrt1, sqrt2, sqrt3; - //Rolling + // Rolling double k_roll, damp_roll; double torroll1, torroll2, torroll3; double rollmag, rolldotn, scalefac; double fr, fr1, fr2, fr3; - //Twisting + // Twisting double k_twist, damp_twist, mu_twist; double signtwist, magtwist, magtortwist, Mtcrit; double tortwist1, tortwist2, tortwist3; @@ -180,7 +180,7 @@ void PairGranular::compute(int eflag, int vflag) // body[i] = which body atom I is in, -1 if none // mass_body = mass of each rigid body - if (fix_rigid && neighbor->ago == 0){ + if (fix_rigid && neighbor->ago == 0) { int tmp; int *body = (int *) fix_rigid->extract("body",tmp); double *mass_body = (double *) fix_rigid->extract("masstotal",tmp); @@ -211,7 +211,7 @@ void PairGranular::compute(int eflag, int vflag) ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; - if (use_history){ + if (use_history) { firsttouch = fix_history->firstflag; firsthistory = fix_history->firstvalue; } @@ -224,14 +224,14 @@ void PairGranular::compute(int eflag, int vflag) ztmp = x[i][2]; itype = type[i]; radi = radius[i]; - if (use_history){ + if (use_history) { touch = firsttouch[i]; allhistory = firsthistory[i]; } jlist = firstneigh[i]; jnum = numneigh[i]; - for (jj = 0; jj < jnum; jj++){ + for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; j &= NEIGHMASK; @@ -247,33 +247,30 @@ void PairGranular::compute(int eflag, int vflag) Reff = radi*radj/radsum; touchflag = false; - if (normal_model[itype][jtype] == JKR){ + if (normal_model[itype][jtype] == JKR) { E *= THREEQUARTERS; - if (touch[jj]){ + if (touch[jj]) { R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; a = cbrt(9.0*M_PI*coh*R2/(4*E)); delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); dist_pulloff = radsum-delta_pulloff; touchflag = (rsq < dist_pulloff*dist_pulloff); - } - else{ + } else { touchflag = (rsq < radsum*radsum); } - } - else{ + } else { touchflag = (rsq < radsum*radsum); } - if (!touchflag){ + if (!touchflag) { // unset non-touching neighbors - if (use_history){ + if (use_history) { touch[jj] = 0; history = &allhistory[size_history*jj]; for (int k = 0; k < size_history; k++) history[k] = 0.0; } - } - else{ + } else { r = sqrt(rsq); rinv = 1.0/r; @@ -311,7 +308,7 @@ void PairGranular::compute(int eflag, int vflag) delta = radsum - r; dR = delta*Reff; - if (normal_model[itype][jtype] == JKR){ + if (normal_model[itype][jtype] == JKR) { touch[jj] = 1; R2=Reff*Reff; coh = normal_coeffs[itype][jtype][3]; @@ -330,12 +327,11 @@ void PairGranular::compute(int eflag, int vflag) a2 = a*a; knfac = normal_coeffs[itype][jtype][0]*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - } - else{ + } else { knfac = E; //Hooke Fne = knfac*delta; a = sqrt(dR); - if (normal_model[itype][jtype] != HOOKE){ + if (normal_model[itype][jtype] != HOOKE) { Fne *= a; knfac *= a; } @@ -344,13 +340,11 @@ void PairGranular::compute(int eflag, int vflag) } //Consider restricting Hooke to only have 'velocity' as an option for damping? - if (damping_model[itype][jtype] == VELOCITY){ + if (damping_model[itype][jtype] == VELOCITY) { damp_normal = 1; - } - else if (damping_model[itype][jtype] == VISCOELASTIC){ + } else if (damping_model[itype][jtype] == VISCOELASTIC) { damp_normal = a*meff; - } - else if (damping_model[itype][jtype] == TSUJI){ + } else if (damping_model[itype][jtype] == TSUJI) { damp_normal = sqrt(meff*knfac); } @@ -381,20 +375,18 @@ void PairGranular::compute(int eflag, int vflag) vrel = sqrt(vrel); // If any history is needed: - if (use_history){ + if (use_history) { touch[jj] = 1; history = &allhistory[size_history*jj]; } - if (normal_model[itype][jtype] == JKR){ + if (normal_model[itype][jtype] == JKR) { F_pulloff = 3*M_PI*coh*Reff; Fncrit = fabs(Fne + 2*F_pulloff); - } - else if (normal_model[itype][jtype] == DMT){ + } else if (normal_model[itype][jtype] == DMT) { F_pulloff = 4*M_PI*coh*Reff; Fncrit = fabs(Fne + 2*F_pulloff); - } - else{ + } else { Fncrit = fabs(Fntot); } @@ -404,13 +396,12 @@ void PairGranular::compute(int eflag, int vflag) k_tangential = tangential_coeffs[itype][jtype][0]; damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor; - if (tangential_history){ - if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN){ + if (tangential_history) { + if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN) { k_tangential *= a; - } - else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE){ + } else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) { k_tangential *= a; - if (a < history[3]){ //On unloading, rescale the shear displacements + if (a < history[3]) { //On unloading, rescale the shear displacements double factor = a/history[3]; history[0] *= factor; history[1] *= factor; @@ -422,7 +413,7 @@ void PairGranular::compute(int eflag, int vflag) if (historyupdate) { rsht = history[0]*nx + history[1]*ny + history[2]*nz; if (fabs(rsht) < EPSILON) rsht = 0; - if (rsht > 0){ + if (rsht > 0) { shrmag = sqrt(history[0]*history[0] + history[1]*history[1] + history[2]*history[2]); scalefac = shrmag/(shrmag - rsht); //if rsht == shrmag, contacting pair has rotated 90 deg. in one step, in which case you deserve a crash! @@ -461,8 +452,7 @@ void PairGranular::compute(int eflag, int vflag) fs3 *= Fscrit/fs; } else fs1 = fs2 = fs3 = 0.0; } - } - else{ //Classic pair gran/hooke (no history) + } else{ //Classic pair gran/hooke (no history) fs = meff*damp_tangential*vrel; if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; else Ft = 0.0; @@ -475,7 +465,7 @@ void PairGranular::compute(int eflag, int vflag) // Rolling resistance //**************************************** - if (roll_model[itype][jtype] != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE) { relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -492,9 +482,9 @@ void PairGranular::compute(int eflag, int vflag) int rhist2 = rhist1 + 1; rolldotn = history[rhist0]*nx + history[rhist1]*ny + history[rhist2]*nz; - if (historyupdate){ + if (historyupdate) { if (fabs(rolldotn) < EPSILON) rolldotn = 0; - if (rolldotn > 0){ //Rotate into tangential plane + if (rolldotn > 0) { //Rotate into tangential plane rollmag = sqrt(history[rhist0]*history[rhist0] + history[rhist1]*history[rhist1] + history[rhist2]*history[rhist2]); @@ -540,19 +530,18 @@ void PairGranular::compute(int eflag, int vflag) //**************************************** // Twisting torque, including history effects //**************************************** - if (twist_model[itype][jtype] != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE) { magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist_model[itype][jtype] == TWIST_MARSHALL){ + if (twist_model[itype][jtype] == TWIST_MARSHALL) { k_twist = 0.5*k_tangential*a*a;; //eq 32 of Marshall paper damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a*tangential_coeffs[itype][jtype][2]; - } - else{ + } else { k_twist = twist_coeffs[itype][jtype][0]; damp_twist = twist_coeffs[itype][jtype][1]; mu_twist = twist_coeffs[itype][jtype][2]; } - if (historyupdate){ + if (historyupdate) { history[twist_history_index] += magtwist*dt; } magtortwist = -k_twist*history[twist_history_index] - damp_twist*magtwist;//M_t torque (eq 30) @@ -582,7 +571,7 @@ void PairGranular::compute(int eflag, int vflag) torque[i][1] -= dist_to_contact*tor2; torque[i][2] -= dist_to_contact*tor3; - if (twist_model[itype][jtype] != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE) { tortwist1 = magtortwist * nx; tortwist2 = magtortwist * ny; tortwist3 = magtortwist * nz; @@ -592,7 +581,7 @@ void PairGranular::compute(int eflag, int vflag) torque[i][2] += tortwist3; } - if (roll_model[itype][jtype] != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE) { torroll1 = Reff*(ny*fr3 - nz*fr2); //n cross fr torroll2 = Reff*(nz*fr1 - nx*fr3); torroll3 = Reff*(nx*fr2 - ny*fr1); @@ -612,12 +601,12 @@ void PairGranular::compute(int eflag, int vflag) torque[j][1] -= dist_to_contact*tor2; torque[j][2] -= dist_to_contact*tor3; - if (twist_model[itype][jtype] != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE) { torque[j][0] -= tortwist1; torque[j][1] -= tortwist2; torque[j][2] -= tortwist3; } - if (roll_model[itype][jtype] != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE) { torque[j][0] -= torroll1; torque[j][1] -= torroll2; torque[j][2] -= torroll3; @@ -673,10 +662,9 @@ void PairGranular::allocate() void PairGranular::settings(int narg, char **arg) { - if (narg == 1){ + if (narg == 1) { cutoff_global = force->numeric(FLERR,arg[0]); - } - else{ + } else { cutoff_global = -1; //Will be set based on particle sizes, model choice } @@ -715,23 +703,21 @@ void PairGranular::coeff(int narg, char **arg) damping_model_one = VISCOELASTIC; int iarg = 2; - while (iarg < narg){ - if (strcmp(arg[iarg], "hooke") == 0){ + while (iarg < narg) { + if (strcmp(arg[iarg], "hooke") == 0) { if (iarg + 2 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hooke option"); normal_model_one = HOOKE; normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += 3; - } - else if (strcmp(arg[iarg], "hertz") == 0){ + } else if (strcmp(arg[iarg], "hertz") == 0) { int num_coeffs = 2; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); normal_model_one = HERTZ; normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //kn normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "hertz/material") == 0){ + } else if (strcmp(arg[iarg], "hertz/material") == 0) { int num_coeffs = 3; if (iarg + num_coeffs >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz/material option"); normal_model_one = HERTZ_MATERIAL; @@ -739,8 +725,7 @@ void PairGranular::coeff(int narg, char **arg) normal_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //damping normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio iarg += num_coeffs+1; - } - else if (strcmp(arg[iarg], "dmt") == 0){ + } else if (strcmp(arg[iarg], "dmt") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for Hertz option"); normal_model_one = DMT; normal_coeffs_one[0] = force->numeric(FLERR,arg[iarg+1]); //E @@ -748,8 +733,7 @@ void PairGranular::coeff(int narg, char **arg) normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; - } - else if (strcmp(arg[iarg], "jkr") == 0){ + } else if (strcmp(arg[iarg], "jkr") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for JKR option"); beyond_contact = 1; normal_model_one = JKR; @@ -758,67 +742,57 @@ void PairGranular::coeff(int narg, char **arg) normal_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //Poisson's ratio normal_coeffs_one[3] = force->numeric(FLERR,arg[iarg+4]); //cohesion iarg += 5; - } - else if (strcmp(arg[iarg], "damping") == 0){ + } else if (strcmp(arg[iarg], "damping") == 0) { if (iarg+1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters provided for damping model"); - if (strcmp(arg[iarg+1], "velocity") == 0){ + if (strcmp(arg[iarg+1], "velocity") == 0) { damping_model_one = VELOCITY; iarg += 1; - } - else if (strcmp(arg[iarg+1], "viscoelastic") == 0){ + } else if (strcmp(arg[iarg+1], "viscoelastic") == 0) { damping_model_one = VISCOELASTIC; iarg += 1; - } - else if (strcmp(arg[iarg+1], "tsuji") == 0){ + } else if (strcmp(arg[iarg+1], "tsuji") == 0) { damping_model_one = TSUJI; iarg += 1; - } - else error->all(FLERR, "Illegal pair_coeff command, unrecognized damping model"); + } else error->all(FLERR, "Illegal pair_coeff command, unrecognized damping model"); iarg += 1; - } - else if (strcmp(arg[iarg], "tangential") == 0){ + } else if (strcmp(arg[iarg], "tangential") == 0) { if (iarg + 1 >= narg) error->all(FLERR,"Illegal pair_coeff command, must specify tangential model after 'tangential' keyword"); - if (strcmp(arg[iarg+1], "linear_nohistory") == 0){ + if (strcmp(arg[iarg+1], "linear_nohistory") == 0) { if (iarg + 3 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); tangential_model_one = TANGENTIAL_NOHISTORY; tangential_coeffs_one[0] = 0; tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+2]); //gammat tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+3]); //friction coeff. iarg += 4; - } - else if ((strcmp(arg[iarg+1], "linear_history") == 0) || + } else if ((strcmp(arg[iarg+1], "linear_history") == 0) || (strcmp(arg[iarg+1], "mindlin") == 0) || - (strcmp(arg[iarg+1], "mindlin_rescale") == 0)){ + (strcmp(arg[iarg+1], "mindlin_rescale") == 0)) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for tangential model"); if (strcmp(arg[iarg+1], "linear_history") == 0) tangential_model_one = TANGENTIAL_HISTORY; else if (strcmp(arg[iarg+1], "mindlin") == 0) tangential_model_one = TANGENTIAL_MINDLIN; else if (strcmp(arg[iarg+1], "mindlin_rescale") == 0) tangential_model_one = TANGENTIAL_MINDLIN_RESCALE; tangential_history = 1; if ((tangential_model_one == TANGENTIAL_MINDLIN || tangential_model_one == TANGENTIAL_MINDLIN_RESCALE) && - (strcmp(arg[iarg+2], "NULL") == 0)){ - if (normal_model_one == HERTZ || normal_model_one == HOOKE){ + (strcmp(arg[iarg+2], "NULL") == 0)) { + if (normal_model_one == HERTZ || normal_model_one == HOOKE) { error->all(FLERR, "NULL setting for Mindlin tangential stiffness requires a normal contact model that specifies material properties"); } tangential_coeffs_one[0] = -1; - } - else{ + } else { tangential_coeffs_one[0] = force->numeric(FLERR,arg[iarg+2]); //kt } tangential_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat tangential_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; - } - else{ + } else { error->all(FLERR, "Illegal pair_coeff command, tangential model not recognized"); } - } - else if (strcmp(arg[iarg], "rolling") == 0){ + } else if (strcmp(arg[iarg], "rolling") == 0) { if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ + if (strcmp(arg[iarg+1], "none") == 0) { roll_model_one = ROLL_NONE; iarg += 2; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ + } else if (strcmp(arg[iarg+1], "sds") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for rolling model"); roll_model_one = ROLL_SDS; roll_history = 1; @@ -826,23 +800,19 @@ void PairGranular::coeff(int narg, char **arg) roll_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammaR roll_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //rolling friction coeff. iarg += 5; - } - else{ + } else { error->all(FLERR, "Illegal pair_coeff command, rolling friction model not recognized"); } - } - else if (strcmp(arg[iarg], "twisting") == 0){ + } else if (strcmp(arg[iarg], "twisting") == 0) { if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); - if (strcmp(arg[iarg+1], "none") == 0){ + if (strcmp(arg[iarg+1], "none") == 0) { twist_model_one = TWIST_NONE; iarg += 2; - } - else if (strcmp(arg[iarg+1], "marshall") == 0){ + } else if (strcmp(arg[iarg+1], "marshall") == 0) { twist_model_one = TWIST_MARSHALL; twist_history = 1; iarg += 2; - } - else if (strcmp(arg[iarg+1], "sds") == 0){ + } else if (strcmp(arg[iarg+1], "sds") == 0) { if (iarg + 4 >= narg) error->all(FLERR,"Illegal pair_coeff command, not enough parameters provided for twist model"); twist_model_one = TWIST_SDS; twist_history = 1; @@ -850,16 +820,13 @@ void PairGranular::coeff(int narg, char **arg) twist_coeffs_one[1] = force->numeric(FLERR,arg[iarg+3]); //gammat twist_coeffs_one[2] = force->numeric(FLERR,arg[iarg+4]); //friction coeff. iarg += 5; - } - else{ + } else { error->all(FLERR, "Illegal pair_coeff command, twisting friction model not recognized"); } - } - else if (strcmp(arg[iarg], "cutoff") == 0){ + } else if (strcmp(arg[iarg], "cutoff") == 0) { if (iarg + 1 >= narg) error->all(FLERR, "Illegal pair_coeff command, not enough parameters"); cutoff_one = force->numeric(FLERR,arg[iarg+1]); - } - else error->all(FLERR, "Illegal pair coeff command"); + } else error->all(FLERR, "Illegal pair coeff command"); } //It is an error not to specify normal or tangential model @@ -867,25 +834,23 @@ void PairGranular::coeff(int narg, char **arg) int count = 0; double damp; - if (damping_model_one == TSUJI){ + if (damping_model_one == TSUJI) { double cor; cor = normal_coeffs_one[1]; damp = 1.2728-4.2783*cor+11.087*pow(cor,2)-22.348*pow(cor,3)+ 27.467*pow(cor,4)-18.022*pow(cor,5)+ 4.8218*pow(cor,6); - } - else damp = normal_coeffs_one[1]; + } else damp = normal_coeffs_one[1]; for (int i = ilo; i <= ihi; i++) { for (int j = MAX(jlo,i); j <= jhi; j++) { normal_model[i][j] = normal_model[j][i] = normal_model_one; normal_coeffs[i][j][1] = normal_coeffs[j][i][1] = damp; - if (normal_model_one != HERTZ && normal_model_one != HOOKE){ + if (normal_model_one != HERTZ && normal_model_one != HOOKE) { Emod[i][j] = Emod[j][i] = normal_coeffs_one[0]; poiss[i][j] = poiss[j][i] = normal_coeffs_one[2]; normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = FOURTHIRDS*mix_stiffnessE(Emod[i][j], Emod[i][j], poiss[i][j], poiss[i][j]); - } - else{ + } else { normal_coeffs[i][j][0] = normal_coeffs[j][i][0] = normal_coeffs_one[0]; } if ((normal_model_one == JKR) || (normal_model_one == DMT)) @@ -894,10 +859,9 @@ void PairGranular::coeff(int narg, char **arg) damping_model[i][j] = damping_model[j][i] = damping_model_one; tangential_model[i][j] = tangential_model[j][i] = tangential_model_one; - if (tangential_coeffs_one[0] == -1){ + if (tangential_coeffs_one[0] == -1) { tangential_coeffs[i][j][0] = tangential_coeffs[j][i][0] = 8*mix_stiffnessG(Emod[i][j], Emod[i][j], poiss[i][j], poiss[i][j]); - } - else{ + } else { tangential_coeffs[i][j][0] = tangential_coeffs[j][i][0] = tangential_coeffs_one[0]; } for (int k = 1; k < 3; k++) @@ -949,23 +913,22 @@ void PairGranular::init_style() size_history = 3*tangential_history + 3*roll_history + twist_history; //Determine location of tangential/roll/twist histories in array - if (roll_history){ + if (roll_history) { if (tangential_history) roll_history_index = 3; else roll_history_index = 0; } - if (twist_history){ - if (tangential_history){ + if (twist_history) { + if (tangential_history) { if (roll_history) twist_history_index = 6; else twist_history_index = 3; - } - else{ + } else { if (roll_history) twist_history_index = 3; else twist_history_index = 0; } } for (int i = 1; i <= atom->ntypes; i++) for (int j = i; j <= atom->ntypes; j++) - if (tangential_model[i][j] == TANGENTIAL_MINDLIN_RESCALE){ + if (tangential_model[i][j] == TANGENTIAL_MINDLIN_RESCALE) { size_history += 1; roll_history_index += 1; twist_history_index += 1; @@ -1049,24 +1012,23 @@ void PairGranular::init_style() int *type = atom->type; int nlocal = atom->nlocal; - for (i = 0; i < nlocal; i++){ + for (i = 0; i < nlocal; i++) { double radius_cut = radius[i]; - if (mask[i] & freeze_group_bit){ + if (mask[i] & freeze_group_bit) { onerad_frozen[type[i]] = MAX(onerad_frozen[type[i]],radius_cut); - } - else{ + } else { onerad_dynamic[type[i]] = MAX(onerad_dynamic[type[i]],radius_cut); } } MPI_Allreduce(&onerad_dynamic[1],&maxrad_dynamic[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); + MPI_DOUBLE,MPI_MAX,world); MPI_Allreduce(&onerad_frozen[1],&maxrad_frozen[1],atom->ntypes, - MPI_DOUBLE,MPI_MAX,world); + MPI_DOUBLE,MPI_MAX,world); // set fix which stores history info - if (size_history > 0){ + if (size_history > 0) { int ifix = modify->find_fix("NEIGH_HISTORY"); if (ifix < 0) error->all(FLERR,"Could not find pair fix neigh history ID"); fix_history = (FixNeighHistory *) modify->fix[ifix]; @@ -1081,12 +1043,12 @@ double PairGranular::init_one(int i, int j) { double cutoff; - if (setflag[i][j] == 0){ + if (setflag[i][j] == 0) { if ((normal_model[i][i] != normal_model[j][j]) || (damping_model[i][i] != damping_model[j][j]) || (tangential_model[i][i] != tangential_model[j][j]) || (roll_model[i][i] != roll_model[j][j]) || - (twist_model[i][i] != twist_model[j][j])){ + (twist_model[i][i] != twist_model[j][j])) { char str[512]; sprintf(str,"Granular pair style functional forms are different, cannot mix coefficients for types %d and %d. \nThis combination must be set explicitly via pair_coeff command.",i,j); @@ -1105,12 +1067,12 @@ double PairGranular::init_one(int i, int j) for (int k = 0; k < 3; k++) tangential_coeffs[i][j][k] = tangential_coeffs[j][i][k] = mix_geom(tangential_coeffs[i][i][k], tangential_coeffs[j][j][k]); - if (roll_model[i][j] != ROLL_NONE){ + if (roll_model[i][j] != ROLL_NONE) { for (int k = 0; k < 3; k++) roll_coeffs[i][j][k] = roll_coeffs[j][i][k] = mix_geom(roll_coeffs[i][i][k], roll_coeffs[j][j][k]); } - if (twist_model[i][j] != TWIST_NONE && twist_model[i][j] != TWIST_MARSHALL){ + if (twist_model[i][j] != TWIST_NONE && twist_model[i][j] != TWIST_MARSHALL) { for (int k = 0; k < 3; k++) twist_coeffs[i][j][k] = twist_coeffs[j][i][k] = mix_geom(twist_coeffs[i][i][k], twist_coeffs[j][j][k]); } @@ -1124,14 +1086,14 @@ double PairGranular::init_one(int i, int j) // we assign cutoff = max(cut[i][j]) for i,j such that cut[i][j] > 0.0. double pulloff; - if (cutoff_type[i][j] < 0 && cutoff_global < 0){ + if (cutoff_type[i][j] < 0 && cutoff_global < 0) { if (((maxrad_dynamic[i] > 0.0) && (maxrad_dynamic[j] > 0.0)) || ((maxrad_dynamic[i] > 0.0) && (maxrad_frozen[j] > 0.0)) || ((maxrad_frozen[i] > 0.0) && (maxrad_dynamic[j] > 0.0))) { // radius info about both i and j exist cutoff = maxrad_dynamic[i]+maxrad_dynamic[j]; pulloff = 0.0; - if (normal_model[i][j] == JKR){ + if (normal_model[i][j] == JKR) { pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_dynamic[j], i, j); cutoff += pulloff; } @@ -1143,8 +1105,7 @@ double PairGranular::init_one(int i, int j) if (normal_model[i][j] == JKR) pulloff = pulloff_distance(maxrad_dynamic[i], maxrad_frozen[j], i, j); cutoff = MAX(cutoff,maxrad_dynamic[i]+maxrad_frozen[j]+pulloff); - } - else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) + } else { // radius info about either i or j does not exist (i.e. not present and not about to get poured; set to largest value to not interfere with neighbor list) double cutmax = 0.0; for (int k = 1; k <= atom->ntypes; k++) { cutmax = MAX(cutmax,2.0*maxrad_dynamic[k]); @@ -1152,11 +1113,9 @@ double PairGranular::init_one(int i, int j) } cutoff = cutmax; } - } - else if (cutoff_type[i][j] > 0){ + } else if (cutoff_type[i][j] > 0) { cutoff = cutoff_type[i][j]; - } - else if (cutoff_global > 0){ + } else if (cutoff_global > 0) { cutoff = cutoff_global; } @@ -1285,7 +1244,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, bool touchflag; E = normal_coeffs[itype][jtype][0]; - if (normal_model[itype][jtype] == JKR){ + if (normal_model[itype][jtype] == JKR) { E *= THREEQUARTERS; R2 = Reff*Reff; coh = normal_coeffs[itype][jtype][3]; @@ -1293,12 +1252,9 @@ double PairGranular::single(int i, int j, int itype, int jtype, delta_pulloff = a*a/Reff - 2*sqrt(M_PI*coh*a/E); dist_pulloff = radsum+delta_pulloff; touchflag = (rsq <= dist_pulloff*dist_pulloff); - } - else{ - touchflag = (rsq <= radsum*radsum); - } + } else touchflag = (rsq <= radsum*radsum); - if (!touchflag){ + if (!touchflag) { fforce = 0.0; for (int m = 0; m < single_extra; m++) svector[m] = 0.0; return 0.0; @@ -1376,7 +1332,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, delta = radsum - r; dR = delta*Reff; - if (normal_model[itype][jtype] == JKR){ + if (normal_model[itype][jtype] == JKR) { dR2 = dR*dR; t0 = coh*coh*R2*R2*E; t1 = PI27SQ*t0; @@ -1392,12 +1348,11 @@ double PairGranular::single(int i, int j, int itype, int jtype, a2 = a*a; knfac = normal_coeffs[itype][jtype][0]*a; Fne = knfac*a2/Reff - TWOPI*a2*sqrt(4*coh*E/(M_PI*a)); - } - else{ + } else { knfac = E; Fne = knfac*delta; a = sqrt(dR); - if (normal_model[itype][jtype] != HOOKE){ + if (normal_model[itype][jtype] != HOOKE) { Fne *= a; knfac *= a; } @@ -1405,13 +1360,11 @@ double PairGranular::single(int i, int j, int itype, int jtype, Fne -= 4*MY_PI*normal_coeffs[itype][jtype][3]*Reff; } - if (damping_model[itype][jtype] == VELOCITY){ + if (damping_model[itype][jtype] == VELOCITY) { damp_normal = normal_coeffs[itype][jtype][1]; - } - else if (damping_model[itype][jtype] == VISCOELASTIC){ + } else if (damping_model[itype][jtype] == VISCOELASTIC) { damp_normal = normal_coeffs[itype][jtype][1]*a*meff; - } - else if (damping_model[itype][jtype] == TSUJI){ + } else if (damping_model[itype][jtype] == TSUJI) { damp_normal = normal_coeffs[itype][jtype][1]*sqrt(meff*knfac); } @@ -1423,7 +1376,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, jnum = list->numneigh[i]; jlist = list->firstneigh[i]; - if (use_history){ + if (use_history) { allhistory = fix_history->firstvalue[i]; for (int jj = 0; jj < jnum; jj++) { neighprev++; @@ -1454,15 +1407,13 @@ double PairGranular::single(int i, int j, int itype, int jtype, vrel = vtr1*vtr1 + vtr2*vtr2 + vtr3*vtr3; vrel = sqrt(vrel); - if (normal_model[itype][jtype] == JKR){ + if (normal_model[itype][jtype] == JKR) { F_pulloff = 3*M_PI*coh*Reff; Fncrit = fabs(Fne + 2*F_pulloff); - } - else if (normal_model[itype][jtype] == DMT){ + } else if (normal_model[itype][jtype] == DMT) { F_pulloff = 4*M_PI*coh*Reff; Fncrit = fabs(Fne + 2*F_pulloff); - } - else{ + } else { Fncrit = fabs(Fntot); } @@ -1472,13 +1423,12 @@ double PairGranular::single(int i, int j, int itype, int jtype, k_tangential = tangential_coeffs[itype][jtype][0]; damp_tangential = tangential_coeffs[itype][jtype][1]*damp_normal_prefactor; - if (tangential_history){ - if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN){ + if (tangential_history) { + if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN) { k_tangential *= a; - } - else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE){ + } else if (tangential_model[itype][jtype] == TANGENTIAL_MINDLIN_RESCALE) { k_tangential *= a; - if (a < history[3]){ //On unloading, rescale the shear displacements + if (a < history[3]) { //On unloading, rescale the shear displacements double factor = a/history[3]; history[0] *= factor; history[1] *= factor; @@ -1507,8 +1457,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, fs3 *= Fscrit/fs; } else fs1 = fs2 = fs3 = 0.0; } - } - else{ //Classic pair gran/hooke (no history) + } else { //Classic pair gran/hooke (no history) fs = meff*damp_tangential*vrel; if (vrel != 0.0) Ft = MIN(Fne,fs) / vrel; else Ft = 0.0; @@ -1521,7 +1470,7 @@ double PairGranular::single(int i, int j, int itype, int jtype, // Rolling resistance //**************************************** - if (roll_model[itype][jtype] != ROLL_NONE){ + if (roll_model[itype][jtype] != ROLL_NONE) { relrot1 = omega[i][0] - omega[j][0]; relrot2 = omega[i][1] - omega[j][1]; relrot3 = omega[i][2] - omega[j][2]; @@ -1565,14 +1514,13 @@ double PairGranular::single(int i, int j, int itype, int jtype, //**************************************** // Twisting torque, including history effects //**************************************** - if (twist_model[itype][jtype] != TWIST_NONE){ + if (twist_model[itype][jtype] != TWIST_NONE) { magtwist = relrot1*nx + relrot2*ny + relrot3*nz; //Omega_T (eq 29 of Marshall) - if (twist_model[itype][jtype] == TWIST_MARSHALL){ + if (twist_model[itype][jtype] == TWIST_MARSHALL) { k_twist = 0.5*k_tangential*a*a;; //eq 32 damp_twist = 0.5*damp_tangential*a*a; mu_twist = TWOTHIRDS*a*tangential_coeffs[itype][jtype][2];; - } - else{ + } else { k_twist = twist_coeffs[itype][jtype][0]; damp_twist = twist_coeffs[itype][jtype][1]; mu_twist = twist_coeffs[itype][jtype][2]; @@ -1686,7 +1634,7 @@ double PairGranular::pulloff_distance(double radi, double radj, int itype, int j Transfer history during fix/neigh/history exchange Only needed if any history entries i-j are not just negative of j-i entries ------------------------------------------------------------------------- */ -void PairGranular::transfer_history(double* source, double* target){ +void PairGranular::transfer_history(double* source, double* target) { for (int i = 0; i < size_history; i++) target[i] = history_transfer_factors[i]*source[i]; } -- GitLab From a7a1fd4ee583be6bbd77ba82e194672c02e973a8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 15:50:44 -0400 Subject: [PATCH 0255/1243] remove reference to USER-OMP version of fix wall/gran --- doc/src/Commands_fix.txt | 2 +- doc/src/fix_wall_gran.txt | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/doc/src/Commands_fix.txt b/doc/src/Commands_fix.txt index 678cc9ba0d..c8b3ef8991 100644 --- a/doc/src/Commands_fix.txt +++ b/doc/src/Commands_fix.txt @@ -224,7 +224,7 @@ OPT. "wall/body/polyhedron"_fix_wall_body_polyhedron.html, "wall/colloid"_fix_wall.html, "wall/ees"_fix_wall_ees.html, -"wall/gran (o)"_fix_wall_gran.html, +"wall/gran"_fix_wall_gran.html, "wall/gran/region"_fix_wall_gran_region.html, "wall/harmonic"_fix_wall.html, "wall/lj1043"_fix_wall.html, diff --git a/doc/src/fix_wall_gran.txt b/doc/src/fix_wall_gran.txt index e8c2247594..198b22aa3f 100644 --- a/doc/src/fix_wall_gran.txt +++ b/doc/src/fix_wall_gran.txt @@ -7,7 +7,6 @@ :line fix wall/gran command :h3 -fix wall/gran/omp command :h3 [Syntax:] @@ -151,28 +150,6 @@ the clockwise direction for {vshear} > 0 or counter-clockwise for {vshear} < 0. In this case, {vshear} is the tangential velocity of the wall at whatever {radius} has been defined. -:line - -Styles with a {gpu}, {intel}, {kk}, {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 on the "Speed packages"_Speed_packages.html doc -page. 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 GPU, USER-INTEL, KOKKOS, -USER-OMP and OPT packages, respectively. They are only enabled if -LAMMPS was built with those packages. See the "Build -package"_Build_package.html doc page 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"_Run_options.html when you invoke LAMMPS, or you can use the -"suffix"_suffix.html command in your input script. - -See the "Speed packages"_Speed_packages.html doc page for more -instructions on how to use the accelerated styles effectively. - [Restart, fix_modify, output, run start/stop, minimize info:] This fix writes the shear friction state of atoms interacting with the -- GitLab From 2bac3650811d5b30fc04e61fe85abdab195a7d90 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 15 Mar 2019 15:51:08 -0400 Subject: [PATCH 0256/1243] support old style PDF build for new pair style granular --- doc/src/lammps.book | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 198e234f0c..8165c9d743 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -578,6 +578,7 @@ pair_extep.html pair_gauss.html pair_gayberne.html pair_gran.html +pair_granular.html pair_gromacs.html pair_gw.html pair_ilp_graphene_hbn.html -- GitLab From 8c4baac3f10b7d2c505a9ffe73c22bdd7e8656ee Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 15 Mar 2019 14:25:24 -0600 Subject: [PATCH 0257/1243] Only copy force on ghost atoms if newton on --- src/KOKKOS/atom_vec_atomic_kokkos.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/atom_vec_atomic_kokkos.cpp b/src/KOKKOS/atom_vec_atomic_kokkos.cpp index e3c1bee956..80321fd2ea 100644 --- a/src/KOKKOS/atom_vec_atomic_kokkos.cpp +++ b/src/KOKKOS/atom_vec_atomic_kokkos.cpp @@ -21,6 +21,7 @@ #include "atom_masks.h" #include "memory_kokkos.h" #include "error.h" +#include "force.h" using namespace LAMMPS_NS; @@ -901,7 +902,14 @@ void AtomVecAtomicKokkos::sync(ExecutionSpace space, unsigned int mask) if (space == Device) { if (mask & X_MASK) atomKK->k_x.sync(); if (mask & V_MASK) atomKK->k_v.sync(); - if (mask & F_MASK) atomKK->k_f.sync(); + if (mask & F_MASK) { + if (!force || force->newton) { + atomKK->k_f.sync(); + } else { + auto k_f_nlocal = Kokkos::subview(atomKK->k_f,std::make_pair(0,atom->nlocal),Kokkos::ALL); + k_f_nlocal.sync(); + } + } if (mask & TAG_MASK) atomKK->k_tag.sync(); if (mask & TYPE_MASK) atomKK->k_type.sync(); if (mask & MASK_MASK) atomKK->k_mask.sync(); @@ -909,7 +917,14 @@ void AtomVecAtomicKokkos::sync(ExecutionSpace space, unsigned int mask) } else { if (mask & X_MASK) atomKK->k_x.sync(); if (mask & V_MASK) atomKK->k_v.sync(); - if (mask & F_MASK) atomKK->k_f.sync(); + if (mask & F_MASK) { + if (!force || force->newton) { + atomKK->k_f.sync(); + } else { + auto k_f_nlocal = Kokkos::subview(atomKK->k_f,std::make_pair(0,atom->nlocal),Kokkos::ALL); + k_f_nlocal.sync(); + } + } if (mask & TAG_MASK) atomKK->k_tag.sync(); if (mask & TYPE_MASK) atomKK->k_type.sync(); if (mask & MASK_MASK) atomKK->k_mask.sync(); -- GitLab From ac20d1ab41d63096f60cdeac54d1f76cb60b5dff Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 18 Mar 2019 09:52:16 -0600 Subject: [PATCH 0258/1243] fix corner-case issue with hyper communication, also timer --- src/REPLICA/fix_hyper_local.cpp | 12 ++++++++++-- src/REPLICA/hyper.cpp | 11 ++++++++--- src/comm_brick.cpp | 18 ++++++++---------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/REPLICA/fix_hyper_local.cpp b/src/REPLICA/fix_hyper_local.cpp index 21ad2cd86a..be4a642ebb 100644 --- a/src/REPLICA/fix_hyper_local.cpp +++ b/src/REPLICA/fix_hyper_local.cpp @@ -1261,16 +1261,24 @@ void FixHyperLocal::unpack_reverse_comm(int n, int *list, double *buf) { int i,j,k,m; - m = 0; + // return if n = 0 + // b/c if there are no atoms (n = 0), the message will not have + // been sent by Comm::reverse_comm_fix() or reverse_comm_fix_variable() + // so must not read nonzero from first buf location (would be zero anyway) + + if (n == 0) return; // STRAIN // unpack maxstrain vector // nonzero # of entries, each has offset to which atom in receiver's list // use MAX, b/c want maximum abs value strain for each atom's bonds - + + m = 0; + if (commflag == STRAIN) { int offset; int nonzero = (int) ubuf(buf[m++]).i; // # of atoms with values + for (int iatom = 0; iatom < nonzero; iatom++) { offset = (int) ubuf(buf[m++]).i; // offset into list for which atom j = list[offset]; diff --git a/src/REPLICA/hyper.cpp b/src/REPLICA/hyper.cpp index 0d8de6d060..5d820b2e27 100644 --- a/src/REPLICA/hyper.cpp +++ b/src/REPLICA/hyper.cpp @@ -181,9 +181,6 @@ void Hyper::command(int narg, char **arg) if (hyperenable) fix_hyper->init_hyper(); - timer->barrier_start(); - time_start = timer->get_wall(Timer::TOTAL); - // perform initial minimization and bond list creation int nevent = 0; @@ -198,6 +195,14 @@ void Hyper::command(int narg, char **arg) if (hyperenable) fix_hyper->build_bond_list(0); fix_event->restore_state_quench(); + // reset stats and timers to skip HD setup + + nbuild = ndanger = 0; + time_dynamics = time_quench = 0.0; + + timer->barrier_start(); + time_start = timer->get_wall(Timer::TOTAL); + // main loop: dynamics, store state, quench, check event, restore state int ecount; diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index 64b21e41c9..330551aaed 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -1046,10 +1046,6 @@ void CommBrick::reverse_comm_fix(Fix *fix, int size) reverse communication invoked by a Fix with variable size data query fix for pack size to insure buf_send is big enough handshake sizes before each Irecv/Send to insure buf_recv is big enough - this removes the if tests on sendnum and recvnum to make MPI calls, - as in reverse_comm_fix(), b/c the caller may still want to - exchange a message even if the send/recv swap has no atoms, - e.g. a reduced count = 0 of atoms to send/recv, as in fix hyper/local ------------------------------------------------------------------------- */ void CommBrick::reverse_comm_fix_variable(Fix *fix) @@ -1074,12 +1070,14 @@ void CommBrick::reverse_comm_fix_variable(Fix *fix) &nrecv,1,MPI_INT,sendproc[iswap],0,world, MPI_STATUS_IGNORE); - if (nrecv > maxrecv) grow_recv(nrecv); - MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0, - world,&request); - - MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world); - MPI_Wait(&request,MPI_STATUS_IGNORE); + if (sendnum[iswap]) { + if (nrecv > maxrecv) grow_recv(nrecv); + MPI_Irecv(buf_recv,maxrecv,MPI_DOUBLE,sendproc[iswap],0, + world,&request); + } + if (recvnum[iswap]) + MPI_Send(buf_send,nsend,MPI_DOUBLE,recvproc[iswap],0,world); + if (sendnum[iswap]) MPI_Wait(&request,MPI_STATUS_IGNORE); buf = buf_recv; } else buf = buf_send; -- GitLab From 36836598b1a4bbe76fac874274ae9d5f1dc635b9 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 18 Mar 2019 10:45:14 -0600 Subject: [PATCH 0259/1243] Reduce data transfer in exchange --- src/KOKKOS/comm_kokkos.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 5aa2cbdfbe..06807b08b9 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -57,10 +57,10 @@ CommKokkos::CommKokkos(LAMMPS *lmp) : CommBrick(lmp) memory->destroy(buf_recv); buf_recv = NULL; - k_exchange_sendlist = DAT:: - tdual_int_1d("comm:k_exchange_sendlist",100); - k_exchange_copylist = DAT:: - tdual_int_1d("comm:k_exchange_copylist",100); + k_exchange_lists = DAT:: + tdual_int_1d("comm:k_exchange_lists",2,100); + k_exchange_sendlist = Kokkos::subview(k_exchange_lists,0,KOKKOS::ALL); + k_exchange_copylist = Kokkos::subview(k_exchange_lists,1,KOKKOS::ALL); k_count = DAT::tdual_int_scalar("comm:k_count"); k_sendflag = DAT::tdual_int_1d("comm:k_sendflag",100); @@ -619,8 +619,9 @@ void CommKokkos::exchange_device() k_count.h_view()=k_exchange_sendlist.h_view.extent(0); } } - k_exchange_copylist.sync(); - k_exchange_sendlist.sync(); + + auto k_exchange_lists_short = Kokkos::subview(k_exchange_lists,KOKKOS::ALL,k_count.h_view()); + k_exchange_lists_short.template sync(); k_sendflag.sync(); int sendpos = nlocal-1; @@ -634,8 +635,8 @@ void CommKokkos::exchange_device() k_exchange_copylist.h_view(i) = -1; } - k_exchange_copylist.modify(); - k_exchange_copylist.sync(); + k_exchange_copylist_short.modify(); + k_exchange_copylist_short.sync(); nsend = k_count.h_view(); if (nsend > maxsend) grow_send_kokkos(nsend,1); nsend = -- GitLab From b50ef59a199346141ae06bea6e474fb5ade762bd Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 18 Mar 2019 13:17:32 -0600 Subject: [PATCH 0260/1243] Optimize Kokkos comm for small systems --- src/KOKKOS/comm_kokkos.cpp | 90 ++++++++++++++++++++------------------ src/KOKKOS/comm_kokkos.h | 2 + 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 06807b08b9..814824bc5b 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -57,10 +57,9 @@ CommKokkos::CommKokkos(LAMMPS *lmp) : CommBrick(lmp) memory->destroy(buf_recv); buf_recv = NULL; - k_exchange_lists = DAT:: - tdual_int_1d("comm:k_exchange_lists",2,100); - k_exchange_sendlist = Kokkos::subview(k_exchange_lists,0,KOKKOS::ALL); - k_exchange_copylist = Kokkos::subview(k_exchange_lists,1,KOKKOS::ALL); + k_exchange_lists = DAT::tdual_int_2d("comm:k_exchange_lists",2,100); + k_exchange_sendlist = Kokkos::subview(k_exchange_lists,0,Kokkos::ALL); + k_exchange_copylist = Kokkos::subview(k_exchange_lists,1,Kokkos::ALL); k_count = DAT::tdual_int_scalar("comm:k_count"); k_sendflag = DAT::tdual_int_1d("comm:k_sendflag",100); @@ -188,6 +187,8 @@ void CommKokkos::forward_comm_device(int dummy) atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); if (comm->nprocs == 1) { + k_swap.sync(); + k_pbc.sync(); n = avec->pack_comm_self_fused(totalsend,k_sendlist,k_sendnum_scan, k_firstrecv,k_pbc_flag,k_pbc); } else { @@ -620,8 +621,7 @@ void CommKokkos::exchange_device() } } - auto k_exchange_lists_short = Kokkos::subview(k_exchange_lists,KOKKOS::ALL,k_count.h_view()); - k_exchange_lists_short.template sync(); + k_exchange_lists.sync(); k_sendflag.sync(); int sendpos = nlocal-1; @@ -635,6 +635,7 @@ void CommKokkos::exchange_device() k_exchange_copylist.h_view(i) = -1; } + auto k_exchange_copylist_short = Kokkos::subview(k_exchange_copylist,k_count.h_view()); k_exchange_copylist_short.modify(); k_exchange_copylist_short.sync(); nsend = k_count.h_view(); @@ -749,14 +750,16 @@ void CommKokkos::borders() if (!exchange_comm_classic) { if (exchange_comm_on_host) borders_device(); else borders_device(); - return; + } else { + atomKK->sync(Host,ALL_MASK); + k_sendlist.sync(); + CommBrick::borders(); + k_sendlist.modify(); + atomKK->modified(Host,ALL_MASK); } - atomKK->sync(Host,ALL_MASK); - k_sendlist.sync(); - CommBrick::borders(); - k_sendlist.modify(); - atomKK->modified(Host,ALL_MASK); + if (comm->nprocs == 1 && !forward_comm_classic) + copy_pbc_info(); } /* ---------------------------------------------------------------------- */ @@ -1043,40 +1046,43 @@ void CommKokkos::borders_device() { atomKK->sync(Host,TAG_MASK); atom->map_set(); } +} - if (comm->nprocs == 1) { - if (nswap > k_pbc.extent(0)) { - k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); - k_swap = DAT::tdual_int_2d("comm:swap",3,nswap); - k_pbc_flag .d_view = Kokkos::subview(k_swap.d_view,0,Kokkos::ALL); - k_firstrecv .d_view = Kokkos::subview(k_swap.d_view,1,Kokkos::ALL); - k_sendnum_scan.d_view = Kokkos::subview(k_swap.d_view,2,Kokkos::ALL); - k_pbc_flag .h_view = Kokkos::subview(k_swap.h_view,0,Kokkos::ALL); - k_firstrecv .h_view = Kokkos::subview(k_swap.h_view,1,Kokkos::ALL); - k_sendnum_scan.h_view = Kokkos::subview(k_swap.h_view,2,Kokkos::ALL); - } - int scan = 0; - for (int iswap = 0; iswap < nswap; iswap++) { - scan += sendnum[iswap]; - k_sendnum_scan.h_view[iswap] = scan; - k_firstrecv.h_view[iswap] = firstrecv[iswap]; - k_pbc_flag.h_view[iswap] = pbc_flag[iswap]; - k_pbc.h_view(iswap,0) = pbc[iswap][0]; - k_pbc.h_view(iswap,1) = pbc[iswap][1]; - k_pbc.h_view(iswap,2) = pbc[iswap][2]; - k_pbc.h_view(iswap,3) = pbc[iswap][3]; - k_pbc.h_view(iswap,4) = pbc[iswap][4]; - k_pbc.h_view(iswap,5) = pbc[iswap][5]; - } - totalsend = scan; - - k_swap.modify(); - k_pbc.modify(); +/* ---------------------------------------------------------------------- + copy pbc info +------------------------------------------------------------------------- */ - k_swap.sync(); - k_pbc.sync(); +void CommKokkos::copy_pbc_info() +{ + if (nswap > k_pbc.extent(0)) { + k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); + k_swap = DAT::tdual_int_2d("comm:swap",3,nswap); + k_pbc_flag .d_view = Kokkos::subview(k_swap.d_view,0,Kokkos::ALL); + k_firstrecv .d_view = Kokkos::subview(k_swap.d_view,1,Kokkos::ALL); + k_sendnum_scan.d_view = Kokkos::subview(k_swap.d_view,2,Kokkos::ALL); + k_pbc_flag .h_view = Kokkos::subview(k_swap.h_view,0,Kokkos::ALL); + k_firstrecv .h_view = Kokkos::subview(k_swap.h_view,1,Kokkos::ALL); + k_sendnum_scan.h_view = Kokkos::subview(k_swap.h_view,2,Kokkos::ALL); + } + int scan = 0; + for (int iswap = 0; iswap < nswap; iswap++) { + scan += sendnum[iswap]; + k_sendnum_scan.h_view[iswap] = scan; + k_firstrecv.h_view[iswap] = firstrecv[iswap]; + k_pbc_flag.h_view[iswap] = pbc_flag[iswap]; + k_pbc.h_view(iswap,0) = pbc[iswap][0]; + k_pbc.h_view(iswap,1) = pbc[iswap][1]; + k_pbc.h_view(iswap,2) = pbc[iswap][2]; + k_pbc.h_view(iswap,3) = pbc[iswap][3]; + k_pbc.h_view(iswap,4) = pbc[iswap][4]; + k_pbc.h_view(iswap,5) = pbc[iswap][5]; } + totalsend = scan; + + k_swap.modify(); + k_pbc.modify(); } + /* ---------------------------------------------------------------------- realloc the size of the send buffer as needed with BUFFACTOR and bufextra if flag = 1, realloc diff --git a/src/KOKKOS/comm_kokkos.h b/src/KOKKOS/comm_kokkos.h index cab8124231..194826f9df 100644 --- a/src/KOKKOS/comm_kokkos.h +++ b/src/KOKKOS/comm_kokkos.h @@ -58,6 +58,7 @@ class CommKokkos : public CommBrick { DAT::tdual_int_2d k_sendlist; DAT::tdual_int_scalar k_total_send; DAT::tdual_xfloat_2d k_buf_send,k_buf_recv; + DAT::tdual_int_2d k_exchange_lists; DAT::tdual_int_1d k_exchange_sendlist,k_exchange_copylist,k_sendflag; DAT::tdual_int_scalar k_count; //double *buf_send; // send buffer for all comm @@ -81,6 +82,7 @@ class CommKokkos : public CommBrick { void grow_recv_kokkos(int, ExecutionSpace space = Host); void grow_list(int, int); void grow_swap(int); + void copy_pbc_info(); }; } -- GitLab From e2d28f5160d9f58c1519ee40fd289c8918f1383a Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 18 Mar 2019 15:27:35 -0600 Subject: [PATCH 0261/1243] Only copy pbc info in comm setup --- src/KOKKOS/comm_kokkos.cpp | 52 +++++++++++++++++++++++--------------- src/KOKKOS/comm_kokkos.h | 3 ++- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 814824bc5b..c6d8424c27 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -140,6 +140,31 @@ void CommKokkos::init() forward_comm_classic = true; } +/* ---------------------------------------------------------------------- */ + +void CommKokkos::setup() +{ + CommBrick::setup(); + + k_pbc_flag = DAT::tdual_int_1d("comm:pbc_flag",nswap); + k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); + + for (int iswap = 0; iswap < nswap; iswap++) { + k_pbc_flag.h_view[iswap] = pbc_flag[iswap]; + k_pbc.h_view(iswap,0) = pbc[iswap][0]; + k_pbc.h_view(iswap,1) = pbc[iswap][1]; + k_pbc.h_view(iswap,2) = pbc[iswap][2]; + k_pbc.h_view(iswap,3) = pbc[iswap][3]; + k_pbc.h_view(iswap,4) = pbc[iswap][4]; + k_pbc.h_view(iswap,5) = pbc[iswap][5]; + } + k_pbc_flag.modify(); + k_pbc.modify(); + + k_pbc_flag.sync(); + k_pbc.sync(); +} + /* ---------------------------------------------------------------------- forward communication of atom coords every timestep other per-atom attributes may also be sent via pack/unpack routines @@ -759,7 +784,7 @@ void CommKokkos::borders() } if (comm->nprocs == 1 && !forward_comm_classic) - copy_pbc_info(); + copy_swap_info(); } /* ---------------------------------------------------------------------- */ @@ -1049,38 +1074,25 @@ void CommKokkos::borders_device() { } /* ---------------------------------------------------------------------- - copy pbc info + copy swap info ------------------------------------------------------------------------- */ -void CommKokkos::copy_pbc_info() +void CommKokkos::copy_swap_info() { - if (nswap > k_pbc.extent(0)) { - k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); - k_swap = DAT::tdual_int_2d("comm:swap",3,nswap); - k_pbc_flag .d_view = Kokkos::subview(k_swap.d_view,0,Kokkos::ALL); - k_firstrecv .d_view = Kokkos::subview(k_swap.d_view,1,Kokkos::ALL); - k_sendnum_scan.d_view = Kokkos::subview(k_swap.d_view,2,Kokkos::ALL); - k_pbc_flag .h_view = Kokkos::subview(k_swap.h_view,0,Kokkos::ALL); - k_firstrecv .h_view = Kokkos::subview(k_swap.h_view,1,Kokkos::ALL); - k_sendnum_scan.h_view = Kokkos::subview(k_swap.h_view,2,Kokkos::ALL); + if (nswap > k_swap.extent(1)) { + k_swap = DAT::tdual_int_2d("comm:swap",2,nswap); + k_firstrecv = Kokkos::subview(k_swap,0,Kokkos::ALL); + k_sendnum_scan = Kokkos::subview(k_swap,1,Kokkos::ALL); } int scan = 0; for (int iswap = 0; iswap < nswap; iswap++) { scan += sendnum[iswap]; k_sendnum_scan.h_view[iswap] = scan; k_firstrecv.h_view[iswap] = firstrecv[iswap]; - k_pbc_flag.h_view[iswap] = pbc_flag[iswap]; - k_pbc.h_view(iswap,0) = pbc[iswap][0]; - k_pbc.h_view(iswap,1) = pbc[iswap][1]; - k_pbc.h_view(iswap,2) = pbc[iswap][2]; - k_pbc.h_view(iswap,3) = pbc[iswap][3]; - k_pbc.h_view(iswap,4) = pbc[iswap][4]; - k_pbc.h_view(iswap,5) = pbc[iswap][5]; } totalsend = scan; k_swap.modify(); - k_pbc.modify(); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/comm_kokkos.h b/src/KOKKOS/comm_kokkos.h index 194826f9df..d5428c8b0c 100644 --- a/src/KOKKOS/comm_kokkos.h +++ b/src/KOKKOS/comm_kokkos.h @@ -33,6 +33,7 @@ class CommKokkos : public CommBrick { CommKokkos(class LAMMPS *); ~CommKokkos(); void init(); + void setup(); void forward_comm(int dummy = 0); // forward comm of atom coords void reverse_comm(); // reverse comm of atom coords @@ -82,7 +83,7 @@ class CommKokkos : public CommBrick { void grow_recv_kokkos(int, ExecutionSpace space = Host); void grow_list(int, int); void grow_swap(int); - void copy_pbc_info(); + void copy_swap_info(); }; } -- GitLab From 194e11c3297d6238b2ae164fa09dfab1f3eab4ea Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 19 Mar 2019 08:12:49 -0600 Subject: [PATCH 0262/1243] Commit JT 031919 - bug with sk sim - commit/push before pull up-to-date SPIN from master --- src/REPLICA/fix_neb_spin.cpp | 6 ++++++ src/REPLICA/fix_neb_spin.h | 6 ------ src/REPLICA/neb_spin.cpp | 6 ++++++ src/SPIN/min_spinmin.cpp | 6 ++++++ src/SPIN/pair_spin_dmi.cpp | 5 +++-- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/REPLICA/fix_neb_spin.cpp index 95d5e19f25..610e6d2fe5 100644 --- a/src/REPLICA/fix_neb_spin.cpp +++ b/src/REPLICA/fix_neb_spin.cpp @@ -11,6 +11,12 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ + Contributing authors: Julien Tranchida (SNL) + + Please cite the related publication: +------------------------------------------------------------------------- */ + #include #include #include diff --git a/src/REPLICA/fix_neb_spin.h b/src/REPLICA/fix_neb_spin.h index c70f35ae2d..9bbacc8bf0 100644 --- a/src/REPLICA/fix_neb_spin.h +++ b/src/REPLICA/fix_neb_spin.h @@ -13,7 +13,6 @@ #ifdef FIX_CLASS -//FixStyle(neb,FixNEB) FixStyle(neb/spin,FixNEB_spin) #else @@ -36,8 +35,6 @@ class FixNEB_spin : public Fix { void init(); void min_setup(int); void min_post_force(int); - //void advance_spins(double); - //double evaluate_dt(); private: int me,nprocs,nprocs_universe; @@ -60,13 +57,11 @@ class FixNEB_spin : public Fix { int maxlocal; // size of xprev,xnext,tangent arrays double *nlenall; double **xprev,**xnext,**fnext; - // spin quantities double **spprev,**spnext,**fmnext; double **springF; double **tangent; double **xsend,**xrecv; // coords to send/recv to/from other replica double **fsend,**frecv; // coords to send/recv to/from other replica - // spin quantities double **spsend,**sprecv; // sp to send/recv to/from other replica double **fmsend,**fmrecv; // fm to send/recv to/from other replica tagint *tagsend,*tagrecv; // ditto for atom IDs @@ -74,7 +69,6 @@ class FixNEB_spin : public Fix { // info gathered from all procs in my replica double **xsendall,**xrecvall; // coords to send/recv to/from other replica double **fsendall,**frecvall; // force to send/recv to/from other replica - // spin quantities double **spsendall,**sprecvall; // sp to send/recv to/from other replica double **fmsendall,**fmrecvall; // fm to send/recv to/from other replica tagint *tagsendall,*tagrecvall; // ditto for atom IDs diff --git a/src/REPLICA/neb_spin.cpp b/src/REPLICA/neb_spin.cpp index 6681bf56ad..38f5b530da 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/REPLICA/neb_spin.cpp @@ -11,6 +11,12 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ + Contributing authors: Julien Tranchida (SNL) + + Please cite the related publication: +------------------------------------------------------------------------- */ + // lmptype.h must be first b/c this file uses MAXBIGINT and includes mpi.h // due to OpenMPI bug which sets INT64_MAX via its mpi.h // before lmptype.h can set flags to insure it is done correctly diff --git a/src/SPIN/min_spinmin.cpp b/src/SPIN/min_spinmin.cpp index cdd0d45287..808a5359bc 100644 --- a/src/SPIN/min_spinmin.cpp +++ b/src/SPIN/min_spinmin.cpp @@ -11,6 +11,12 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ + Contributing authors: Julien Tranchida (SNL) + + Please cite the related publication: +------------------------------------------------------------------------- */ + #include #include #include "min_spinmin.h" diff --git a/src/SPIN/pair_spin_dmi.cpp b/src/SPIN/pair_spin_dmi.cpp index 18682fdb9f..0862e5c618 100644 --- a/src/SPIN/pair_spin_dmi.cpp +++ b/src/SPIN/pair_spin_dmi.cpp @@ -173,8 +173,9 @@ void PairSpinDmi::init_style() if (strcmp(modify->fix[ifix]->style,"nve/spin") == 0) break; ifix++; } - if (ifix == modify->nfix) - error->all(FLERR,"pair/spin style requires nve/spin"); + // test remove if test + //if (ifix == modify->nfix) + // error->all(FLERR,"pair/spin style requires nve/spin"); // get the lattice_flag from nve/spin -- GitLab From cf8bee9b46da121e2c930b8cba2b96635a1ad92c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 19 Mar 2019 11:43:29 -0400 Subject: [PATCH 0263/1243] remove unused and redundant data elements. no write_data support for tables. --- src/USER-MISC/dihedral_table_cut.cpp | 82 ++-------------------------- src/USER-MISC/dihedral_table_cut.h | 8 --- 2 files changed, 4 insertions(+), 86 deletions(-) diff --git a/src/USER-MISC/dihedral_table_cut.cpp b/src/USER-MISC/dihedral_table_cut.cpp index 6ebe094e50..07d0af46b6 100644 --- a/src/USER-MISC/dihedral_table_cut.cpp +++ b/src/USER-MISC/dihedral_table_cut.cpp @@ -425,17 +425,6 @@ DihedralTableCut::DihedralTableCut(LAMMPS *lmp) : Dihedral(lmp) DihedralTableCut::~DihedralTableCut() { if (allocated) { - memory->destroy(setflag); - memory->destroy(setflag_d); - memory->destroy(setflag_aat); - - memory->destroy(k1); - memory->destroy(k2); - memory->destroy(k3); - memory->destroy(phi1); - memory->destroy(phi2); - memory->destroy(phi3); - memory->destroy(aat_k); memory->destroy(aat_theta0_1); memory->destroy(aat_theta0_2); @@ -761,27 +750,15 @@ void DihedralTableCut::allocate() allocated = 1; int n = atom->ndihedraltypes; - memory->create(k1,n+1,"dihedral:k1"); - memory->create(k2,n+1,"dihedral:k2"); - memory->create(k3,n+1,"dihedral:k3"); - memory->create(phi1,n+1,"dihedral:phi1"); - memory->create(phi2,n+1,"dihedral:phi2"); - memory->create(phi3,n+1,"dihedral:phi3"); - memory->create(aat_k,n+1,"dihedral:aat_k"); memory->create(aat_theta0_1,n+1,"dihedral:aat_theta0_1"); memory->create(aat_theta0_2,n+1,"dihedral:aat_theta0_2"); - memory->create(setflag,n+1,"dihedral:setflag"); - memory->create(setflag_d,n+1,"dihedral:setflag_d"); - memory->create(setflag_aat,n+1,"dihedral:setflag_aat"); - memory->create(tabindex,n+1,"dihedral:tabindex"); - //memory->create(phi0,n+1,"dihedral:phi0"); <-equilibrium angles not supported memory->create(setflag,n+1,"dihedral:setflag"); for (int i = 1; i <= n; i++) - setflag[i] = setflag_d[i] = setflag_aat[i] = 0; + setflag[i] = 0; } void DihedralTableCut::settings(int narg, char **arg) @@ -824,9 +801,6 @@ void DihedralTableCut::coeff(int narg, char **arg) int ilo,ihi; force->bounds(FLERR,arg[0],atom->ndihedraltypes,ilo,ihi); - int count = 0; - - double k_one = force->numeric(FLERR,arg[2]); double theta0_1_one = force->numeric(FLERR,arg[3]); double theta0_2_one = force->numeric(FLERR,arg[4]); @@ -837,8 +811,6 @@ void DihedralTableCut::coeff(int narg, char **arg) aat_k[i] = k_one; 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++; } int me; @@ -998,8 +970,7 @@ void DihedralTableCut::coeff(int narg, char **arg) // To be nice and report something, I do the same thing here.) cyc_splintD(tb->phi, tb->e, tb->e2, tablength, MY_2PI,phi); f = -dU_dphi; - } - else + } else // Otherwise we calculated the tb->f[] array. Report its contents. f = tb->f[i]; if (tb->use_degrees) { @@ -1015,9 +986,8 @@ void DihedralTableCut::coeff(int narg, char **arg) } // if (me == 0) // store ptr to table in tabindex - count = 0; - for (int i = ilo; i <= ihi; i++) - { + int count = 0; + for (int i = ilo; i <= ihi; i++) { tabindex[i] = ntables; //phi0[i] = tb->phi0; <- equilibrium dihedral angles not supported setflag[i] = 1; @@ -1025,12 +995,7 @@ void DihedralTableCut::coeff(int narg, char **arg) } ntables++; - if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients"); - - for (int i = ilo; i <= ihi; i++) - if (setflag_d[i] == 1 && setflag_aat[i] == 1 ) - setflag[i] = 1; } /* ---------------------------------------------------------------------- @@ -1041,12 +1006,6 @@ void DihedralTableCut::write_restart(FILE *fp) { fwrite(&tabstyle,sizeof(int),1,fp); fwrite(&tablength,sizeof(int),1,fp); - fwrite(&k1[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&k2[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&k3[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&phi1[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&phi2[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&phi3[1],sizeof(double),atom->ndihedraltypes,fp); fwrite(&aat_k[1],sizeof(double),atom->ndihedraltypes,fp); fwrite(&aat_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp); @@ -1064,32 +1023,18 @@ void DihedralTableCut::read_restart(FILE *fp) if (comm->me == 0) { fread(&tabstyle,sizeof(int),1,fp); fread(&tablength,sizeof(int),1,fp); - fread(&k1[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&k2[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&k3[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&phi1[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&phi2[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&phi3[1],sizeof(double),atom->ndihedraltypes,fp); fread(&aat_k[1],sizeof(double),atom->ndihedraltypes,fp); fread(&aat_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp); fread(&aat_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp); } - MPI_Bcast(&k1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&k2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&k3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&phi1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&phi2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&phi3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&aat_k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&aat_theta0_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&aat_theta0_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&tabstyle,1,MPI_INT,0,world); MPI_Bcast(&tablength,1,MPI_INT,0,world); - allocate(); for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1; } @@ -1474,22 +1419,3 @@ void DihedralTableCut::bcast_table(Table *tb) } - -/* ---------------------------------------------------------------------- - proc 0 writes to data file -------------------------------------------------------------------------- */ - -void DihedralTableCut::write_data(FILE *fp) -{ - for (int i = 1; i <= atom->ndihedraltypes; i++) - fprintf(fp,"%d %g %g %g %g %g %g\n",i, - k1[i],phi1[i]*180.0/MY_PI, - k2[i],phi2[i]*180.0/MY_PI, - k3[i],phi3[i]*180.0/MY_PI); - - fprintf(fp,"\nAngleAngleTorsion Coeffs\n\n"); - for (int i = 1; i <= atom->ndihedraltypes; i++) - fprintf(fp,"%d %g %g %g\n",i,aat_k[i], - aat_theta0_1[i]*180.0/MY_PI,aat_theta0_2[i]*180.0/MY_PI); - -} diff --git a/src/USER-MISC/dihedral_table_cut.h b/src/USER-MISC/dihedral_table_cut.h index d01903c88b..723d9a0d75 100644 --- a/src/USER-MISC/dihedral_table_cut.h +++ b/src/USER-MISC/dihedral_table_cut.h @@ -20,7 +20,6 @@ DihedralStyle(table/cut,DihedralTableCut) #ifndef LMP_DIHEDRAL_TABLE_CUT_H #define LMP_DIHEDRAL_TABLE_CUT_H -#include #include "dihedral.h" namespace LAMMPS_NS { @@ -34,26 +33,19 @@ class DihedralTableCut : public Dihedral { void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - void write_data(FILE *); double single(int type, int i1, int i2, int i3, int i4); protected: - double *k1,*k2,*k3; - double *phi1,*phi2,*phi3; double *aat_k,*aat_theta0_1,*aat_theta0_2; - int *setflag_d; - int *setflag_aat; void allocate(); int tabstyle,tablength; - // double *phi0; <- equilibrium angles not supported char *checkU_fname; char *checkF_fname; struct Table { int ninput; - //double phi0; <-equilibrium angles not supported int f_unspecified; // boolean (but MPI does not like type "bool") int use_degrees; // boolean (but MPI does not like type "bool") double *phifile,*efile,*ffile; -- GitLab From c0c61268ee0a44ba21ef398f0feab233e873814e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 19 Mar 2019 11:56:23 -0400 Subject: [PATCH 0264/1243] store only dihedral style info in restart, no coeffs --- src/USER-MISC/dihedral_table_cut.cpp | 13 ------------- src/USER-MISC/dihedral_table_cut.h | 1 - 2 files changed, 14 deletions(-) diff --git a/src/USER-MISC/dihedral_table_cut.cpp b/src/USER-MISC/dihedral_table_cut.cpp index 07d0af46b6..e9596df6c8 100644 --- a/src/USER-MISC/dihedral_table_cut.cpp +++ b/src/USER-MISC/dihedral_table_cut.cpp @@ -1006,10 +1006,6 @@ void DihedralTableCut::write_restart(FILE *fp) { fwrite(&tabstyle,sizeof(int),1,fp); fwrite(&tablength,sizeof(int),1,fp); - - fwrite(&aat_k[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&aat_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp); - fwrite(&aat_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp); } /* ---------------------------------------------------------------------- @@ -1023,19 +1019,10 @@ void DihedralTableCut::read_restart(FILE *fp) if (comm->me == 0) { fread(&tabstyle,sizeof(int),1,fp); fread(&tablength,sizeof(int),1,fp); - - fread(&aat_k[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&aat_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp); - fread(&aat_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp); } - MPI_Bcast(&aat_k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&aat_theta0_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); - MPI_Bcast(&aat_theta0_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world); MPI_Bcast(&tabstyle,1,MPI_INT,0,world); MPI_Bcast(&tablength,1,MPI_INT,0,world); - - for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1; } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/dihedral_table_cut.h b/src/USER-MISC/dihedral_table_cut.h index 723d9a0d75..dd645bedda 100644 --- a/src/USER-MISC/dihedral_table_cut.h +++ b/src/USER-MISC/dihedral_table_cut.h @@ -33,7 +33,6 @@ class DihedralTableCut : public Dihedral { void coeff(int, char **); void write_restart(FILE *); void read_restart(FILE *); - double single(int type, int i1, int i2, int i3, int i4); protected: double *aat_k,*aat_theta0_1,*aat_theta0_2; -- GitLab From e87e215bcc9d1746e760e869420eb264fffc6a47 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 19 Mar 2019 12:02:25 -0400 Subject: [PATCH 0265/1243] enable and correct write_data output for dihedral style spherical --- src/USER-MISC/dihedral_spherical.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/USER-MISC/dihedral_spherical.cpp b/src/USER-MISC/dihedral_spherical.cpp index 77fa885b7a..8ef41feac5 100644 --- a/src/USER-MISC/dihedral_spherical.cpp +++ b/src/USER-MISC/dihedral_spherical.cpp @@ -41,7 +41,9 @@ using namespace MathExtra; /* ---------------------------------------------------------------------- */ -DihedralSpherical::DihedralSpherical(LAMMPS *lmp) : Dihedral(lmp) {} +DihedralSpherical::DihedralSpherical(LAMMPS *lmp) : Dihedral(lmp) { + writedata = 1; +} /* ---------------------------------------------------------------------- */ @@ -817,10 +819,11 @@ void DihedralSpherical::write_data(FILE *fp) for (int i = 1; i <= atom->ndihedraltypes; i++) { fprintf(fp,"%d %d ", i , nterms[i]); for (int j = 0; j < nterms[i]; j++) { - fprintf(fp, "%g %g %g %g %g %g %g %g %g ", - phi_mult[i][j], phi_shift[i][j], phi_offset[i][j], - theta1_mult[i][j], theta1_shift[i][j], theta1_offset[i][j], - theta2_mult[i][j], theta2_shift[i][j], theta2_offset[i][j]); + fprintf(fp, "%g %g %g %g %g %g %g %g %g %g ", Ccoeff[i][j], + phi_mult[i][j], phi_shift[i][j]*180.0/MY_PI, phi_offset[i][j], + theta1_mult[i][j], theta1_shift[i][j]*180.0/MY_PI, + theta1_offset[i][j], theta2_mult[i][j], + theta2_shift[i][j]*180.0/MY_PI, theta2_offset[i][j]); } fprintf(fp,"\n"); } -- GitLab From 487671c46b42b3d0dd625e0df8db3c42fbf0176f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 19 Mar 2019 12:10:30 -0400 Subject: [PATCH 0266/1243] enable write_data functionality for more dihedral styles --- src/MOLECULE/dihedral_helix.cpp | 5 ++++- src/MOLECULE/dihedral_multi_harmonic.cpp | 5 ++++- src/USER-MISC/dihedral_cosine_shift_exp.cpp | 5 ++++- src/USER-MISC/dihedral_nharmonic.cpp | 3 ++- src/USER-MISC/dihedral_quadratic.cpp | 5 ++++- src/USER-MISC/dihedral_spherical.cpp | 3 ++- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp index ae23b77951..0998d654af 100644 --- a/src/MOLECULE/dihedral_helix.cpp +++ b/src/MOLECULE/dihedral_helix.cpp @@ -39,7 +39,10 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -DihedralHelix::DihedralHelix(LAMMPS *lmp) : Dihedral(lmp) {} +DihedralHelix::DihedralHelix(LAMMPS *lmp) : Dihedral(lmp) +{ + writedata = 1; +} /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/dihedral_multi_harmonic.cpp b/src/MOLECULE/dihedral_multi_harmonic.cpp index f6461abb6e..09c90f8d81 100644 --- a/src/MOLECULE/dihedral_multi_harmonic.cpp +++ b/src/MOLECULE/dihedral_multi_harmonic.cpp @@ -34,7 +34,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -DihedralMultiHarmonic::DihedralMultiHarmonic(LAMMPS *lmp) : Dihedral(lmp) {} +DihedralMultiHarmonic::DihedralMultiHarmonic(LAMMPS *lmp) : Dihedral(lmp) +{ + writedata = 1; +} /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/dihedral_cosine_shift_exp.cpp b/src/USER-MISC/dihedral_cosine_shift_exp.cpp index 82da173f8e..6a04228226 100644 --- a/src/USER-MISC/dihedral_cosine_shift_exp.cpp +++ b/src/USER-MISC/dihedral_cosine_shift_exp.cpp @@ -36,7 +36,10 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -DihedralCosineShiftExp::DihedralCosineShiftExp(LAMMPS *lmp) : Dihedral(lmp) {} +DihedralCosineShiftExp::DihedralCosineShiftExp(LAMMPS *lmp) : Dihedral(lmp) +{ + writedata = 1; +} /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/dihedral_nharmonic.cpp b/src/USER-MISC/dihedral_nharmonic.cpp index f8e8850680..aa3f6a6f3e 100644 --- a/src/USER-MISC/dihedral_nharmonic.cpp +++ b/src/USER-MISC/dihedral_nharmonic.cpp @@ -35,7 +35,8 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ -DihedralNHarmonic::DihedralNHarmonic(LAMMPS *lmp) : Dihedral(lmp) { +DihedralNHarmonic::DihedralNHarmonic(LAMMPS *lmp) : Dihedral(lmp) +{ writedata = 1; } diff --git a/src/USER-MISC/dihedral_quadratic.cpp b/src/USER-MISC/dihedral_quadratic.cpp index 1b64b52faf..c9bce4f02c 100644 --- a/src/USER-MISC/dihedral_quadratic.cpp +++ b/src/USER-MISC/dihedral_quadratic.cpp @@ -38,7 +38,10 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -DihedralQuadratic::DihedralQuadratic(LAMMPS *lmp) : Dihedral(lmp) {} +DihedralQuadratic::DihedralQuadratic(LAMMPS *lmp) : Dihedral(lmp) +{ + writedata = 1; +} /* ---------------------------------------------------------------------- */ diff --git a/src/USER-MISC/dihedral_spherical.cpp b/src/USER-MISC/dihedral_spherical.cpp index 8ef41feac5..8ce58243ac 100644 --- a/src/USER-MISC/dihedral_spherical.cpp +++ b/src/USER-MISC/dihedral_spherical.cpp @@ -41,7 +41,8 @@ using namespace MathExtra; /* ---------------------------------------------------------------------- */ -DihedralSpherical::DihedralSpherical(LAMMPS *lmp) : Dihedral(lmp) { +DihedralSpherical::DihedralSpherical(LAMMPS *lmp) : Dihedral(lmp) +{ writedata = 1; } -- GitLab From 02b800a3bbaf1b4ec1a5e023849ee66bf2cb47ad Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 19 Aug 2018 20:25:23 -0400 Subject: [PATCH 0267/1243] add template for new kim_query command --- src/.gitignore | 7 ++- src/KIM/kim_query.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++ src/KIM/kim_query.h | 85 +++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 src/KIM/kim_query.cpp create mode 100644 src/KIM/kim_query.h diff --git a/src/.gitignore b/src/.gitignore index d405cb209e..27f4f8a64c 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -26,6 +26,11 @@ /*_ssa.h /*_ssa.cpp +/kim_query.cpp +/kim_query.h +/pair_kim.cpp +/pair_kim.h + /kokkos.cpp /kokkos.h /kokkos_type.h @@ -818,8 +823,6 @@ /pair_hbond_dreiding_morse.h /pair_ilp_graphene_hbn.cpp /pair_ilp_graphene_hbn.h -/pair_kim.cpp -/pair_kim.h /pair_kolmogorov_crespi_full.cpp /pair_kolmogorov_crespi_full.h /pair_kolmogorov_crespi_z.cpp diff --git a/src/KIM/kim_query.cpp b/src/KIM/kim_query.cpp new file mode 100644 index 0000000000..1755b61417 --- /dev/null +++ b/src/KIM/kim_query.cpp @@ -0,0 +1,116 @@ +/* ---------------------------------------------------------------------- + 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: Axel Kohlmeyer (Temple U), + Ryan S. Elliott (UMN) +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + 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 the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, see . + + Linking LAMMPS statically or dynamically with other modules is making a + combined work based on LAMMPS. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + In addition, as a special exception, the copyright holders of LAMMPS give + you permission to combine LAMMPS with free software programs or libraries + that are released under the GNU LGPL and with code included in the standard + release of the "kim-api" under the CDDL (or modified versions of such code, + with unchanged license). You may copy and distribute such a system following + the terms of the GNU GPL for LAMMPS and the licenses of the other code + concerned, provided that you include the source code of that other code + when and as the GNU GPL requires distribution of source code. + + Note that people who make modified versions of LAMMPS are not obligated to + grant this special exception for their modified versions; it is their choice + whether to do so. The GNU General Public License gives permission to release + a modified version without this exception; this exception also makes it + possible to release a modified version which carries forward this exception. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package +------------------------------------------------------------------------- */ + +#include +#include +#include "kim_query.h" +#include "comm.h" +#include "error.h" +#include "input.h" +#include "variable.h" + +using namespace LAMMPS_NS; + +static char *do_query(char *, char *, int, MPI_Comm); + +/* ---------------------------------------------------------------------- */ + +void KimQuery::command(int narg, char **arg) +{ + char *model, *property, *varname, *value; + + if (narg != 3) error->all(FLERR,"Illegal kim_query command"); + + model = arg[0]; + property = arg[1]; + varname = arg[2]; + + value = do_query(model, property, comm->me, world); + + if (comm->me == 0) + printf("property %s for model %s is %s\n",property,model,value); + + char **varcmd = new char*[3]; + varcmd[0] = varname; + varcmd[1] = (char *) "string"; + varcmd[2] = value; + + input->variable->set(3,varcmd); + + delete[] varcmd; + delete[] value; +} + + +char *do_query(char *model, char *property, int rank, MPI_Comm comm) +{ + char val[512], *retval; + int len; + + // only run query from rank 0 + if (rank == 0) { + + // fake query + strcpy(val,(const char*)"4.25"); + } + MPI_Bcast(val, 512, MPI_CHAR, 0, comm); + len = strlen(val) + 1; + retval = new char[len]; + strcpy(retval,val); + + return retval; +} diff --git a/src/KIM/kim_query.h b/src/KIM/kim_query.h new file mode 100644 index 0000000000..92972d804d --- /dev/null +++ b/src/KIM/kim_query.h @@ -0,0 +1,85 @@ +/* -*- 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 authors: Axel Kohlmeyer (Temple U), + Ryan S. Elliott (UMN) +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + 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 the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, see . + + Linking LAMMPS statically or dynamically with other modules is making a + combined work based on LAMMPS. Thus, the terms and conditions of the GNU + General Public License cover the whole combination. + + In addition, as a special exception, the copyright holders of LAMMPS give + you permission to combine LAMMPS with free software programs or libraries + that are released under the GNU LGPL and with code included in the standard + release of the "kim-api" under the CDDL (or modified versions of such code, + with unchanged license). You may copy and distribute such a system following + the terms of the GNU GPL for LAMMPS and the licenses of the other code + concerned, provided that you include the source code of that other code + when and as the GNU GPL requires distribution of source code. + + Note that people who make modified versions of LAMMPS are not obligated to + grant this special exception for their modified versions; it is their choice + whether to do so. The GNU General Public License gives permission to release + a modified version without this exception; this exception also makes it + possible to release a modified version which carries forward this exception. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package +------------------------------------------------------------------------- */ + +#ifdef COMMAND_CLASS + +CommandStyle(kim_query,KimQuery) + +#else + +#ifndef LMP_KIM_QUERY_H +#define LMP_KIM_QUERY_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class KimQuery : protected Pointers { + public: + KimQuery(class LAMMPS *lmp) : Pointers(lmp) {}; + void command(int, char **); + +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + + +*/ -- GitLab From 7a8bb5baaf938f7534c9f0aee2231ff1a744a2f8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 19 Aug 2018 21:18:03 -0400 Subject: [PATCH 0268/1243] come code cleanup and refactoring --- src/KIM/kim_query.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/KIM/kim_query.cpp b/src/KIM/kim_query.cpp index 1755b61417..17f993c92d 100644 --- a/src/KIM/kim_query.cpp +++ b/src/KIM/kim_query.cpp @@ -81,8 +81,13 @@ void KimQuery::command(int narg, char **arg) value = do_query(model, property, comm->me, world); - if (comm->me == 0) - printf("property %s for model %s is %s\n",property,model,value); + // check for valid result + + int len = strlen(value) + 1; + if (len == 1) { + // TODO: store more detailed error message after \0 byte. + error->all(FLERR,"Query of OpenKIM database failed"); + } char **varcmd = new char*[3]; varcmd[0] = varname; @@ -98,19 +103,21 @@ void KimQuery::command(int narg, char **arg) char *do_query(char *model, char *property, int rank, MPI_Comm comm) { - char val[512], *retval; - int len; + char value[512], *retval; // only run query from rank 0 if (rank == 0) { // fake query - strcpy(val,(const char*)"4.25"); + strcpy(value,(const char*)"4.25"); } - MPI_Bcast(val, 512, MPI_CHAR, 0, comm); - len = strlen(val) + 1; + MPI_Bcast(value, 512, MPI_CHAR, 0, comm); + + // must make a proper copy of the query, as the stack allocation + // will go out of scope + + int len = strlen(value) + 1; retval = new char[len]; - strcpy(retval,val); - + strcpy(retval,value); return retval; } -- GitLab From 741a7fe630d5e445163115c897db5aba74455f7f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 20 Aug 2018 18:56:40 -0400 Subject: [PATCH 0269/1243] final touches to support compiling with libcurl transparently --- examples/kim/in.query | 11 ++ examples/kim/log.16Aug2018.query.g++.1 | 34 ++++++ lib/kim/Makefile.lammps | 7 +- lib/kim/README | 6 + src/KIM/kim_query.cpp | 156 +++++++++++++++++++++---- 5 files changed, 191 insertions(+), 23 deletions(-) create mode 100644 examples/kim/in.query create mode 100644 examples/kim/log.16Aug2018.query.g++.1 diff --git a/examples/kim/in.query b/examples/kim/in.query new file mode 100644 index 0000000000..8538cac749 --- /dev/null +++ b/examples/kim/in.query @@ -0,0 +1,11 @@ + +# example for performing a query to the OpenKIM test database to retrieve +# a parameter to be used in the input. here it requests the aluminium +# lattice constant for a specific test used for a specific model and then +# assigns it to the variable 'latconst' + +units metal +info variables out log +kim_query latconst get_test_result test=TE_156715955670_004 species=["Al"] model=MO_800509458712_001 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"] +info variables out log +lattice fcc ${latconst} diff --git a/examples/kim/log.16Aug2018.query.g++.1 b/examples/kim/log.16Aug2018.query.g++.1 new file mode 100644 index 0000000000..eb83dd84b1 --- /dev/null +++ b/examples/kim/log.16Aug2018.query.g++.1 @@ -0,0 +1,34 @@ +LAMMPS (16 Aug 2018) + +# example for performing a query to the OpenKIM test database to retrieve +# a parameter to be used in the input. here it requests the aluminium +# lattice constant for a specific test used for a specific model and then +# assigns it to the variable 'latconst' + +units metal +info variables out log + +Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info +Printed on Mon Aug 20 18:44:24 2018 + + +Variable information: + +Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info + +kim_query latconst get_test_result test=TE_156715955670_004 species=["Al"] model=MO_800509458712_001 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"] +info variables out log + +Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info +Printed on Mon Aug 20 18:44:24 2018 + + +Variable information: +Variable[ 0]: latconst , style = string , def = 4.0320827961 + +Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info + +lattice fcc ${latconst} +lattice fcc 4.0320827961 +Lattice spacing in x,y,z = 4.03208 4.03208 4.03208 +Total wall time: 0:00:00 diff --git a/lib/kim/Makefile.lammps b/lib/kim/Makefile.lammps index 7c9fc7c5f7..492b9ddfc6 100644 --- a/lib/kim/Makefile.lammps +++ b/lib/kim/Makefile.lammps @@ -17,13 +17,18 @@ ifeq ($(strip $(shell pkg-config --version)),) $(error 'pkg-config' not found, but is required to configure the KIM API) endif - kim_PREFIX := $(shell cat ../../lib/kim/kim-prefix.txt 2> /dev/null) kim_PREFIX := $(if $(kim_PREFIX),$(kim_PREFIX)/lib/pkgconfig,) kim_PREFIX := $(if $(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX):$(shell printf -- "$${PKG_CONFIG_PATH}"),$(kim_PREFIX)) +# there is no usable libcurl installation +ifeq ($(shell curl-config --version 2> /dev/null),) kim_SYSINC := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --cflags libkim-api-v2 2> /dev/null) kim_SYSLIB := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --libs libkim-api-v2 2> /dev/null) +else +kim_SYSINC := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --cflags libkim-api-v2 2> /dev/null) $(shell curl-config --cflags) -DLMP_KIM_CURL +kim_SYSLIB := $(shell export PKG_CONFIG_PATH="$(kim_PREFIX)"; pkg-config --libs libkim-api-v2 2> /dev/null) $(shell curl-config --libs) +endif ifeq ($(strip $(kim_SYSINC)),) $(error 'pkg-config' could not find an installed KIM API library.) diff --git a/lib/kim/README b/lib/kim/README index 0e51a30870..493758561d 100644 --- a/lib/kim/README +++ b/lib/kim/README @@ -13,6 +13,12 @@ do the same thing by typing "python Install.py" from within this directory, or you can do it manually by following the instructions below. +As of KIM API version 2, the KIM package also provides a LAMMPS command +to perform queries through the OpenKIM web API. This feature requires +that the CURL library (libcurl) development package and its configuration +query tool, curl-config, are installed. The provided Makefile.lammps +is set up to automatically detect this. + ----------------- Instructions: diff --git a/src/KIM/kim_query.cpp b/src/KIM/kim_query.cpp index 17f993c92d..8d400ac333 100644 --- a/src/KIM/kim_query.cpp +++ b/src/KIM/kim_query.cpp @@ -57,36 +57,55 @@ #include #include +#include #include "kim_query.h" #include "comm.h" #include "error.h" #include "input.h" #include "variable.h" +#include +#include + using namespace LAMMPS_NS; -static char *do_query(char *, char *, int, MPI_Comm); +#if defined(LMP_KIM_CURL) + +struct WriteBuf { + char *dataptr; + size_t sizeleft; +}; + +static char *do_query(char *, int, char **, int, MPI_Comm); +static size_t write_callback(void *, size_t, size_t, void *); + +#endif /* ---------------------------------------------------------------------- */ void KimQuery::command(int narg, char **arg) { - char *model, *property, *varname, *value; + char *varname, *function, *value; - if (narg != 3) error->all(FLERR,"Illegal kim_query command"); + if (narg < 2) error->all(FLERR,"Illegal kim_query command"); - model = arg[0]; - property = arg[1]; - varname = arg[2]; + varname = arg[0]; + function = arg[1]; - value = do_query(model, property, comm->me, world); +#if defined(LMP_KIM_CURL) + + value = do_query(function, narg-2, arg+2, comm->me, world); // check for valid result + // on error the content of "value" is a '\0' byte + // as the first element, and then the error message + // that was returned by the web server + + if (0 == strlen(value)) { + char errmsg[512]; - int len = strlen(value) + 1; - if (len == 1) { - // TODO: store more detailed error message after \0 byte. - error->all(FLERR,"Query of OpenKIM database failed"); + sprintf(errmsg,"OpenKIM query failed: %s",value+1); + error->all(FLERR,errmsg); } char **varcmd = new char*[3]; @@ -98,26 +117,119 @@ void KimQuery::command(int narg, char **arg) delete[] varcmd; delete[] value; +#else + error->all(FLERR,"Cannot use 'kim_query' command when KIM package " + "is compiled without support for libcurl"); +#endif } +#if defined(LMP_KIM_CURL) -char *do_query(char *model, char *property, int rank, MPI_Comm comm) +// copy data to the user provided data structure, optionally in increments + +size_t write_callback(void *data, size_t size, size_t nmemb, void *userp) +{ + struct WriteBuf *buf = (struct WriteBuf *)userp; + size_t buffer_size = size*nmemb; + + // copy chunks into the buffer for as long as there is space left + if (buf->sizeleft) { + size_t copy_this_much = buf->sizeleft; + if (copy_this_much > buffer_size) + copy_this_much = buffer_size; + memcpy(buf->dataptr, data, copy_this_much); + + buf->dataptr += copy_this_much; + buf->sizeleft -= copy_this_much; + return copy_this_much; + } + return 0; // done +} + +char *do_query(char *qfunction, int narg, char **arg, int rank, MPI_Comm comm) { char value[512], *retval; - // only run query from rank 0 - if (rank == 0) { + // run the web query from rank 0 only - // fake query - strcpy(value,(const char*)"4.25"); + if (rank == 0) { + CURL *handle; + CURLcode res; + + // set up and clear receive buffer + + struct WriteBuf buf; + buf.dataptr = value; + buf.sizeleft = 511; + memset(value,0,512); + + // create curl web query instance + curl_global_init(CURL_GLOBAL_DEFAULT); + handle = curl_easy_init(); + + if (handle) { + std::string url("https://query.openkim.org/api/"); + url += qfunction; + + std::string query(arg[0]); + for (int i=1; i < narg; ++i) { + query += '&'; + query += arg[i]; + } + +#if LMP_DEBUG_CURL + curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); +#endif + +#if defined(LMP_NO_SSL_CHECK) + // disable verifying SSL certificate and host name + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L); +#endif + + curl_easy_setopt(handle, CURLOPT_URL, url.c_str()); + curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(handle, CURLOPT_POSTFIELDS, query.c_str()); + + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,write_callback); + curl_easy_setopt(handle, CURLOPT_WRITEDATA,&buf); + + // perform OpenKIM query and check for errors + res = curl_easy_perform(handle); + if (res != CURLE_OK) { + // on error we return an "empty" string but add error message after it + value[0]= '\0'; + strcpy(value+1,curl_easy_strerror(res)); + } + curl_easy_cleanup(handle); + } + curl_global_cleanup(); } MPI_Bcast(value, 512, MPI_CHAR, 0, comm); - // must make a proper copy of the query, as the stack allocation - // will go out of scope - - int len = strlen(value) + 1; - retval = new char[len]; - strcpy(retval,value); + // we must make a proper copy of the query, as the stack allocation + // for "value" will go out of scope. a valid query has a '[' as + // the first character. skip over it (and the last character ']', too) + // an error messages starts with a '\0' character. copy that and + // the remaining string, as that is the error message. + + if (value[0] == '[') { + int len = strlen(value)-1; + retval = new char[len]; + value[len] = '\0'; + strcpy(retval,value+1); + } else if (value[0] == '\0') { + int len = strlen(value+1)+2; + retval = new char[len]; + retval[0] = '\0'; + strcpy(retval+1,value+1); + } else { + // unknown response type. we should not get here. + // copy response without modifications. + int len = strlen(value)+1; + retval = new char[len]; + strcpy(retval,value); + } return retval; } +#endif -- GitLab From 38c373a0e41d4f4d07d0624187680eb55b46c5d7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 20 Aug 2018 21:29:32 -0400 Subject: [PATCH 0270/1243] integrate new kim_query command into the documentation environment --- doc/src/Build_extras.txt | 4 +++- doc/src/Packages_details.txt | 2 ++ doc/src/commands_list.txt | 1 + doc/src/kim_query.txt | 46 ++++++++++++++++++++++++++++++++++++ doc/src/lammps.book | 1 + doc/src/pair_kim.txt | 9 +++---- 6 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 doc/src/kim_query.txt diff --git a/doc/src/Build_extras.txt b/doc/src/Build_extras.txt index cbbd9db2f3..c096b5901b 100644 --- a/doc/src/Build_extras.txt +++ b/doc/src/Build_extras.txt @@ -171,7 +171,9 @@ KIM package :h4,link(kim) To build with this package, the KIM library must be downloaded and built on your system. It must include the KIM models that you want to -use with LAMMPS. +use with LAMMPS. If you want to use the "kim_query"_kim_query.html +command, you also need to have libcurl installed with the matching +development headers and the curl-config tool. Note that in LAMMPS lingo, a KIM model driver is a pair style (e.g. EAM or Tersoff). A KIM model is a pair style for a particular diff --git a/doc/src/Packages_details.txt b/doc/src/Packages_details.txt index 3a362a23d0..0ab1b5e4fd 100644 --- a/doc/src/Packages_details.txt +++ b/doc/src/Packages_details.txt @@ -341,6 +341,8 @@ KIM package :link(PKG-KIM),h4 A "pair_style kim"_pair_kim.html command which is a wrapper on the Knowledge Base for Interatomic Models (KIM) repository of interatomic potentials, enabling any of them to be used in LAMMPS simulations. +Also a "kim_query"_kim_query.html command, which allows to query +the OpenKIM database for stored properties. To use this package you must have the KIM library available on your system. diff --git a/doc/src/commands_list.txt b/doc/src/commands_list.txt index 27e0906b5f..61221b26d8 100644 --- a/doc/src/commands_list.txt +++ b/doc/src/commands_list.txt @@ -53,6 +53,7 @@ Commands :h1 include info jump + kim_query kspace_modify kspace_style label diff --git a/doc/src/kim_query.txt b/doc/src/kim_query.txt new file mode 100644 index 0000000000..61f8bf12ae --- /dev/null +++ b/doc/src/kim_query.txt @@ -0,0 +1,46 @@ +"LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +kim_query command :h3 + +[Syntax:] + +kim_query variable query_function web_query_flags :pre + +variable = name of a (string style) variable where the result of the query is stored +query_function = name of the OpenKIM web API query function to be used +web_query_flags = a series of keyword=value pairs that represent the web query; supported keywords depend on query function :ul + +[Examples:] + +kim_query latconst get_test_result test=TE_156715955670_004 model=MO_800509458712_001 & + prop=structure-cubic-crystal-npt species=\["Al"\] keys=\["a"\] units=\["angstrom"\] :pre + +[Description:] + +The kim_query command allows to retrieve properties from the OpenKIM +through a web query. The result is stored in a string style +"variable"_variable.html, the name of which must be given as the first +argument of the kim_query command. The second required argument is the +name of the actual query function (e.g. {get_test_result}). All following +arguments are parameters handed over to the web query in the format +{keyword=value}. This list of supported keywords and the type of how +the value has to be encoded depends on the query function used. +For more details on this, please refer to the OpenKIM homepage. + +[Restrictions:] + +This command is part of the KIM package. It is only enabled if +LAMMPS was built with that package. Furthermore, its correct +functioning is dependend on compiling LAMMPS with libcurl support. +See the "Build package"_Build_package.html doc page for more info. + +[Related commands:] + +"pair_style kim"_pair_kim.html, "variable"_variable.html + diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 198e234f0c..6b220ed241 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -167,6 +167,7 @@ if.html include.html info.html jump.html +kim_query.html label.html lattice.html log.html diff --git a/doc/src/pair_kim.txt b/doc/src/pair_kim.txt index c5d42403e3..a415ac606b 100644 --- a/doc/src/pair_kim.txt +++ b/doc/src/pair_kim.txt @@ -42,12 +42,9 @@ section of the "Packages details"_Packages_details.html doc page has instructions on how to do this with a simple make command, when building LAMMPS. -See the examples/kim dir for an input script that uses a KIM model (potential) -for Lennard-Jones. Note, for this example input script, the example models -shipped with with kim-api package must be installed. See the "Build -package"_Build_package.html section and the ./lib/kim/README for details -on how to build LAMMSPS with the kim-api and how to install the example models. - +See the examples/kim dir for an input script that uses a KIM model +(potential) for Lennard-Jones. + :line The argument {model} is the name of the KIM model for a specific -- GitLab From fed48427be9ee74c21cdf6fa5edc2b37bf4df95c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 20 Aug 2018 22:15:02 -0400 Subject: [PATCH 0271/1243] update lib/kim/Install.py to support md5 checksum. update CMake support as needed --- cmake/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f6f822676e..601aa4b7c4 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -670,6 +670,12 @@ if(PKG_USER-VTK) endif() if(PKG_KIM) + find_package(CURL) + if(CURL_FOUND) + include_directories(${CURL_INCLUDE_DIRS}) + list(APPEND LAMMPS_LINK_LIBS ${CURL_LIBRARIES}) + add_definitions(-DLMP_KIM_CURL) + endif() option(DOWNLOAD_KIM "Download KIM-API v2 from OpenKIM instead of using an already installed one" OFF) if(DOWNLOAD_KIM) message(STATUS "KIM-API v2 download requested - we will build our own") -- GitLab From 1c3e3ce5481144b77bc438de5bb1cdcfceb0b055 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 19 Mar 2019 15:57:19 -0400 Subject: [PATCH 0272/1243] add kim_query command to commands list --- doc/src/Commands_all.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/Commands_all.txt b/doc/src/Commands_all.txt index 155b56ace8..ddb8e121cb 100644 --- a/doc/src/Commands_all.txt +++ b/doc/src/Commands_all.txt @@ -68,6 +68,7 @@ An alphabetic list of all general LAMMPS commands. "improper_style"_improper_style.html, "include"_include.html, "jump"_jump.html, +"kim_query"_kim_query.html, "kspace_modify"_kspace_modify.html, "kspace_style"_kspace_style.html, "label"_label.html, -- GitLab From 2dbc2c59169533d3fe2e8ad0897abf7288d8afd4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 19 Mar 2019 16:04:53 -0400 Subject: [PATCH 0273/1243] fix spelling issues in documentation and some minor clarification --- doc/src/Build_extras.txt | 10 +++++----- doc/src/kim_query.txt | 2 +- doc/utils/sphinx-config/false_positives.txt | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/src/Build_extras.txt b/doc/src/Build_extras.txt index c096b5901b..66f1c8fcbd 100644 --- a/doc/src/Build_extras.txt +++ b/doc/src/Build_extras.txt @@ -169,8 +169,8 @@ used to build the GPU library. KIM package :h4,link(kim) -To build with this package, the KIM library must be downloaded and -built on your system. It must include the KIM models that you want to +To build with this package, the KIM library with API v2 must be downloaded +and built on your system. It must include the KIM models that you want to use with LAMMPS. If you want to use the "kim_query"_kim_query.html command, you also need to have libcurl installed with the matching development headers and the curl-config tool. @@ -178,9 +178,9 @@ development headers and the curl-config tool. Note that in LAMMPS lingo, a KIM model driver is a pair style (e.g. EAM or Tersoff). A KIM model is a pair style for a particular element or alloy and set of parameters, e.g. EAM for Cu with a -specific EAM potential file. Also note that installing the KIM API -library with all its models, may take around 30 min to build. Of -course you only need to do that once. +specific EAM potential file. Also note that downloading and installing +the KIM API library with all its models, may take a long time (10s of +minutes to hours) to build. Of course you only need to do that once. See the list of KIM model drivers here: https://openkim.org/browse/model-drivers/alphabetical diff --git a/doc/src/kim_query.txt b/doc/src/kim_query.txt index 61f8bf12ae..ffebe698be 100644 --- a/doc/src/kim_query.txt +++ b/doc/src/kim_query.txt @@ -37,7 +37,7 @@ For more details on this, please refer to the OpenKIM homepage. This command is part of the KIM package. It is only enabled if LAMMPS was built with that package. Furthermore, its correct -functioning is dependend on compiling LAMMPS with libcurl support. +functioning depends on compiling LAMMPS with libcurl support. See the "Build package"_Build_package.html doc page for more info. [Related commands:] diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 5366a31d5d..6eb158396f 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1382,6 +1382,7 @@ libAtoms libawpmd libch libcolvars +libcurl libdir libdl libfftw -- GitLab From 08273c40d7489c7015b600ff7b9b5f4a7d029313 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 19 Mar 2019 14:29:45 -0600 Subject: [PATCH 0274/1243] Fix compile issue in comm_kokkos --- src/KOKKOS/comm_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index c6d8424c27..4396637153 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -661,8 +661,8 @@ void CommKokkos::exchange_device() } auto k_exchange_copylist_short = Kokkos::subview(k_exchange_copylist,k_count.h_view()); - k_exchange_copylist_short.modify(); - k_exchange_copylist_short.sync(); + k_exchange_copylist_short.template modify(); + k_exchange_copylist_short.template sync(); nsend = k_count.h_view(); if (nsend > maxsend) grow_send_kokkos(nsend,1); nsend = -- GitLab From a508f1de6c8001b7c70cf75330663faf06996818 Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 19 Mar 2019 22:30:44 -0600 Subject: [PATCH 0275/1243] Commit JT 031919 - correct. error in fix_prec_spin - added min_post_force in fix_prec_spin --- src/SPIN/fix_precession_spin.cpp | 17 +++++++++++++---- src/SPIN/fix_precession_spin.h | 5 +++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index d3edb3ae8a..433a260e83 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -115,6 +115,7 @@ int FixPrecessionSpin::setmask() { int mask = 0; mask |= POST_FORCE; + mask |= MIN_POST_FORCE; mask |= THERMO_ENERGY; mask |= POST_FORCE_RESPA; return mask; @@ -171,6 +172,7 @@ void FixPrecessionSpin::setup(int vflag) void FixPrecessionSpin::post_force(int /*vflag*/) { + // update mag field with time (potential improvement) if (varflag != CONSTANT) { @@ -200,7 +202,7 @@ void FixPrecessionSpin::post_force(int /*vflag*/) if (aniso_flag) { // compute magnetic anisotropy compute_anisotropy(spi,fmi); - emag -= (spi[0]*fmi[0] + spi[1]*fmi[1] + spi[2]*fmi[2]); + emag -= 0.5*(spi[0]*fmi[0] + spi[1]*fmi[1] + spi[2]*fmi[2]); } fm[i][0] += fmi[0]; @@ -228,9 +230,9 @@ void FixPrecessionSpin::compute_single_precession(int i, double spi[3], double f void FixPrecessionSpin::compute_zeeman(int i, double fmi[3]) { double **sp = atom->sp; - fmi[0] -= sp[i][3]*hx; - fmi[1] -= sp[i][3]*hy; - fmi[2] -= sp[i][3]*hz; + fmi[0] += sp[i][0]*hx; + fmi[1] += sp[i][1]*hy; + fmi[2] += sp[i][3]*hz; } /* ---------------------------------------------------------------------- */ @@ -280,3 +282,10 @@ double FixPrecessionSpin::compute_scalar() } return emag_all; } + +/* ---------------------------------------------------------------------- */ + +void FixPrecessionSpin::min_post_force(int vflag) +{ + post_force(vflag); +} diff --git a/src/SPIN/fix_precession_spin.h b/src/SPIN/fix_precession_spin.h index 53ae4ba124..2fe6b5a673 100644 --- a/src/SPIN/fix_precession_spin.h +++ b/src/SPIN/fix_precession_spin.h @@ -33,8 +33,9 @@ class FixPrecessionSpin : public Fix { int setmask(); void init(); void setup(int); - virtual void post_force(int); - virtual void post_force_respa(int, int, int); + void post_force(int); + void post_force_respa(int, int, int); + void min_post_force(int); double compute_scalar(); int zeeman_flag, aniso_flag; -- GitLab From 86810c2d7ccab32a9f0019e94d9197ae5d85bafc Mon Sep 17 00:00:00 2001 From: julient31 Date: Tue, 19 Mar 2019 22:44:26 -0600 Subject: [PATCH 0276/1243] Commit2 JT 031919 - correct error in fix_precession_spin - only the sign of the force needed a correction --- src/SPIN/fix_precession_spin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index 433a260e83..6ccb692033 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -230,8 +230,8 @@ void FixPrecessionSpin::compute_single_precession(int i, double spi[3], double f void FixPrecessionSpin::compute_zeeman(int i, double fmi[3]) { double **sp = atom->sp; - fmi[0] += sp[i][0]*hx; - fmi[1] += sp[i][1]*hy; + fmi[0] += sp[i][3]*hx; + fmi[1] += sp[i][3]*hy; fmi[2] += sp[i][3]*hz; } -- GitLab From 2cbf56846a28fe7ffc751b0fd270d17a80c73653 Mon Sep 17 00:00:00 2001 From: julient31 Date: Wed, 20 Mar 2019 10:41:36 -0600 Subject: [PATCH 0277/1243] Commit JT 032019 - moved gneb files from src/REPLICA to src/SPIN - changed name of min/spin - implemented read_param in min.cpp and min_spin.cpp - set sp_flag tests in min_spin.cpp and neb_spin.cpp --- doc/src/min_style.txt | 12 ++-- examples/SPIN/gneb/in.gneb.iron | 2 +- examples/SPIN/spinmin/in.spinmin.bfo | 2 +- examples/SPIN/spinmin/in.spinmin.iron | 2 +- src/SPIN/README | 5 +- src/{REPLICA => SPIN}/fix_neb_spin.cpp | 0 src/{REPLICA => SPIN}/fix_neb_spin.h | 0 src/SPIN/fix_precession_spin.cpp | 4 +- src/SPIN/{min_spinmin.cpp => min_spin.cpp} | 41 ++++++++--- src/SPIN/{min_spinmin.h => min_spin.h} | 16 +++-- src/{REPLICA => SPIN}/neb_spin.cpp | 79 ++++++++++++++++++++-- src/{REPLICA => SPIN}/neb_spin.h | 0 src/min.cpp | 14 ++-- src/min.h | 6 +- 14 files changed, 133 insertions(+), 50 deletions(-) rename src/{REPLICA => SPIN}/fix_neb_spin.cpp (100%) rename src/{REPLICA => SPIN}/fix_neb_spin.h (100%) rename src/SPIN/{min_spinmin.cpp => min_spin.cpp} (90%) rename src/SPIN/{min_spinmin.h => min_spin.h} (78%) rename src/{REPLICA => SPIN}/neb_spin.cpp (93%) rename src/{REPLICA => SPIN}/neb_spin.h (100%) diff --git a/doc/src/min_style.txt b/doc/src/min_style.txt index b1a9da997d..f8c05d5483 100644 --- a/doc/src/min_style.txt +++ b/doc/src/min_style.txt @@ -11,7 +11,7 @@ min_style command :h3 min_style style :pre -style = {cg} or {hftn} or {sd} or {quickmin} or {fire} or {spinmin} :ul +style = {cg} or {hftn} or {sd} or {quickmin} or {fire} or {spin} :ul [Examples:] @@ -62,18 +62,14 @@ the velocity non-parallel to the current force vector. The velocity of each atom is initialized to 0.0 by this style, at the beginning of a minimization. -Style {spinmin} is a damped spin dynamics with a variable +Style {spin} is a damped spin dynamics with a variable timestep as described in "(Tranchida)"_#Tranchida. -The value of the fictitious Gilbert damping and of the dividing -factor for the adaptive timestep can be modified by the -{alpha_damp} and {discret_factor} options respectively. -Those options can be defined using the "min_modify"_min_modify.html -command. +See the "min/spin"_min_spin.html doc page for more information. Either the {quickmin} and {fire} styles are useful in the context of nudged elastic band (NEB) calculations via the "neb"_neb.html command. -The {spinmin} style is useful in the context of geodesic nudged +The {spin} style is useful in the context of geodesic nudged elastic band (GNEB) calculations via the "neb/spin"_neb_spin.html command. diff --git a/examples/SPIN/gneb/in.gneb.iron b/examples/SPIN/gneb/in.gneb.iron index 7aab0c04c3..a8028392a1 100644 --- a/examples/SPIN/gneb/in.gneb.iron +++ b/examples/SPIN/gneb/in.gneb.iron @@ -55,7 +55,7 @@ variable u universe 1 2 3 4 #dump 1 all custom 100 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] dump 1 all custom 200 dump.$u type x y z c_outsp[1] c_outsp[2] c_outsp[3] -min_style spinmin +min_style spin min_modify alpha_damp 1.0 discret_factor 10.0 neb/spin 1.0e-12 1.0e-12 50000 50000 10 final final.iron_spin #neb/spin 1.0e-6 1.0e-6 1000 10 10 final final.iron_spin diff --git a/examples/SPIN/spinmin/in.spinmin.bfo b/examples/SPIN/spinmin/in.spinmin.bfo index a00af8833c..5b678c8a4d 100644 --- a/examples/SPIN/spinmin/in.spinmin.bfo +++ b/examples/SPIN/spinmin/in.spinmin.bfo @@ -52,6 +52,6 @@ thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 1 all custom 50 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] -min_style spinmin +min_style spin min_modify alpha_damp 1.0 discret_factor 10.0 minimize 0.0 0.0 10000 1000 diff --git a/examples/SPIN/spinmin/in.spinmin.iron b/examples/SPIN/spinmin/in.spinmin.iron index 5a15082122..b87a811cc7 100644 --- a/examples/SPIN/spinmin/in.spinmin.iron +++ b/examples/SPIN/spinmin/in.spinmin.iron @@ -52,6 +52,6 @@ thermo_modify format float %20.15g compute outsp all property/atom spx spy spz sp fmx fmy fmz dump 1 all custom 100 dump.lammpstrj type x y z c_outsp[1] c_outsp[2] c_outsp[3] c_outsp[4] c_outsp[5] c_outsp[6] c_outsp[7] -min_style spinmin +min_style spin min_modify alpha_damp 1.0 discret_factor 10.0 minimize 1.0e-10 1.0e-10 100000 1000 diff --git a/src/SPIN/README b/src/SPIN/README index e371e39767..c3c02b1445 100644 --- a/src/SPIN/README +++ b/src/SPIN/README @@ -8,13 +8,16 @@ atom in the system * integrating the equations of motion for the coupled spin-lattice system * implementing magnetic pair interactions and magnetic forces * thermostating and applying a transverse damping to the magnetic spins +* minimizing spin configurations with an adaptive timestep scheme +* performing geodesic NEB calculations * computing and outputing magnetic quantities The different options provided by this package are explained in the LAMMPS documentation. Once you have successfully built LAMMPS with this package, you can test -it using one of the input files provided from the examples/SPIN dir: +it using one of the input files provided from the examples/SPIN dir. +For example: ./lmp_serial < lammps/examples/SPIN/cobalt_hcp/in.spin.cobalt_hcp diff --git a/src/REPLICA/fix_neb_spin.cpp b/src/SPIN/fix_neb_spin.cpp similarity index 100% rename from src/REPLICA/fix_neb_spin.cpp rename to src/SPIN/fix_neb_spin.cpp diff --git a/src/REPLICA/fix_neb_spin.h b/src/SPIN/fix_neb_spin.h similarity index 100% rename from src/REPLICA/fix_neb_spin.h rename to src/SPIN/fix_neb_spin.h diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index 433a260e83..6ccb692033 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -230,8 +230,8 @@ void FixPrecessionSpin::compute_single_precession(int i, double spi[3], double f void FixPrecessionSpin::compute_zeeman(int i, double fmi[3]) { double **sp = atom->sp; - fmi[0] += sp[i][0]*hx; - fmi[1] += sp[i][1]*hy; + fmi[0] += sp[i][3]*hx; + fmi[1] += sp[i][3]*hy; fmi[2] += sp[i][3]*hz; } diff --git a/src/SPIN/min_spinmin.cpp b/src/SPIN/min_spin.cpp similarity index 90% rename from src/SPIN/min_spinmin.cpp rename to src/SPIN/min_spin.cpp index 808a5359bc..ac8f22186e 100644 --- a/src/SPIN/min_spinmin.cpp +++ b/src/SPIN/min_spin.cpp @@ -19,7 +19,7 @@ #include #include -#include "min_spinmin.h" +#include "min_spin.h" #include "universe.h" #include "atom.h" #include "force.h" @@ -27,7 +27,6 @@ #include "output.h" #include "timer.h" #include "error.h" - #include #include #include "modify.h" @@ -46,11 +45,11 @@ using namespace MathConst; /* ---------------------------------------------------------------------- */ -MinSpinMin::MinSpinMin(LAMMPS *lmp) : Min(lmp) {} +MinSpin::MinSpin(LAMMPS *lmp) : Min(lmp) {} /* ---------------------------------------------------------------------- */ -void MinSpinMin::init() +void MinSpin::init() { alpha_damp = 1.0; discret_factor = 10.0; @@ -63,21 +62,43 @@ void MinSpinMin::init() /* ---------------------------------------------------------------------- */ -void MinSpinMin::setup_style() +void MinSpin::setup_style() { double **v = atom->v; int nlocal = atom->nlocal; + // check if the atom/spin style is defined + + if (!atom->sp_flag) + error->all(FLERR,"min/spin requires atom/spin style"); + for (int i = 0; i < nlocal; i++) v[i][0] = v[i][1] = v[i][2] = 0.0; } +/* ---------------------------------------------------------------------- */ + +int MinSpin::modify_param(int narg, char **arg) +{ + if (strcmp(arg[0],"alpha_damp") == 0) { + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + alpha_damp = force->numeric(FLERR,arg[1]); + return 2; + } + if (strcmp(arg[0],"discret_factor") == 0) { + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + discret_factor = force->numeric(FLERR,arg[1]); + return 2; + } + return 0; +} + /* ---------------------------------------------------------------------- set current vector lengths and pointers called after atoms have migrated ------------------------------------------------------------------------- */ -void MinSpinMin::reset_vectors() +void MinSpin::reset_vectors() { // atomic dof @@ -96,7 +117,7 @@ void MinSpinMin::reset_vectors() minimization via damped spin dynamics ------------------------------------------------------------------------- */ -int MinSpinMin::iterate(int maxiter) +int MinSpin::iterate(int maxiter) { bigint ntimestep; double fmdotfm,fmdotfmall; @@ -172,7 +193,7 @@ int MinSpinMin::iterate(int maxiter) evaluate max timestep ---------------------------------------------------------------------- */ -double MinSpinMin::evaluate_dt() +double MinSpin::evaluate_dt() { double dtmax; double fmsq; @@ -218,7 +239,7 @@ double MinSpinMin::evaluate_dt() geometric damped advance of spins ---------------------------------------------------------------------- */ -void MinSpinMin::advance_spins(double dts) +void MinSpin::advance_spins(double dts) { int nlocal = atom->nlocal; int *mask = atom->mask; @@ -282,7 +303,7 @@ void MinSpinMin::advance_spins(double dts) compute and return ||mag. torque||_2^2 ------------------------------------------------------------------------- */ -double MinSpinMin::fmnorm_sqr() +double MinSpin::fmnorm_sqr() { int i,n; double *fmatom; diff --git a/src/SPIN/min_spinmin.h b/src/SPIN/min_spin.h similarity index 78% rename from src/SPIN/min_spinmin.h rename to src/SPIN/min_spin.h index abc532a3d5..569bcbaab2 100644 --- a/src/SPIN/min_spinmin.h +++ b/src/SPIN/min_spin.h @@ -13,23 +13,24 @@ #ifdef MINIMIZE_CLASS -MinimizeStyle(spinmin,MinSpinMin) +MinimizeStyle(spin,MinSpin) #else -#ifndef LMP_MIN_SPINMIN_H -#define LMP_MIN_SPINMIN_H +#ifndef LMP_MIN_SPIN_H +#define LMP_MIN_SPIN_H #include "min.h" namespace LAMMPS_NS { -class MinSpinMin : public Min { +class MinSpin : public Min { public: - MinSpinMin(class LAMMPS *); - ~MinSpinMin() {} + MinSpin(class LAMMPS *); + ~MinSpin() {} void init(); void setup_style(); + int modify_param(int, char **); void reset_vectors(); int iterate(int); double evaluate_dt(); @@ -43,6 +44,9 @@ class MinSpinMin : public Min { double dt; double dts; + double alpha_damp; // damping for spin minimization + double discret_factor; // factor for spin timestep evaluation + double *spvec; // variables for atomic dof, as 1d vector double *fmvec; // variables for atomic dof, as 1d vector diff --git a/src/REPLICA/neb_spin.cpp b/src/SPIN/neb_spin.cpp similarity index 93% rename from src/REPLICA/neb_spin.cpp rename to src/SPIN/neb_spin.cpp index 38f5b530da..f5d9a75020 100644 --- a/src/REPLICA/neb_spin.cpp +++ b/src/SPIN/neb_spin.cpp @@ -109,7 +109,7 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, sp[i][0] = spfinal[0]; sp[i][1] = spfinal[1]; sp[i][2] = spfinal[2]; - + ii += 3; } } @@ -228,8 +228,8 @@ void NEB_spin::run() if (update->minimize->searchflag) error->all(FLERR,"NEB_spin requires damped dynamics minimizer"); - if (strcmp(update->minimize_style,"spinmin") != 0) - error->all(FLERR,"NEB_spin requires spinmin minimizer"); + if (strcmp(update->minimize_style,"spin") != 0) + error->all(FLERR,"NEB_spin requires spin minimizer"); // setup regular NEB_spin minimization @@ -530,10 +530,14 @@ void NEB_spin::readfile(char *file, int flag) spfinal[0] = spx; spfinal[1] = spy; spfinal[2] = spz; + + printf("test spinit[0]:%g \n",sp[m][0]); // interpolate intermediate spin states initial_rotation(spinit,spfinal,fraction); + + printf("test spfinal[0]:%g \n",spfinal[0]); sp[m][0] = spfinal[0]; sp[m][1] = spfinal[1]; @@ -556,6 +560,8 @@ void NEB_spin::readfile(char *file, int flag) nread += nchunk; } + printf("test sp[1][2]:%g \n",sp[1][2]); + // check that all atom IDs in file were found by a proc if (flag == 0) { @@ -613,11 +619,15 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) spfy = sploc[1]; spfz = sploc[2]; + iphi = itheta = fphi = ftheta = 0.0; + iphi = acos(spiz); - itheta = acos(spix/sin(iphi)); + if (sin(iphi) != 0.0) + itheta = acos(spix/sin(iphi)); fphi = acos(spfz); - ftheta = acos(spfx/sin(fphi)); + if (sin(fphi) != 0.0) + ftheta = acos(spfx/sin(fphi)); kphi = iphi + fraction*(fphi-iphi); ktheta = itheta + fraction*(ftheta-itheta); @@ -626,12 +636,69 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) spky = sin(ktheta)*sin(kphi); spkz = cos(kphi); - iknorm = spkx*spkx+spky*spky+spkz*spkz; + double knormsq = spkx*spkx+spky*spky+spkz*spkz; + if (knormsq != 0.0) + iknorm = 1.0/sqrt(knormsq); spkx *= iknorm; spky *= iknorm; spkz *= iknorm; + //sploc[0] = spkx; + //sploc[1] = spky; + //sploc[2] = spkz; + + //double kx,ky,kz; + //double spix,spiy,spiz,spfx,spfy,spfz; + //double kcrossx,kcrossy,kcrossz,knormsq; + //double spkx,spky,spkz; + //double sdot,omega,iknorm; + + //spix = spi[0]; + //spiy = spi[1]; + //spiz = spi[2]; + + //spfx = sploc[0]; + //spfy = sploc[1]; + //spfz = sploc[2]; + // + //kx = spiy*spfz - spiz*spfy; + //ky = spiz*spfx - spix*spfz; + //kz = spix*spfy - spiy*spfx; + + //knormsq = kx*kx+ky*ky+kz*kz; + // + //if (knormsq != 0.0) { + // iknorm = 1.0/sqrt(knormsq); + // kx *= iknorm; + // ky *= iknorm; + // kz *= iknorm; + //} + // + //kcrossx = ky*spiz - kz*spiy; + //kcrossy = kz*spix - kx*spiz; + //kcrossz = kx*spiy - ky*spix; + + //sdot = spix*spfx + spiy*spfy + spiz*spfz; + + //omega = acos(sdot); + //omega *= fraction; + + //spkx = spix*cos(omega) + kcrossx*sin(omega); + //spky = spiy*cos(omega) + kcrossy*sin(omega); + //spkz = spiz*cos(omega) + kcrossz*sin(omega); + // + //iknorm = 1.0/sqrt(spkx*spkx+spky*spky+spkz*spkz); + //if (iknorm == 0.0) + // error->all(FLERR,"Incorrect rotation operation"); + + //spkx *= iknorm; + //spky *= iknorm; + //spkz *= iknorm; + + printf("init: %g %g %g \n",spix,spiy,spiz); + printf("fina: %g %g %g \n",spkx,spky,spkz); + sploc[0] = spkx; sploc[1] = spky; sploc[2] = spkz; diff --git a/src/REPLICA/neb_spin.h b/src/SPIN/neb_spin.h similarity index 100% rename from src/REPLICA/neb_spin.h rename to src/SPIN/neb_spin.h diff --git a/src/min.cpp b/src/min.cpp index c75db6e2b0..2a42a444a0 100644 --- a/src/min.cpp +++ b/src/min.cpp @@ -655,15 +655,11 @@ void Min::modify_params(int narg, char **arg) else if (strcmp(arg[iarg+1],"forcezero") == 0) linestyle = 2; else error->all(FLERR,"Illegal min_modify command"); iarg += 2; - } else if (strcmp(arg[iarg],"alpha_damp") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); - alpha_damp = force->numeric(FLERR,arg[iarg+1]); - iarg += 2; - } else if (strcmp(arg[iarg],"discret_factor") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal min_modify command"); - discret_factor = force->numeric(FLERR,arg[iarg+1]); - iarg += 2; - } else error->all(FLERR,"Illegal min_modify command"); + } else { + int n = modify_param(narg-iarg,&arg[iarg]); + if (n == 0) error->all(FLERR,"Illegal fix_modify command"); + iarg += n; + } } } diff --git a/src/min.h b/src/min.h index ba1885671e..a63254231c 100644 --- a/src/min.h +++ b/src/min.h @@ -38,6 +38,7 @@ class Min : protected Pointers { int request(class Pair *, int, double); virtual bigint memory_usage() {return 0;} void modify_params(int, char **); + virtual int modify_param(int, char **) {return 0;} double fnorm_sqr(); double fnorm_inf(); @@ -58,11 +59,6 @@ class Min : protected Pointers { double dmax; // max dist to move any atom in one step int linestyle; // 0 = backtrack, 1 = quadratic, 2 = forcezero - // spinmin quantities - - double alpha_damp; // damping for spin minimization - double discret_factor; // factor for spin timestep evaluation - int nelist_global,nelist_atom; // # of PE,virial computes to check int nvlist_global,nvlist_atom; class Compute **elist_global; // lists of PE,virial Computes -- GitLab From d1e751d717752927b33b53fd2f613b8bd02288b7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 20 Mar 2019 14:32:03 -0600 Subject: [PATCH 0278/1243] Fix thread safety issue in fused forward comm --- src/KOKKOS/atom_vec_kokkos.cpp | 38 +++++++++-------- src/KOKKOS/atom_vec_kokkos.h | 3 +- src/KOKKOS/comm_kokkos.cpp | 74 +++++++++++++++++++++------------- src/KOKKOS/comm_kokkos.h | 3 +- 4 files changed, 72 insertions(+), 46 deletions(-) diff --git a/src/KOKKOS/atom_vec_kokkos.cpp b/src/KOKKOS/atom_vec_kokkos.cpp index 076e3e52fa..9e7de1785b 100644 --- a/src/KOKKOS/atom_vec_kokkos.cpp +++ b/src/KOKKOS/atom_vec_kokkos.cpp @@ -281,6 +281,7 @@ struct AtomVecKokkos_PackCommSelfFused { typename ArrayTypes::t_int_1d_const _pbc_flag; typename ArrayTypes::t_int_1d_const _firstrecv; typename ArrayTypes::t_int_1d_const _sendnum_scan; + typename ArrayTypes::t_int_1d_const _g2l; X_FLOAT _xprd,_yprd,_zprd,_xy,_xz,_yz; AtomVecKokkos_PackCommSelfFused( @@ -290,6 +291,7 @@ struct AtomVecKokkos_PackCommSelfFused { const typename DAT::tdual_int_1d &pbc_flag, const typename DAT::tdual_int_1d &firstrecv, const typename DAT::tdual_int_1d &sendnum_scan, + const typename DAT::tdual_int_1d &g2l, const X_FLOAT &xprd, const X_FLOAT &yprd, const X_FLOAT &zprd, const X_FLOAT &xy, const X_FLOAT &xz, const X_FLOAT &yz): _x(x.view()),_xw(x.view()), @@ -298,6 +300,7 @@ struct AtomVecKokkos_PackCommSelfFused { _pbc_flag(pbc_flag.view()), _firstrecv(firstrecv.view()), _sendnum_scan(sendnum_scan.view()), + _g2l(g2l.view()), _xprd(xprd),_yprd(yprd),_zprd(zprd), _xy(xy),_xz(xz),_yz(yz) {}; @@ -309,43 +312,46 @@ struct AtomVecKokkos_PackCommSelfFused { int i = ii; if (iswap > 0) i = ii - _sendnum_scan[iswap-1]; - const int _nfirst = _firstrecv[iswap]; + const int _nfirst = _firstrecv[iswap]; + const int nlocal = _firstrecv[0]; + int j = _list(iswap,i); + if (j >= nlocal) + j = _g2l(j-nlocal); - const int j = _list(iswap,i); - if (_pbc_flag(iswap) == 0) { + if (_pbc_flag(ii) == 0) { _xw(i+_nfirst,0) = _x(j,0); _xw(i+_nfirst,1) = _x(j,1); _xw(i+_nfirst,2) = _x(j,2); } else { if (TRICLINIC == 0) { - _xw(i+_nfirst,0) = _x(j,0) + _pbc(iswap,0)*_xprd; - _xw(i+_nfirst,1) = _x(j,1) + _pbc(iswap,1)*_yprd; - _xw(i+_nfirst,2) = _x(j,2) + _pbc(iswap,2)*_zprd; + _xw(i+_nfirst,0) = _x(j,0) + _pbc(ii,0)*_xprd; + _xw(i+_nfirst,1) = _x(j,1) + _pbc(ii,1)*_yprd; + _xw(i+_nfirst,2) = _x(j,2) + _pbc(ii,2)*_zprd; } else { - _xw(i+_nfirst,0) = _x(j,0) + _pbc(iswap,0)*_xprd + _pbc(iswap,5)*_xy + _pbc(iswap,4)*_xz; - _xw(i+_nfirst,1) = _x(j,1) + _pbc(iswap,1)*_yprd + _pbc(iswap,3)*_yz; - _xw(i+_nfirst,2) = _x(j,2) + _pbc(iswap,2)*_zprd; + _xw(i+_nfirst,0) = _x(j,0) + _pbc(ii,0)*_xprd + _pbc(ii,5)*_xy + _pbc(ii,4)*_xz; + _xw(i+_nfirst,1) = _x(j,1) + _pbc(ii,1)*_yprd + _pbc(ii,3)*_yz; + _xw(i+_nfirst,2) = _x(j,2) + _pbc(ii,2)*_zprd; } } - } }; /* ---------------------------------------------------------------------- */ int AtomVecKokkos::pack_comm_self_fused(const int &n, const DAT::tdual_int_2d &list, const DAT::tdual_int_1d &sendnum_scan, - const DAT::tdual_int_1d &firstrecv, const DAT::tdual_int_1d &pbc_flag, const DAT::tdual_int_2d &pbc) { + const DAT::tdual_int_1d &firstrecv, const DAT::tdual_int_1d &pbc_flag, const DAT::tdual_int_2d &pbc, + const DAT::tdual_int_1d &g2l) { if(commKK->forward_comm_on_host) { sync(Host,X_MASK); modified(Host,X_MASK); if(domain->triclinic) { - struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan,g2l, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); } else { - struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan,g2l, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); @@ -354,18 +360,18 @@ int AtomVecKokkos::pack_comm_self_fused(const int &n, const DAT::tdual_int_2d &l sync(Device,X_MASK); modified(Device,X_MASK); if(domain->triclinic) { - struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan,g2l, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); } else { - struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan, + struct AtomVecKokkos_PackCommSelfFused f(atomKK->k_x,list,pbc,pbc_flag,firstrecv,sendnum_scan,g2l, domain->xprd,domain->yprd,domain->zprd, domain->xy,domain->xz,domain->yz); Kokkos::parallel_for(n,f); } } - return n*3; + return n*3; } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index ea83ef1c8f..0474a2380a 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -56,7 +56,8 @@ class AtomVecKokkos : public AtomVec { const DAT::tdual_int_1d &sendnum_scan, const DAT::tdual_int_1d &firstrecv, const DAT::tdual_int_1d &pbc_flag, - const DAT::tdual_int_2d &pbc); + const DAT::tdual_int_2d &pbc, + const DAT::tdual_int_1d &g2l); virtual int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &list, diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 4396637153..cd6ade1c2f 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -140,31 +140,6 @@ void CommKokkos::init() forward_comm_classic = true; } -/* ---------------------------------------------------------------------- */ - -void CommKokkos::setup() -{ - CommBrick::setup(); - - k_pbc_flag = DAT::tdual_int_1d("comm:pbc_flag",nswap); - k_pbc = DAT::tdual_int_2d("comm:pbc",nswap,6); - - for (int iswap = 0; iswap < nswap; iswap++) { - k_pbc_flag.h_view[iswap] = pbc_flag[iswap]; - k_pbc.h_view(iswap,0) = pbc[iswap][0]; - k_pbc.h_view(iswap,1) = pbc[iswap][1]; - k_pbc.h_view(iswap,2) = pbc[iswap][2]; - k_pbc.h_view(iswap,3) = pbc[iswap][3]; - k_pbc.h_view(iswap,4) = pbc[iswap][4]; - k_pbc.h_view(iswap,5) = pbc[iswap][5]; - } - k_pbc_flag.modify(); - k_pbc.modify(); - - k_pbc_flag.sync(); - k_pbc.sync(); -} - /* ---------------------------------------------------------------------- forward communication of atom coords every timestep other per-atom attributes may also be sent via pack/unpack routines @@ -211,11 +186,12 @@ void CommKokkos::forward_comm_device(int dummy) k_sendlist.sync(); atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); - if (comm->nprocs == 1) { + if (comm->nprocs == 1 && !ghost_velocity) { k_swap.sync(); + k_swap2.sync(); k_pbc.sync(); n = avec->pack_comm_self_fused(totalsend,k_sendlist,k_sendnum_scan, - k_firstrecv,k_pbc_flag,k_pbc); + k_firstrecv,k_pbc_flag,k_pbc,k_g2l); } else { for (int iswap = 0; iswap < nswap; iswap++) { @@ -783,7 +759,7 @@ void CommKokkos::borders() atomKK->modified(Host,ALL_MASK); } - if (comm->nprocs == 1 && !forward_comm_classic) + if (comm->nprocs == 1 && !ghost_velocity && !forward_comm_classic) copy_swap_info(); } @@ -1092,7 +1068,49 @@ void CommKokkos::copy_swap_info() } totalsend = scan; + int* list = NULL; + memory->create(list,totalsend,"comm:list"); + if (totalsend > k_pbc.extent(0)) { + k_pbc = DAT::tdual_int_2d("comm:pbc",totalsend,6); + k_swap2 = DAT::tdual_int_2d("comm:swap2",2,totalsend); + k_pbc_flag = Kokkos::subview(k_swap2,0,Kokkos::ALL); + k_g2l = Kokkos::subview(k_swap2,1,Kokkos::ALL); + } + + // create map of ghost atoms to local atoms + // store periodic boundary transform from local to ghost + + for (int iswap = 0; iswap < nswap; iswap++) { + for (int i = 0; i < sendnum[iswap]; i++) { + int source = sendlist[iswap][i] - atom->nlocal; + int dest = firstrecv[iswap] + i - atom->nlocal; + k_pbc_flag.h_view(dest) = pbc_flag[iswap]; + k_pbc.h_view(dest,0) = pbc[iswap][0]; + k_pbc.h_view(dest,1) = pbc[iswap][1]; + k_pbc.h_view(dest,2) = pbc[iswap][2]; + k_pbc.h_view(dest,3) = pbc[iswap][3]; + k_pbc.h_view(dest,4) = pbc[iswap][4]; + k_pbc.h_view(dest,5) = pbc[iswap][5]; + k_g2l.h_view(dest) = atom->nlocal + source; + + if (source >= 0) { + k_pbc_flag.h_view(dest) = k_pbc_flag.h_view(dest) || k_pbc_flag.h_view(source); + k_pbc.h_view(dest,0) += k_pbc.h_view(source,0); + k_pbc.h_view(dest,1) += k_pbc.h_view(source,1); + k_pbc.h_view(dest,2) += k_pbc.h_view(source,2); + k_pbc.h_view(dest,3) += k_pbc.h_view(source,3); + k_pbc.h_view(dest,4) += k_pbc.h_view(source,4); + k_pbc.h_view(dest,5) += k_pbc.h_view(source,5); + k_g2l.h_view(dest) = k_g2l.h_view(source); + } + } + } + k_swap.modify(); + k_swap2.modify(); + k_pbc.modify(); + + memory->destroy(list); } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/comm_kokkos.h b/src/KOKKOS/comm_kokkos.h index d5428c8b0c..9d8766e309 100644 --- a/src/KOKKOS/comm_kokkos.h +++ b/src/KOKKOS/comm_kokkos.h @@ -33,7 +33,6 @@ class CommKokkos : public CommBrick { CommKokkos(class LAMMPS *); ~CommKokkos(); void init(); - void setup(); void forward_comm(int dummy = 0); // forward comm of atom coords void reverse_comm(); // reverse comm of atom coords @@ -66,8 +65,10 @@ class CommKokkos : public CommBrick { //double *buf_recv; // recv buffer for all comm DAT::tdual_int_2d k_swap; + DAT::tdual_int_2d k_swap2; DAT::tdual_int_2d k_pbc; DAT::tdual_int_1d k_pbc_flag; + DAT::tdual_int_1d k_g2l; DAT::tdual_int_1d k_firstrecv; DAT::tdual_int_1d k_sendnum_scan; int totalsend; -- GitLab From 1f44dc2498366b80c0e0b0f36424728a2c98cf0f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 20 Mar 2019 15:01:47 -0600 Subject: [PATCH 0279/1243] Remove unused array in comm_kokkos --- src/KOKKOS/comm_kokkos.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index cd6ade1c2f..a89889bd28 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -1068,7 +1068,9 @@ void CommKokkos::copy_swap_info() } totalsend = scan; - int* list = NULL; + // create map of ghost to local atom id + // store periodic boundary transform from local to ghost + memory->create(list,totalsend,"comm:list"); if (totalsend > k_pbc.extent(0)) { k_pbc = DAT::tdual_int_2d("comm:pbc",totalsend,6); @@ -1077,9 +1079,6 @@ void CommKokkos::copy_swap_info() k_g2l = Kokkos::subview(k_swap2,1,Kokkos::ALL); } - // create map of ghost atoms to local atoms - // store periodic boundary transform from local to ghost - for (int iswap = 0; iswap < nswap; iswap++) { for (int i = 0; i < sendnum[iswap]; i++) { int source = sendlist[iswap][i] - atom->nlocal; @@ -1109,8 +1108,6 @@ void CommKokkos::copy_swap_info() k_swap.modify(); k_swap2.modify(); k_pbc.modify(); - - memory->destroy(list); } /* ---------------------------------------------------------------------- -- GitLab From 744a8215dd4c2bd29c6b056a142f88e756213675 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 20 Mar 2019 15:08:08 -0600 Subject: [PATCH 0280/1243] Fix compile error in comm_kokkos and indent in atom_vec_kokkos --- src/KOKKOS/atom_vec_kokkos.cpp | 37 +++++++++++++++++----------------- src/KOKKOS/comm_kokkos.cpp | 1 - 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/KOKKOS/atom_vec_kokkos.cpp b/src/KOKKOS/atom_vec_kokkos.cpp index 9e7de1785b..7d5df17544 100644 --- a/src/KOKKOS/atom_vec_kokkos.cpp +++ b/src/KOKKOS/atom_vec_kokkos.cpp @@ -312,28 +312,29 @@ struct AtomVecKokkos_PackCommSelfFused { int i = ii; if (iswap > 0) i = ii - _sendnum_scan[iswap-1]; - const int _nfirst = _firstrecv[iswap]; - const int nlocal = _firstrecv[0]; - int j = _list(iswap,i); - if (j >= nlocal) - j = _g2l(j-nlocal); + const int _nfirst = _firstrecv[iswap]; + const int nlocal = _firstrecv[0]; - if (_pbc_flag(ii) == 0) { - _xw(i+_nfirst,0) = _x(j,0); - _xw(i+_nfirst,1) = _x(j,1); - _xw(i+_nfirst,2) = _x(j,2); + int j = _list(iswap,i); + if (j >= nlocal) + j = _g2l(j-nlocal); + + if (_pbc_flag(ii) == 0) { + _xw(i+_nfirst,0) = _x(j,0); + _xw(i+_nfirst,1) = _x(j,1); + _xw(i+_nfirst,2) = _x(j,2); + } else { + if (TRICLINIC == 0) { + _xw(i+_nfirst,0) = _x(j,0) + _pbc(ii,0)*_xprd; + _xw(i+_nfirst,1) = _x(j,1) + _pbc(ii,1)*_yprd; + _xw(i+_nfirst,2) = _x(j,2) + _pbc(ii,2)*_zprd; } else { - if (TRICLINIC == 0) { - _xw(i+_nfirst,0) = _x(j,0) + _pbc(ii,0)*_xprd; - _xw(i+_nfirst,1) = _x(j,1) + _pbc(ii,1)*_yprd; - _xw(i+_nfirst,2) = _x(j,2) + _pbc(ii,2)*_zprd; - } else { - _xw(i+_nfirst,0) = _x(j,0) + _pbc(ii,0)*_xprd + _pbc(ii,5)*_xy + _pbc(ii,4)*_xz; - _xw(i+_nfirst,1) = _x(j,1) + _pbc(ii,1)*_yprd + _pbc(ii,3)*_yz; - _xw(i+_nfirst,2) = _x(j,2) + _pbc(ii,2)*_zprd; - } + _xw(i+_nfirst,0) = _x(j,0) + _pbc(ii,0)*_xprd + _pbc(ii,5)*_xy + _pbc(ii,4)*_xz; + _xw(i+_nfirst,1) = _x(j,1) + _pbc(ii,1)*_yprd + _pbc(ii,3)*_yz; + _xw(i+_nfirst,2) = _x(j,2) + _pbc(ii,2)*_zprd; } + } } }; diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index a89889bd28..d52011879d 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -1071,7 +1071,6 @@ void CommKokkos::copy_swap_info() // create map of ghost to local atom id // store periodic boundary transform from local to ghost - memory->create(list,totalsend,"comm:list"); if (totalsend > k_pbc.extent(0)) { k_pbc = DAT::tdual_int_2d("comm:pbc",totalsend,6); k_swap2 = DAT::tdual_int_2d("comm:swap2",2,totalsend); -- GitLab From c3adfcbc155859f4313503a0e1acef5c71d84b0b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 21 Mar 2019 08:56:12 -0600 Subject: [PATCH 0281/1243] Add missing sync in comm_kokkos --- src/KOKKOS/comm_kokkos.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index d52011879d..7432f30b95 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -1071,6 +1071,8 @@ void CommKokkos::copy_swap_info() // create map of ghost to local atom id // store periodic boundary transform from local to ghost + k_sendlist.sync(); + if (totalsend > k_pbc.extent(0)) { k_pbc = DAT::tdual_int_2d("comm:pbc",totalsend,6); k_swap2 = DAT::tdual_int_2d("comm:swap2",2,totalsend); -- GitLab From f2ef02b6d94603b1902774dbddf488a1fd06522b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 21 Mar 2019 09:27:18 -0600 Subject: [PATCH 0282/1243] Comm exchange is a no-op for 1 MPI rank --- src/KOKKOS/comm_kokkos.cpp | 257 ++++++++++++++++++------------------- 1 file changed, 128 insertions(+), 129 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 7432f30b95..720a79617f 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -504,9 +504,8 @@ void CommKokkos::exchange() } atomKK->sync(Host,ALL_MASK); - atomKK->modified(Host,ALL_MASK); - CommBrick::exchange(); + atomKK->modified(Host,ALL_MASK); } /* ---------------------------------------------------------------------- */ @@ -573,147 +572,149 @@ void CommKokkos::exchange_device() atom->nghost = 0; atom->avec->clear_bonus(); - // subbox bounds for orthogonal or triclinic + if (comm->nprocs > 1) { // otherwise no-op - if (triclinic == 0) { - sublo = domain->sublo; - subhi = domain->subhi; - } else { - sublo = domain->sublo_lamda; - subhi = domain->subhi_lamda; - } + // subbox bounds for orthogonal or triclinic + + if (triclinic == 0) { + sublo = domain->sublo; + subhi = domain->subhi; + } else { + sublo = domain->sublo_lamda; + subhi = domain->subhi_lamda; + } + + atomKK->sync(ExecutionSpaceFromDevice::space,ALL_MASK); + + // loop over dimensions + for (int dim = 0; dim < 3; dim++) { + + // fill buffer with atoms leaving my box, using < and >= + // when atom is deleted, fill it in with last atom - atomKK->sync(ExecutionSpaceFromDevice::space,ALL_MASK); - - // loop over dimensions - for (int dim = 0; dim < 3; dim++) { - - // fill buffer with atoms leaving my box, using < and >= - // when atom is deleted, fill it in with last atom - - x = atom->x; - lo = sublo[dim]; - hi = subhi[dim]; - nlocal = atom->nlocal; - i = nsend = 0; - - if (true) { - if (k_sendflag.h_view.extent(0)(); - k_count.h_view() = k_exchange_sendlist.h_view.extent(0); - while (k_count.h_view()>=k_exchange_sendlist.h_view.extent(0)) { - k_count.h_view() = 0; - k_count.modify(); - k_count.sync(); - - BuildExchangeListFunctor - f(atomKK->k_x,k_exchange_sendlist,k_count,k_sendflag, - nlocal,dim,lo,hi); - Kokkos::parallel_for(nlocal,f); - k_exchange_sendlist.modify(); - k_sendflag.modify(); - k_count.modify(); - - k_count.sync(); - if (k_count.h_view()>=k_exchange_sendlist.h_view.extent(0)) { - k_exchange_sendlist.resize(k_count.h_view()*1.1); - k_exchange_copylist.resize(k_count.h_view()*1.1); - k_count.h_view()=k_exchange_sendlist.h_view.extent(0); + x = atom->x; + lo = sublo[dim]; + hi = subhi[dim]; + nlocal = atom->nlocal; + i = nsend = 0; + + if (true) { + if (k_sendflag.h_view.extent(0)(); + k_count.h_view() = k_exchange_sendlist.h_view.extent(0); + while (k_count.h_view()>=k_exchange_sendlist.h_view.extent(0)) { + k_count.h_view() = 0; + k_count.modify(); + k_count.sync(); + + BuildExchangeListFunctor + f(atomKK->k_x,k_exchange_sendlist,k_count,k_sendflag, + nlocal,dim,lo,hi); + Kokkos::parallel_for(nlocal,f); + k_exchange_sendlist.modify(); + k_sendflag.modify(); + k_count.modify(); + + k_count.sync(); + if (k_count.h_view()>=k_exchange_sendlist.h_view.extent(0)) { + k_exchange_sendlist.resize(k_count.h_view()*1.1); + k_exchange_copylist.resize(k_count.h_view()*1.1); + k_count.h_view()=k_exchange_sendlist.h_view.extent(0); + } } - } - k_exchange_lists.sync(); - k_sendflag.sync(); - - int sendpos = nlocal-1; - nlocal -= k_count.h_view(); - for(int i = 0; i < k_count.h_view(); i++) { - if (k_exchange_sendlist.h_view(i)(); + k_sendflag.sync(); + + int sendpos = nlocal-1; + nlocal -= k_count.h_view(); + for(int i = 0; i < k_count.h_view(); i++) { + if (k_exchange_sendlist.h_view(i)(); - k_exchange_copylist_short.template sync(); - nsend = k_count.h_view(); - if (nsend > maxsend) grow_send_kokkos(nsend,1); - nsend = - avec->pack_exchange_kokkos(k_count.h_view(),k_buf_send, - k_exchange_sendlist,k_exchange_copylist, - ExecutionSpaceFromDevice::space, - dim,lo,hi); - DeviceType::fence(); - } else { - while (i < nlocal) { - if (x[i][dim] < lo || x[i][dim] >= hi) { - if (nsend > maxsend) grow_send_kokkos(nsend,1); - nsend += avec->pack_exchange(i,&buf_send[nsend]); - avec->copy(nlocal-1,i,1); - nlocal--; - } else i++; - } - } - atom->nlocal = nlocal; - - // send/recv atoms in both directions - // if 1 proc in dimension, no send/recv, set recv buf to send buf - // if 2 procs in dimension, single send/recv - // if more than 2 procs in dimension, send/recv to both neighbors - - if (procgrid[dim] == 1) { - nrecv = nsend; - if (nrecv) { - atom->nlocal=avec-> - unpack_exchange_kokkos(k_buf_send,nrecv,atom->nlocal,dim,lo,hi, - ExecutionSpaceFromDevice::space); + auto k_exchange_copylist_short = Kokkos::subview(k_exchange_copylist,k_count.h_view()); + k_exchange_copylist_short.template modify(); + k_exchange_copylist_short.template sync(); + nsend = k_count.h_view(); + if (nsend > maxsend) grow_send_kokkos(nsend,1); + nsend = + avec->pack_exchange_kokkos(k_count.h_view(),k_buf_send, + k_exchange_sendlist,k_exchange_copylist, + ExecutionSpaceFromDevice::space, + dim,lo,hi); DeviceType::fence(); + } else { + while (i < nlocal) { + if (x[i][dim] < lo || x[i][dim] >= hi) { + if (nsend > maxsend) grow_send_kokkos(nsend,1); + nsend += avec->pack_exchange(i,&buf_send[nsend]); + avec->copy(nlocal-1,i,1); + nlocal--; + } else i++; + } } - } else { - MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0, - &nrecv1,1,MPI_INT,procneigh[dim][1],0,world,MPI_STATUS_IGNORE); - nrecv = nrecv1; - if (procgrid[dim] > 2) { - MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0, - &nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE); - nrecv += nrecv2; - } - if (nrecv > maxrecv) grow_recv_kokkos(nrecv); - - MPI_Irecv(k_buf_recv.view().data(),nrecv1, - MPI_DOUBLE,procneigh[dim][1],0, - world,&request); - MPI_Send(k_buf_send.view().data(),nsend, - MPI_DOUBLE,procneigh[dim][0],0,world); - MPI_Wait(&request,MPI_STATUS_IGNORE); - - if (procgrid[dim] > 2) { - MPI_Irecv(k_buf_recv.view().data()+nrecv1, - nrecv2,MPI_DOUBLE,procneigh[dim][0],0, + atom->nlocal = nlocal; + + // send/recv atoms in both directions + // if 1 proc in dimension, no send/recv, set recv buf to send buf + // if 2 procs in dimension, single send/recv + // if more than 2 procs in dimension, send/recv to both neighbors + + if (procgrid[dim] == 1) { + nrecv = nsend; + if (nrecv) { + atom->nlocal=avec-> + unpack_exchange_kokkos(k_buf_send,nrecv,atom->nlocal,dim,lo,hi, + ExecutionSpaceFromDevice::space); + DeviceType::fence(); + } + } else { + MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0, + &nrecv1,1,MPI_INT,procneigh[dim][1],0,world,MPI_STATUS_IGNORE); + nrecv = nrecv1; + if (procgrid[dim] > 2) { + MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0, + &nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE); + nrecv += nrecv2; + } + if (nrecv > maxrecv) grow_recv_kokkos(nrecv); + + MPI_Irecv(k_buf_recv.view().data(),nrecv1, + MPI_DOUBLE,procneigh[dim][1],0, world,&request); MPI_Send(k_buf_send.view().data(),nsend, - MPI_DOUBLE,procneigh[dim][1],0,world); + MPI_DOUBLE,procneigh[dim][0],0,world); MPI_Wait(&request,MPI_STATUS_IGNORE); - } - if (nrecv) { - atom->nlocal = avec-> - unpack_exchange_kokkos(k_buf_recv,nrecv,atom->nlocal,dim,lo,hi, - ExecutionSpaceFromDevice::space); - DeviceType::fence(); + if (procgrid[dim] > 2) { + MPI_Irecv(k_buf_recv.view().data()+nrecv1, + nrecv2,MPI_DOUBLE,procneigh[dim][0],0, + world,&request); + MPI_Send(k_buf_send.view().data(),nsend, + MPI_DOUBLE,procneigh[dim][1],0,world); + MPI_Wait(&request,MPI_STATUS_IGNORE); + } + + if (nrecv) { + atom->nlocal = avec-> + unpack_exchange_kokkos(k_buf_recv,nrecv,atom->nlocal,dim,lo,hi, + ExecutionSpaceFromDevice::space); + DeviceType::fence(); + } } - } - // check incoming atoms to see if they are in my box - // if so, add to my list + // check incoming atoms to see if they are in my box + // if so, add to my list + } + atomKK->modified(ExecutionSpaceFromDevice::space,ALL_MASK); } - atomKK->modified(ExecutionSpaceFromDevice::space,ALL_MASK); - if (atom->firstgroupname) { /* this is not yet implemented with Kokkos */ atomKK->sync(Host,ALL_MASK); @@ -753,7 +754,6 @@ void CommKokkos::borders() else borders_device(); } else { atomKK->sync(Host,ALL_MASK); - k_sendlist.sync(); CommBrick::borders(); k_sendlist.modify(); atomKK->modified(Host,ALL_MASK); @@ -828,7 +828,6 @@ void CommKokkos::borders_device() { AtomVecKokkos *avec = (AtomVecKokkos *) atom->avec; ExecutionSpace exec_space = ExecutionSpaceFromDevice::space; - k_sendlist.sync(); atomKK->sync(exec_space,ALL_MASK); // do swaps over all 3 dimensions -- GitLab From 1e8ccb17742f8cf72f06ca4780598a2e81999ff2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 04:54:06 -0400 Subject: [PATCH 0283/1243] initialize setflag and cutsq pointers to NULL, so they are not accessed uninitialized by accident --- src/pair.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pair.cpp b/src/pair.cpp index 44cf3a43ea..9fd3515a3d 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -72,6 +72,9 @@ Pair::Pair(LAMMPS *lmp) : Pointers(lmp) single_extra = 0; svector = NULL; + setflag = NULL; + cutsq = NULL; + ewaldflag = pppmflag = msmflag = dispersionflag = tip4pflag = dipoleflag = 0; reinitflag = 1; -- GitLab From 8f90d6c6d00a8dd07edbd510b072f7f953a114ea Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 04:55:13 -0400 Subject: [PATCH 0284/1243] must bracket 'memory->destroy()' calls in destructor with 'if (allocated)' --- src/pair_buck_coul_cut.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp index 7eecb62121..f9e7c94920 100644 --- a/src/pair_buck_coul_cut.cpp +++ b/src/pair_buck_coul_cut.cpp @@ -42,7 +42,9 @@ PairBuckCoulCut::PairBuckCoulCut(LAMMPS *lmp) : Pair(lmp) PairBuckCoulCut::~PairBuckCoulCut() { - if (!copymode) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); -- GitLab From b975d59d9f7956835ba93d8ba731d0fe1f9941f7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 04:55:58 -0400 Subject: [PATCH 0285/1243] make use of copymode flag in pair style destructors consistent --- src/CLASS2/pair_lj_class2.cpp | 28 +++++------ src/CLASS2/pair_lj_class2_coul_cut.cpp | 34 +++++++------- src/CLASS2/pair_lj_class2_coul_long.cpp | 30 ++++++------ src/KSPACE/pair_buck_coul_long.cpp | 32 ++++++------- src/KSPACE/pair_coul_long.cpp | 14 +++--- src/KSPACE/pair_lj_charmm_coul_long.cpp | 40 ++++++++-------- src/KSPACE/pair_lj_charmmfsw_coul_long.cpp | 42 ++++++++--------- src/MOLECULE/pair_lj_charmm_coul_charmm.cpp | 6 +-- .../pair_lj_charmmfsw_coul_charmmfsh.cpp | 40 ++++++++-------- src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp | 36 +++++++-------- .../pair_lj_class2_coul_long_soft.cpp | 32 ++++++------- src/USER-FEP/pair_lj_class2_soft.cpp | 30 ++++++------ src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp | 46 +++++++++---------- .../pair_buck6d_coul_gauss_long.cpp | 42 ++++++++--------- src/pair_lj_cut_coul_dsf.cpp | 30 ++++++------ src/pair_lj_expand.cpp | 6 +-- src/pair_lj_gromacs.cpp | 6 +-- src/pair_lj_gromacs_coul_gromacs.cpp | 6 +-- 18 files changed, 249 insertions(+), 251 deletions(-) diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp index e6546b1acc..015dc59d2f 100644 --- a/src/CLASS2/pair_lj_class2.cpp +++ b/src/CLASS2/pair_lj_class2.cpp @@ -38,20 +38,20 @@ PairLJClass2::PairLJClass2(LAMMPS *lmp) : Pair(lmp) PairLJClass2::~PairLJClass2() { - if (!copymode) { - 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); - memory->destroy(offset); - } + if (copymode) return; + + 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); + memory->destroy(offset); } } diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp index 49242ecb43..7888591b51 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.cpp +++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp @@ -39,23 +39,23 @@ PairLJClass2CoulCut::PairLJClass2CoulCut(LAMMPS *lmp) : Pair(lmp) PairLJClass2CoulCut::~PairLJClass2CoulCut() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(cut_coul); - memory->destroy(cut_coulsq); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(cut_coul); + memory->destroy(cut_coulsq); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(offset); } } diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp index bbea2ade6e..4ae448af30 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.cpp +++ b/src/CLASS2/pair_lj_class2_coul_long.cpp @@ -50,21 +50,21 @@ PairLJClass2CoulLong::PairLJClass2CoulLong(LAMMPS *lmp) : Pair(lmp) PairLJClass2CoulLong::~PairLJClass2CoulLong() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(offset); } if (ftable) free_tables(); } diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp index a37e4ab4e9..c18b1f3481 100644 --- a/src/KSPACE/pair_buck_coul_long.cpp +++ b/src/KSPACE/pair_buck_coul_long.cpp @@ -50,23 +50,23 @@ PairBuckCoulLong::PairBuckCoulLong(LAMMPS *lmp) : Pair(lmp) PairBuckCoulLong::~PairBuckCoulLong() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(a); - memory->destroy(rho); - memory->destroy(c); - memory->destroy(rhoinv); - memory->destroy(buck1); - memory->destroy(buck2); - memory->destroy(offset); - } - if (ftable) free_tables(); + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(a); + memory->destroy(rho); + memory->destroy(c); + memory->destroy(rhoinv); + memory->destroy(buck1); + memory->destroy(buck2); + memory->destroy(offset); } + if (ftable) free_tables(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KSPACE/pair_coul_long.cpp b/src/KSPACE/pair_coul_long.cpp index 8db5979b39..98dac97db3 100644 --- a/src/KSPACE/pair_coul_long.cpp +++ b/src/KSPACE/pair_coul_long.cpp @@ -55,15 +55,15 @@ PairCoulLong::PairCoulLong(LAMMPS *lmp) : Pair(lmp) PairCoulLong::~PairCoulLong() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); + if (copymode) return; - memory->destroy(scale); - } - if (ftable) free_tables(); + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(scale); } + if (ftable) free_tables(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KSPACE/pair_lj_charmm_coul_long.cpp b/src/KSPACE/pair_lj_charmm_coul_long.cpp index 749d9657aa..78dfdc8dd9 100644 --- a/src/KSPACE/pair_lj_charmm_coul_long.cpp +++ b/src/KSPACE/pair_lj_charmm_coul_long.cpp @@ -59,27 +59,27 @@ PairLJCharmmCoulLong::PairLJCharmmCoulLong(LAMMPS *lmp) : Pair(lmp) PairLJCharmmCoulLong::~PairLJCharmmCoulLong() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(eps14); - memory->destroy(sigma14); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(lj14_1); - memory->destroy(lj14_2); - memory->destroy(lj14_3); - memory->destroy(lj14_4); - memory->destroy(offset); - } - if (ftable) free_tables(); + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(eps14); + memory->destroy(sigma14); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(lj14_1); + memory->destroy(lj14_2); + memory->destroy(lj14_3); + memory->destroy(lj14_4); + memory->destroy(offset); } + if (ftable) free_tables(); } /* ---------------------------------------------------------------------- */ diff --git a/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp b/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp index 614980117e..00c6d793e7 100644 --- a/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp +++ b/src/KSPACE/pair_lj_charmmfsw_coul_long.cpp @@ -77,27 +77,6 @@ PairLJCharmmfswCoulLong::PairLJCharmmfswCoulLong(LAMMPS *lmp) : Pair(lmp) PairLJCharmmfswCoulLong::~PairLJCharmmfswCoulLong() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(eps14); - memory->destroy(sigma14); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(lj14_1); - memory->destroy(lj14_2); - memory->destroy(lj14_3); - memory->destroy(lj14_4); - } - if (ftable) free_tables(); - } - // switch qqr2e back from CHARMM value to LAMMPS value if (update && strcmp(update->unit_style,"real") == 0) { @@ -106,6 +85,27 @@ PairLJCharmmfswCoulLong::~PairLJCharmmfswCoulLong() " conversion constant"); force->qqr2e = force->qqr2e_lammps_real; } + + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(eps14); + memory->destroy(sigma14); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(lj14_1); + memory->destroy(lj14_2); + memory->destroy(lj14_3); + memory->destroy(lj14_4); + } + if (ftable) free_tables(); } /* ---------------------------------------------------------------------- */ diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp index 688c675815..ddca7f8b49 100644 --- a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp +++ b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp @@ -43,8 +43,9 @@ PairLJCharmmCoulCharmm::PairLJCharmmCoulCharmm(LAMMPS *lmp) : Pair(lmp) PairLJCharmmCoulCharmm::~PairLJCharmmCoulCharmm() { - if (!copymode) { - if (allocated) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -60,7 +61,6 @@ PairLJCharmmCoulCharmm::~PairLJCharmmCoulCharmm() memory->destroy(lj14_2); memory->destroy(lj14_3); memory->destroy(lj14_4); - } } } diff --git a/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp b/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp index 4b9147c169..5ea1ce4fcf 100644 --- a/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp +++ b/src/MOLECULE/pair_lj_charmmfsw_coul_charmmfsh.cpp @@ -62,26 +62,6 @@ PairLJCharmmfswCoulCharmmfsh::PairLJCharmmfswCoulCharmmfsh(LAMMPS *lmp) : PairLJCharmmfswCoulCharmmfsh::~PairLJCharmmfswCoulCharmmfsh() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(eps14); - memory->destroy(sigma14); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(lj14_1); - memory->destroy(lj14_2); - memory->destroy(lj14_3); - memory->destroy(lj14_4); - } - } - // switch qqr2e back from CHARMM value to LAMMPS value if (update && strcmp(update->unit_style,"real") == 0) { @@ -90,6 +70,26 @@ PairLJCharmmfswCoulCharmmfsh::~PairLJCharmmfswCoulCharmmfsh() " conversion constant"); force->qqr2e = force->qqr2e_lammps_real; } + + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(eps14); + memory->destroy(sigma14); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(lj14_1); + memory->destroy(lj14_2); + memory->destroy(lj14_3); + memory->destroy(lj14_4); + } } /* ---------------------------------------------------------------------- */ diff --git a/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp b/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp index 7970097cfe..8250f1da06 100644 --- a/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp +++ b/src/USER-FEP/pair_lj_class2_coul_cut_soft.cpp @@ -39,24 +39,24 @@ PairLJClass2CoulCutSoft::PairLJClass2CoulCutSoft(LAMMPS *lmp) : Pair(lmp) PairLJClass2CoulCutSoft::~PairLJClass2CoulCutSoft() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(cut_coul); - memory->destroy(cut_coulsq); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lambda); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(cut_coul); + memory->destroy(cut_coulsq); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lambda); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(offset); } } diff --git a/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp b/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp index 13096a64c6..fe8f6a4f1b 100644 --- a/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp +++ b/src/USER-FEP/pair_lj_class2_coul_long_soft.cpp @@ -49,22 +49,22 @@ PairLJClass2CoulLongSoft::PairLJClass2CoulLongSoft(LAMMPS *lmp) : Pair(lmp) PairLJClass2CoulLongSoft::~PairLJClass2CoulLongSoft() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lambda); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lambda); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(offset); } } diff --git a/src/USER-FEP/pair_lj_class2_soft.cpp b/src/USER-FEP/pair_lj_class2_soft.cpp index b7f21fc59c..88638d9ca0 100644 --- a/src/USER-FEP/pair_lj_class2_soft.cpp +++ b/src/USER-FEP/pair_lj_class2_soft.cpp @@ -32,28 +32,26 @@ using namespace MathConst; PairLJClass2Soft::PairLJClass2Soft(LAMMPS *lmp) : Pair(lmp) { writedata = 1; - allocated = 0; } /* ---------------------------------------------------------------------- */ PairLJClass2Soft::~PairLJClass2Soft() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lambda); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(offset); - allocated=0; - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lambda); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(offset); } } diff --git a/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp b/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp index 1fc4644420..94903f43fa 100644 --- a/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp +++ b/src/USER-MOFFF/pair_buck6d_coul_gauss_dsf.cpp @@ -48,29 +48,29 @@ PairBuck6dCoulGaussDSF::PairBuck6dCoulGaussDSF(LAMMPS *lmp) : Pair(lmp) PairBuck6dCoulGaussDSF::~PairBuck6dCoulGaussDSF() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(alpha_ij); - memory->destroy(f_shift_ij); - memory->destroy(e_shift_ij); - memory->destroy(buck6d1); - memory->destroy(buck6d2); - memory->destroy(buck6d3); - memory->destroy(buck6d4); - memory->destroy(c0); - memory->destroy(c1); - memory->destroy(c2); - memory->destroy(c3); - memory->destroy(c4); - memory->destroy(c5); - memory->destroy(rsmooth_sq); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(alpha_ij); + memory->destroy(f_shift_ij); + memory->destroy(e_shift_ij); + memory->destroy(buck6d1); + memory->destroy(buck6d2); + memory->destroy(buck6d3); + memory->destroy(buck6d4); + memory->destroy(c0); + memory->destroy(c1); + memory->destroy(c2); + memory->destroy(c3); + memory->destroy(c4); + memory->destroy(c5); + memory->destroy(rsmooth_sq); + memory->destroy(offset); } } diff --git a/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp b/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp index 1ca42d864e..7df1ee4a1f 100644 --- a/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp +++ b/src/USER-MOFFF/pair_buck6d_coul_gauss_long.cpp @@ -51,27 +51,27 @@ PairBuck6dCoulGaussLong::PairBuck6dCoulGaussLong(LAMMPS *lmp) : Pair(lmp) PairBuck6dCoulGaussLong::~PairBuck6dCoulGaussLong() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(alpha_ij); - memory->destroy(buck6d1); - memory->destroy(buck6d2); - memory->destroy(buck6d3); - memory->destroy(buck6d4); - memory->destroy(c0); - memory->destroy(c1); - memory->destroy(c2); - memory->destroy(c3); - memory->destroy(c4); - memory->destroy(c5); - memory->destroy(rsmooth_sq); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(alpha_ij); + memory->destroy(buck6d1); + memory->destroy(buck6d2); + memory->destroy(buck6d3); + memory->destroy(buck6d4); + memory->destroy(c0); + memory->destroy(c1); + memory->destroy(c2); + memory->destroy(c3); + memory->destroy(c4); + memory->destroy(c5); + memory->destroy(rsmooth_sq); + memory->destroy(offset); } } diff --git a/src/pair_lj_cut_coul_dsf.cpp b/src/pair_lj_cut_coul_dsf.cpp index a49af13fb2..ba4a9ef201 100644 --- a/src/pair_lj_cut_coul_dsf.cpp +++ b/src/pair_lj_cut_coul_dsf.cpp @@ -52,21 +52,21 @@ PairLJCutCoulDSF::PairLJCutCoulDSF(LAMMPS *lmp) : Pair(lmp) PairLJCutCoulDSF::~PairLJCutCoulDSF() { - if (!copymode) { - if (allocated) { - memory->destroy(setflag); - memory->destroy(cutsq); - - memory->destroy(cut_lj); - memory->destroy(cut_ljsq); - memory->destroy(epsilon); - memory->destroy(sigma); - memory->destroy(lj1); - memory->destroy(lj2); - memory->destroy(lj3); - memory->destroy(lj4); - memory->destroy(offset); - } + if (copymode) return; + + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + + memory->destroy(cut_lj); + memory->destroy(cut_ljsq); + memory->destroy(epsilon); + memory->destroy(sigma); + memory->destroy(lj1); + memory->destroy(lj2); + memory->destroy(lj3); + memory->destroy(lj4); + memory->destroy(offset); } } diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp index 9aa58b3b88..abb57534cd 100644 --- a/src/pair_lj_expand.cpp +++ b/src/pair_lj_expand.cpp @@ -38,8 +38,9 @@ PairLJExpand::PairLJExpand(LAMMPS *lmp) : Pair(lmp) PairLJExpand::~PairLJExpand() { - if (!copymode) { - if (allocated) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -52,7 +53,6 @@ PairLJExpand::~PairLJExpand() memory->destroy(lj3); memory->destroy(lj4); memory->destroy(offset); - } } } diff --git a/src/pair_lj_gromacs.cpp b/src/pair_lj_gromacs.cpp index 495e96c368..da0c8148e2 100644 --- a/src/pair_lj_gromacs.cpp +++ b/src/pair_lj_gromacs.cpp @@ -41,8 +41,9 @@ PairLJGromacs::PairLJGromacs(LAMMPS *lmp) : Pair(lmp) PairLJGromacs::~PairLJGromacs() { - if (!copymode) { - if (allocated) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -60,7 +61,6 @@ PairLJGromacs::~PairLJGromacs() memory->destroy(ljsw3); memory->destroy(ljsw4); memory->destroy(ljsw5); - } } } diff --git a/src/pair_lj_gromacs_coul_gromacs.cpp b/src/pair_lj_gromacs_coul_gromacs.cpp index 414bfea92a..b003d3c068 100644 --- a/src/pair_lj_gromacs_coul_gromacs.cpp +++ b/src/pair_lj_gromacs_coul_gromacs.cpp @@ -41,8 +41,9 @@ PairLJGromacsCoulGromacs::PairLJGromacsCoulGromacs(LAMMPS *lmp) : Pair(lmp) PairLJGromacsCoulGromacs::~PairLJGromacsCoulGromacs() { - if (!copymode) { - if (allocated) { + if (copymode) return; + + if (allocated) { memory->destroy(setflag); memory->destroy(cutsq); @@ -57,7 +58,6 @@ PairLJGromacsCoulGromacs::~PairLJGromacsCoulGromacs() memory->destroy(ljsw3); memory->destroy(ljsw4); memory->destroy(ljsw5); - } } } -- GitLab From 8916aeb36daad1b02ae565baf8f72a4c2dafe640 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 05:25:14 -0400 Subject: [PATCH 0286/1243] update for README to USER-SMTBQ with up-to-date maintainer e-mails --- src/USER-SMTBQ/README | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/USER-SMTBQ/README b/src/USER-SMTBQ/README index 74b621eef1..e778c65be2 100644 --- a/src/USER-SMTBQ/README +++ b/src/USER-SMTBQ/README @@ -2,9 +2,11 @@ This package implements the Second Moment Tight Binding - QEq (SMTB-Q) potential for the description of ionocovalent bonds in oxides. Authors: Nicolas Salles, Emile Maras, Olivier Politano, Robert Tetot -at LAAS-CNRS in France. +at ICB, Universite de Bourgogne and ICMMO, Universite Paris-Sud. -Contact emails: lammps@u-bourgogne.fr, nsalles@laas.fr +Contact emails: lammps@u-bourgogne.fr, nsalles33@gmail.com + +This package is occasionally maintained. See the doc page for the pair_style smtbq command to get started. -- GitLab From 75d63df4e029a15a1780e3337b6ab0b806aeea68 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 05:41:32 -0400 Subject: [PATCH 0287/1243] fix small memory leak in pair style hybrid when reading restarts --- src/pair_hybrid.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/pair_hybrid.cpp b/src/pair_hybrid.cpp index 2b2304718c..2b6546aef3 100644 --- a/src/pair_hybrid.cpp +++ b/src/pair_hybrid.cpp @@ -45,7 +45,7 @@ PairHybrid::PairHybrid(LAMMPS *lmp) : Pair(lmp), PairHybrid::~PairHybrid() { - if (nstyles) { + if (nstyles > 0) { for (int m = 0; m < nstyles; m++) { delete styles[m]; delete [] keywords[m]; @@ -243,11 +243,18 @@ void PairHybrid::settings(int narg, char **arg) // delete old lists, since cannot just change settings - if (nstyles) { - for (int m = 0; m < nstyles; m++) delete styles[m]; - delete [] styles; - for (int m = 0; m < nstyles; m++) delete [] keywords[m]; - delete [] keywords; + if (nstyles > 0) { + for (int m = 0; m < nstyles; m++) { + delete styles[m]; + delete [] keywords[m]; + if (special_lj[m]) delete [] special_lj[m]; + if (special_coul[m]) delete [] special_coul[m]; + } + delete[] styles; + delete[] keywords; + delete[] multiple; + delete[] special_lj; + delete[] special_coul; } if (allocated) { @@ -670,6 +677,12 @@ void PairHybrid::read_restart(FILE *fp) // allocate list of sub-styles + delete[] styles; + delete[] keywords; + delete[] multiple; + delete[] special_lj; + delete[] special_coul; + styles = new Pair*[nstyles]; keywords = new char*[nstyles]; multiple = new int[nstyles]; -- GitLab From cd6b23d1041501543889050f8d6b8396cc3645c4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 09:50:31 -0400 Subject: [PATCH 0288/1243] explicitly request OpenCL version 1.2 compatibility when compiling GPU package kernels for OpenCL --- lib/gpu/lal_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gpu/lal_device.cpp b/lib/gpu/lal_device.cpp index 6b4d0ab2a5..9397f3c6c5 100644 --- a/lib/gpu/lal_device.cpp +++ b/lib/gpu/lal_device.cpp @@ -237,7 +237,7 @@ int DeviceT::set_ocl_params(char *ocl_vendor) { " -DBLOCK_CELL_ID="+params[11]+ " -DMAX_BIO_SHARED_TYPES="+params[12]; } - _ocl_compile_string="-cl-fast-relaxed-math -cl-mad-enable "+std::string(OCL_INT_TYPE)+" "+ + _ocl_compile_string="-cl-std=CL1.2 -cl-fast-relaxed-math -cl-mad-enable "+std::string(OCL_INT_TYPE)+" "+ std::string(OCL_PRECISION_COMPILE)+" "+_ocl_vendor_string; #endif return 0; -- GitLab From 0f030acc597c55152a79a3f50d91b5c6527546e1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 11:59:15 -0400 Subject: [PATCH 0289/1243] refactoring python module installer script to be (more) platform neutral and compatible with conventional make and CMake builds --- python/install.py | 124 ++++++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 43 deletions(-) diff --git a/python/install.py b/python/install.py index 9308506fd2..ab54adee56 100644 --- a/python/install.py +++ b/python/install.py @@ -1,56 +1,95 @@ #!/usr/bin/env python -# copy LAMMPS src/liblammps.so and lammps.py to system dirs - -from __future__ import print_function - -instructions = """ -Syntax: python install.py [-h] [pydir] - pydir = target dir for lammps.py and liblammps.so - default = Python site-packages dir +""" +Installer script to install the LAMMPS python module and the corresponding +shared library into either the system-wide site-packages tree, or - failing +that - into the corresponding user tree. Called from the 'install-python' +build target in the conventional and CMake based build systems """ -import sys,os,shutil - -if (len(sys.argv) > 1 and sys.argv[1] == "-h") or len(sys.argv) > 2: - print(instructions) - sys.exit() - -if len(sys.argv) == 2: pydir = sys.argv[1] -else: pydir = "" - -# copy lammps.py to pydir if it exists -# if pydir not specified, install in site-packages via distutils setup() +# copy LAMMPS shared library and lammps.py to system dirs -if pydir: - if not os.path.isdir(pydir): - print( "ERROR: pydir %s does not exist" % pydir) - sys.exit() - str = "cp ../python/lammps.py %s" % pydir - print(str) +from __future__ import print_function +import sys,os,shutil +from argparse import ArgumentParser + +parser = ArgumentParser(prog='install.py', + description='LAMMPS python module installer script') + +parser.add_argument("-m", "--module", required=True, + help="path to the source of the LAMMPS Python module") +parser.add_argument("-l", "--lib", required=True, + help="path to the compiled LAMMPS shared library") +parser.add_argument("-v", "--version", required=True, + help="path to the LAMMPS version.h header file") +parser.add_argument("-d","--dir", + help="custom installation folder for module and library") + +args = parser.parse_args() + +# validate arguments and make paths absolute + +if args.module: + if not os.path.exists(args.module): + print( "ERROR: LAMMPS module file %s does not exist" % args.module) + parser.print_help() + sys.exit(1) + else: + args.module = os.path.abspath(args.module) + +if args.lib: + if not os.path.exists(args.lib): + print( "ERROR: LAMMPS shared library %s does not exist" % args.lib) + parser.print_help() + sys.exit(1) + else: + args.lib = os.path.abspath(args.lib) + +if args.version: + if not os.path.exists(args.version): + print( "ERROR: LAMMPS version header file %s does not exist" % args.version) + parser.print_help() + sys.exit(1) + else: + args.version = os.path.abspath(args.version) + +if args.dir: + if not os.path.isdir(args.dir): + print( "ERROR: Installation folder %s does not exist" % args.dir) + parser.print_help() + sys.exit(1) + else: + args.dir = os.path.abspath(args.dir) + +# if a custom directory is given, we copy the files directly +# without any special processing or additional steps to that folder + +if args.dir: + print("Copying LAMMPS Python module to custom folder %s" % args.dir) try: - shutil.copyfile("../python/lammps.py", os.path.join(pydir,'lammps.py') ) + shutil.copyfile(args.module, os.path.join(args.dir,'lammps.py')) except shutil.Error: - pass # source and destination are identical + pass # fail silently - str = "cp ../src/liblammps.so %s" % pydir - print(str) + print("Copying LAMMPS shared library to custom folder %s" % args.dir) try: - shutil.copyfile("../src/liblammps.so", os.path.join(pydir,"liblammps.so") ) + shutil.copyfile(args.lib, os.path.join(args.dir,os.path.basename(args.lib))) except shutil.Error: - pass # source and destination are identical + pass # fail silently + sys.exit() -print("installing lammps.py in Python site-packages dir") - -os.chdir('../python') # in case invoked via make in src dir - # extract version string from header -fp = open('../src/version.h','r') +fp = open(args.version,'r') txt=fp.read().split('"')[1].split() verstr=txt[0]+txt[1]+txt[2] fp.close() +print("Installing LAMMPS Python module version %s into site-packages folder" % verstr) + +# we need to switch to the folder of the python module +os.chdir(os.path.dirname(args.module)) + from distutils.core import setup from distutils.sysconfig import get_python_lib import site @@ -63,13 +102,12 @@ try: author = "Steve Plimpton", author_email = "sjplimp@sandia.gov", url = "http://lammps.sandia.gov", - description = "LAMMPS molecular dynamics library", + description = "LAMMPS Molecular Dynamics Python module", py_modules = ["lammps"], - data_files = [(get_python_lib(), ["../src/liblammps.so"])]) + data_files = [(get_python_lib(), [args.lib])]) except: tryuser=True - print ("Installation into global site-packages dir failed.\nTrying user site dir %s now." % site.USER_SITE) - + print ("Installation into global site-packages folder failed.\nTrying user folder %s now." % site.USER_SITE) if tryuser: try: @@ -79,11 +117,11 @@ if tryuser: author = "Steve Plimpton", author_email = "sjplimp@sandia.gov", url = "http://lammps.sandia.gov", - description = "LAMMPS molecular dynamics library", + description = "LAMMPS Molecular Dynamics Python module", py_modules = ["lammps"], - data_files = [(site.USER_SITE, ["../src/liblammps.so"])]) + data_files = [(site.USER_SITE, [args.lib])]) except: - print("Installation into user site package dir failed.\nGo to ../python and install manually.") + print("Installation into user site package folder failed.") -- GitLab From 817a851a3070755c18fcaef8a59c9eaafd97eaf9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 12:01:59 -0400 Subject: [PATCH 0290/1243] adapt master makefile to refactored python module installer script --- src/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index f1030ae08f..3be4e3e78f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -275,7 +275,8 @@ mpi-stubs: sinclude ../lib/python/Makefile.lammps install-python: - @$(PYTHON) ../python/install.py + @$(PYTHON) ../python/install.py -v ../src/version.h \ + -m ../python/lammps.py -l ../src/liblammps.so # Create a tarball of src dir and packages -- GitLab From 04f999fdd6619867aedc2a6c9414857481c37463 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 12:35:21 -0400 Subject: [PATCH 0291/1243] add install-python target to CMake build system. decouple python module install from python package --- cmake/CMakeLists.txt | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f6f822676e..4543dbc502 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -381,19 +381,10 @@ if(PKG_MSCG OR PKG_USER-ATC OR PKG_USER-AWPMD OR PKG_USER-QUIP OR PKG_LATTE) endif() if(PKG_PYTHON) - find_package(PythonInterp REQUIRED) find_package(PythonLibs REQUIRED) add_definitions(-DLMP_PYTHON) include_directories(${PYTHON_INCLUDE_DIR}) list(APPEND LAMMPS_LINK_LIBS ${PYTHON_LIBRARY}) - if(BUILD_LIB AND BUILD_SHARED_LIBS) - if(NOT PYTHON_INSTDIR) - execute_process(COMMAND ${PYTHON_EXECUTABLE} - -c "import distutils.sysconfig as cg; print(cg.get_python_lib(1,0,prefix='${CMAKE_INSTALL_PREFIX}'))" - OUTPUT_VARIABLE PYTHON_INSTDIR OUTPUT_STRIP_TRAILING_WHITESPACE) - endif() - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../python/lammps.py DESTINATION ${PYTHON_INSTDIR}) - endif() endif() find_package(JPEG QUIET) @@ -1483,6 +1474,22 @@ install( DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/profile.d ) +############################################################################### +# Install LAMMPS module into site-packages folder +# Only available, if a shared library is built +############################################################################### +if(BUILD_LIB AND BUILD_SHARED_LIBS) + find_package(PythonInterp) + add_custom_target( + install-python + ${PYTHON_EXECUTABLE} install.py -v ${LAMMPS_SOURCE_DIR}/version.h + -m ${CMAKE_CURRENT_SOURCE_DIR}/../python/lammps.py + -l ${CMAKE_BINARY_DIR}/liblammps${CMAKE_SHARED_LIBRARY_SUFFIX} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../python + COMMENT "Installing LAMMPS Python module" + ) +endif() + ############################################################################### # Testing # -- GitLab From e50c269a6bf1f664e36fe1f9f7b644d97c250522 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 12:51:57 -0400 Subject: [PATCH 0292/1243] add install-python target with suitable error message also when not building a shared library --- cmake/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4543dbc502..e138a7dffc 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1488,6 +1488,10 @@ if(BUILD_LIB AND BUILD_SHARED_LIBS) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../python COMMENT "Installing LAMMPS Python module" ) +else() + add_custom_target( + install-python + echo "Installation of the LAMMPS Python module requires building the LAMMPS shared library") endif() ############################################################################### -- GitLab From c23ace9c972a47f3cd733f093662d14ac46fbe20 Mon Sep 17 00:00:00 2001 From: julient31 Date: Fri, 22 Mar 2019 11:52:09 -0600 Subject: [PATCH 0293/1243] Commit JT 032219 - fixed bug 1: precession_spin had no min_setup - fixed bug 2: incorrect init of spins in neb/spin - improved doc min_spin.txt (added eqs, and connected to related files). --- doc/src/Eqs/min_spin_damping.jpg | Bin 0 -> 7035 bytes doc/src/Eqs/min_spin_damping.tex | 13 ++++++ doc/src/Eqs/min_spin_timestep.jpg | Bin 0 -> 5984 bytes doc/src/Eqs/min_spin_timestep.tex | 14 +++++++ doc/src/fix_precession_spin.txt | 2 +- doc/src/lammps.book | 1 + doc/src/min_modify.txt | 11 +++++- doc/src/min_spin.txt | 63 ++++++++++++++++++++++++++++++ doc/src/min_style.txt | 10 ++--- doc/src/minimize.txt | 7 ++++ src/SPIN/atom_vec_spin.cpp | 4 ++ src/SPIN/fix_precession_spin.cpp | 9 ++++- src/SPIN/fix_precession_spin.h | 1 + src/SPIN/min_spin.cpp | 6 ++- src/SPIN/neb_spin.cpp | 63 ++++++++++++++++++------------ src/SPIN/pair_spin_dmi.cpp | 6 +-- 16 files changed, 168 insertions(+), 42 deletions(-) create mode 100644 doc/src/Eqs/min_spin_damping.jpg create mode 100644 doc/src/Eqs/min_spin_damping.tex create mode 100644 doc/src/Eqs/min_spin_timestep.jpg create mode 100644 doc/src/Eqs/min_spin_timestep.tex create mode 100644 doc/src/min_spin.txt diff --git a/doc/src/Eqs/min_spin_damping.jpg b/doc/src/Eqs/min_spin_damping.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0c700cc67863762a99f9b9e3df0cb945612a2e38 GIT binary patch literal 7035 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 literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/min_spin_damping.tex b/doc/src/Eqs/min_spin_damping.tex new file mode 100644 index 0000000000..88b05447d3 --- /dev/null +++ b/doc/src/Eqs/min_spin_damping.tex @@ -0,0 +1,13 @@ +\documentclass[preview]{standalone} +\usepackage{varwidth} +\usepackage[utf8x]{inputenc} +\usepackage{amsmath, amssymb, graphics, setspace} + +\begin{document} +\begin{varwidth}{50in} + \begin{equation} + \frac{d \vec{s}_{i}}{dt} = \lambda\, \vec{s}_{i} \times\left( \vec{\omega}_{i} \times\vec{s}_{i} \right) + \nonumber + \end{equation} +\end{varwidth} +\end{document} diff --git a/doc/src/Eqs/min_spin_timestep.jpg b/doc/src/Eqs/min_spin_timestep.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0d8f8d07f9ff6ef23a0b8a136b05bf36a1952bb6 GIT binary patch literal 5984 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 XiG>~e4loFX-kSO+GyB7ThW|GK9=c85 literal 0 HcmV?d00001 diff --git a/doc/src/Eqs/min_spin_timestep.tex b/doc/src/Eqs/min_spin_timestep.tex new file mode 100644 index 0000000000..b0f6e68e4d --- /dev/null +++ b/doc/src/Eqs/min_spin_timestep.tex @@ -0,0 +1,14 @@ +\documentclass[preview]{standalone} +\usepackage{varwidth} +\usepackage[utf8x]{inputenc} +\usepackage{amsmath, amssymb, graphics, setspace} + +\begin{document} +\begin{varwidth}{50in} + \begin{equation} + {\Delta t}_{\rm max} = \frac{2\pi}{\kappa + \left|\vec{\omega}_{\rm max} \right|} + \nonumber + \end{equation} +\end{varwidth} +\end{document} diff --git a/doc/src/fix_precession_spin.txt b/doc/src/fix_precession_spin.txt index f16522c7b6..05814931ea 100644 --- a/doc/src/fix_precession_spin.txt +++ b/doc/src/fix_precession_spin.txt @@ -31,7 +31,7 @@ fix 1 all precession/spin zeeman 0.1 0.0 0.0 1.0 anisotropy 0.001 0.0 0.0 1.0 :p [Description:] -Impose a force torque to each magnetic spin in the group. +This fix applies a precession torque to each magnetic spin in the group. Style {zeeman} is used for the simulation of the interaction between the magnetic spins in the defined group and an external diff --git a/doc/src/lammps.book b/doc/src/lammps.book index 198e234f0c..88625e0b73 100644 --- a/doc/src/lammps.book +++ b/doc/src/lammps.book @@ -174,6 +174,7 @@ mass.html message.html min_modify.html min_style.html +min_spin.html minimize.html molecule.html neb.html diff --git a/doc/src/min_modify.txt b/doc/src/min_modify.txt index 701f579af4..525d6716d8 100644 --- a/doc/src/min_modify.txt +++ b/doc/src/min_modify.txt @@ -21,7 +21,7 @@ keyword = {dmax} or {line} or {alpha_damp} or {discret_factor} {alpha_damp} value = damping damping = fictitious Gilbert damping for spin minimization (adim) {discret_factor} value = factor - factor = defines a dividing factor for adaptive spin timestep (adim) :pre + factor = discretization factor for adaptive spin timestep (adim) :pre :ule [Examples:] @@ -70,7 +70,14 @@ that difference may be smaller than machine epsilon even if atoms could move in the gradient direction to reduce forces further. Keywords {alpha_damp} and {discret_factor} only make sense when -a {spinmin} minimization style is declared. +a "min_spin"_min_spin.html command is declared. +Keyword {alpha_damp} defines an analog of a magnetic Gilbert +damping. It defines a relaxation rate toward an equilibrium for +a given magnetic system. +Keyword {discret_factor} defines a discretization factor for the +adaptive timestep used in the {spin} minimization. +See "min_spin"_min_spin.html for more information about those +quantities. Default values are alpha_damp = 1.0 and discret_factor = 10.0. [Restrictions:] none diff --git a/doc/src/min_spin.txt b/doc/src/min_spin.txt new file mode 100644 index 0000000000..468cde0fec --- /dev/null +++ b/doc/src/min_spin.txt @@ -0,0 +1,63 @@ +"LAMMPS WWW Page"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c + +:link(lws,http://lammps.sandia.gov) +:link(ld,Manual.html) +:link(lc,Commands_all.html) + +:line + +min_style spin command :h3 + +[Syntax:] + +min_style spin :pre + +[Examples:] + +min_style spin +min_modify alpha_damp 1.0 discret_factor 10.0 :pre + +[Description:] + +Apply a minimization algorithm to use when a "minimize"_minimize.html +command is performed. + +Style {spin} defines a damped spin dynamics with an adaptive +timestep, according to: + +:c,image(Eqs/min_spin_damping.jpg) + +with lambda a damping coefficient (similar to a Gilbert damping) +Lambda can be defined by setting the {alpha_damp} keyword with the +"min_modify"_min_modify.html command. + +The minimization procedure solves this equation using an +adaptive timestep. The value of this timestep is conditionned +by the largest precession frequency that has to be solved in the +system: + +:c,image(Eqs/min_spin_timestep.jpg) + +with |omega|_{max} the norm of the largest precession frequency +in the system (across all processes, and across all replicas if a +spin/neb calculation is performed). + +Kappa defines a discretization factor {discret_factor} for the +definition of this timestep. +{discret_factor} can be defined with the "min_modify"_min_modify.html +command. + +NOTE: The {spin} style replaces the force tolerance by a torque +tolerance. See "minimize"_minimize.html for more explanation. + +[Restrictions:] none + +[Related commands:] + +"min_style"_min_style.html, "minimize"_minimize.html, +"min_modify"_min_modify.html + +[Default:] + +The option defaults are alpha_damp = 1.0 and discret_factor = +10.0. diff --git a/doc/src/min_style.txt b/doc/src/min_style.txt index f8c05d5483..c46c1492b4 100644 --- a/doc/src/min_style.txt +++ b/doc/src/min_style.txt @@ -16,7 +16,7 @@ style = {cg} or {hftn} or {sd} or {quickmin} or {fire} or {spin} :ul [Examples:] min_style cg -min_style spinmin +min_style spin min_style fire :pre [Description:] @@ -62,17 +62,13 @@ the velocity non-parallel to the current force vector. The velocity of each atom is initialized to 0.0 by this style, at the beginning of a minimization. -Style {spin} is a damped spin dynamics with a variable -timestep as described in "(Tranchida)"_#Tranchida. +Style {spin} is a damped spin dynamics with an adaptive +timestep. See the "min/spin"_min_spin.html doc page for more information. Either the {quickmin} and {fire} styles are useful in the context of nudged elastic band (NEB) calculations via the "neb"_neb.html command. -The {spin} style is useful in the context of geodesic nudged -elastic band (GNEB) calculations via the "neb/spin"_neb_spin.html -command. - NOTE: The damped dynamic minimizers use whatever timestep you have defined via the "timestep"_timestep.html command. Often they will converge more quickly if you use a timestep about 10x larger than you diff --git a/doc/src/minimize.txt b/doc/src/minimize.txt index 00de86c5f5..ecf1ad0fcf 100644 --- a/doc/src/minimize.txt +++ b/doc/src/minimize.txt @@ -103,6 +103,13 @@ the line search fails because the step distance backtracks to 0.0 the number of outer iterations or timesteps exceeds {maxiter} the number of total force evaluations exceeds {maxeval} :ul +NOTE: the "minimization style"_min_style.html {spin} replaces +the force tolerance {ftol} by a torque tolerance. +The minimization procedure stops if the 2-norm (length) of the +global torque vector (defined as the cross product between the +spins and their precession vectors omega) is less than {ftol}, +or if any of the other criteria are met. + NOTE: You can also use the "fix halt"_fix_halt.html command to specify a general criterion for exiting a minimization, that is a calculation performed on the state of the current system, as defined by an diff --git a/src/SPIN/atom_vec_spin.cpp b/src/SPIN/atom_vec_spin.cpp index 24c4480e04..a6c0430940 100644 --- a/src/SPIN/atom_vec_spin.cpp +++ b/src/SPIN/atom_vec_spin.cpp @@ -943,6 +943,10 @@ bigint AtomVecSpin::memory_usage() return bytes; } +/* ---------------------------------------------------------------------- + clear all forces (mech and mag) +------------------------------------------------------------------------- */ + void AtomVecSpin::force_clear(int /*n*/, size_t nbytes) { memset(&atom->f[0][0],0,3*nbytes); diff --git a/src/SPIN/fix_precession_spin.cpp b/src/SPIN/fix_precession_spin.cpp index 6ccb692033..d065f38d16 100644 --- a/src/SPIN/fix_precession_spin.cpp +++ b/src/SPIN/fix_precession_spin.cpp @@ -170,7 +170,14 @@ void FixPrecessionSpin::setup(int vflag) /* ---------------------------------------------------------------------- */ -void FixPrecessionSpin::post_force(int /*vflag*/) +void FixPrecessionSpin::min_setup(int vflag) +{ + post_force(vflag); +} + +/* ---------------------------------------------------------------------- */ + +void FixPrecessionSpin::post_force(int vflag) { // update mag field with time (potential improvement) diff --git a/src/SPIN/fix_precession_spin.h b/src/SPIN/fix_precession_spin.h index 2fe6b5a673..1db4d32ae9 100644 --- a/src/SPIN/fix_precession_spin.h +++ b/src/SPIN/fix_precession_spin.h @@ -33,6 +33,7 @@ class FixPrecessionSpin : public Fix { 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); diff --git a/src/SPIN/min_spin.cpp b/src/SPIN/min_spin.cpp index ac8f22186e..99aa4ac3b7 100644 --- a/src/SPIN/min_spin.cpp +++ b/src/SPIN/min_spin.cpp @@ -102,7 +102,7 @@ void MinSpin::reset_vectors() { // atomic dof - // not really good size => sp is 4N vector + // size sp is 4N vector nvec = 4 * atom->nlocal; if (nvec) spvec = atom->sp[0]; @@ -132,7 +132,9 @@ int MinSpin::iterate(int maxiter) niter++; // optimize timestep accross processes / replicas - + // need a force calculation for timestep optimization + + energy_force(0); dts = evaluate_dt(); // apply damped precessional dynamics to the spins diff --git a/src/SPIN/neb_spin.cpp b/src/SPIN/neb_spin.cpp index f5d9a75020..728532a187 100644 --- a/src/SPIN/neb_spin.cpp +++ b/src/SPIN/neb_spin.cpp @@ -44,7 +44,6 @@ #include "timer.h" #include "memory.h" #include "error.h" -#include "force.h" #include "math_const.h" using namespace LAMMPS_NS; @@ -101,14 +100,22 @@ NEB_spin::NEB_spin(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, spfinal[1] = buf_final[ii+1]; spfinal[2] = buf_final[ii+2]; - // circular initialization - // a better procedure may be developed - - initial_rotation(spinit,spfinal,fraction); - - sp[i][0] = spfinal[0]; - sp[i][1] = spfinal[1]; - sp[i][2] = spfinal[2]; + // interpolate intermediate spin states + + if (fraction == 0.0) { + sp[i][0] = spinit[0]; + sp[i][1] = spinit[1]; + sp[i][2] = spinit[2]; + } else if (fraction == 1.0) { + sp[i][0] = spfinal[0]; + sp[i][1] = spfinal[1]; + sp[i][2] = spfinal[2]; + } else { + initial_rotation(spinit,spfinal,fraction); + sp[i][0] = spfinal[0]; + sp[i][1] = spfinal[1]; + sp[i][2] = spfinal[2]; + } ii += 3; } @@ -499,7 +506,7 @@ void NEB_spin::readfile(char *file, int flag) for (j = 1; j < nwords; j++) values[j] = strtok(NULL," \t\n\r\f"); - // adjust atom coord based on replica fraction + // adjust spin coord based on replica fraction // for flag = 0, interpolate for intermediate and final replicas // for flag = 1, replace existing coord with new coord // ignore image flags of final x @@ -530,19 +537,24 @@ void NEB_spin::readfile(char *file, int flag) spfinal[0] = spx; spfinal[1] = spy; spfinal[2] = spz; - - printf("test spinit[0]:%g \n",sp[m][0]); - + // interpolate intermediate spin states - initial_rotation(spinit,spfinal,fraction); - - printf("test spfinal[0]:%g \n",spfinal[0]); - - sp[m][0] = spfinal[0]; - sp[m][1] = spfinal[1]; - sp[m][2] = spfinal[2]; sp[m][3] = musp; + if (fraction == 0.0) { + sp[m][0] = spinit[0]; + sp[m][1] = spinit[1]; + sp[m][2] = spinit[2]; + } else if (fraction == 1.0) { + sp[m][0] = spfinal[0]; + sp[m][1] = spfinal[1]; + sp[m][2] = spfinal[2]; + } else { + initial_rotation(spinit,spfinal,fraction); + sp[m][0] = spfinal[0]; + sp[m][1] = spfinal[1]; + sp[m][2] = spfinal[2]; + } } else { sp[m][3] = musp; x[m][0] = xx; @@ -560,8 +572,6 @@ void NEB_spin::readfile(char *file, int flag) nread += nchunk; } - printf("test sp[1][2]:%g \n",sp[1][2]); - // check that all atom IDs in file were found by a proc if (flag == 0) { @@ -605,6 +615,10 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) // implementing initial rotation using atan2 // this may not be a sufficient routine, need more accurate verifications + // interpolation only for intermediate replica + + if (fraction == 0.0 || fraction == 1.0) return; + // initial, final and inter ang. values double itheta,iphi,ftheta,fphi,ktheta,kphi; @@ -636,7 +650,7 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) spky = sin(ktheta)*sin(kphi); spkz = cos(kphi); - double knormsq = spkx*spkx+spky*spky+spkz*spkz; + double knormsq = spkx*spkx + spky*spky + spkz*spkz; if (knormsq != 0.0) iknorm = 1.0/sqrt(knormsq); @@ -696,9 +710,6 @@ void NEB_spin::initial_rotation(double *spi, double *sploc, double fraction) //spky *= iknorm; //spkz *= iknorm; - printf("init: %g %g %g \n",spix,spiy,spiz); - printf("fina: %g %g %g \n",spkx,spky,spkz); - sploc[0] = spkx; sploc[1] = spky; sploc[2] = spkz; diff --git a/src/SPIN/pair_spin_dmi.cpp b/src/SPIN/pair_spin_dmi.cpp index 9b193f7e08..e54864e126 100644 --- a/src/SPIN/pair_spin_dmi.cpp +++ b/src/SPIN/pair_spin_dmi.cpp @@ -432,9 +432,9 @@ void PairSpinDmi::compute_dmi(int i, int j, double eij[3], double fmi[3], double dmiy = eij[2]*v_dmx[itype][jtype] - eij[0]*v_dmz[itype][jtype]; dmiz = eij[0]*v_dmy[itype][jtype] - eij[1]*v_dmx[itype][jtype]; - fmi[0] -= (spj[1]*dmiz - spj[2]*dmiy); - fmi[1] -= (spj[2]*dmix - spj[0]*dmiz); - fmi[2] -= (spj[0]*dmiy - spj[1]*dmix); + fmi[0] -= (dmiy*spj[2] - dmiz*spj[1]); + fmi[1] -= (dmiz*spj[0] - dmix*spj[2]); + fmi[2] -= (dmix*spj[1] - dmiy*spj[0]); } /* ---------------------------------------------------------------------- -- GitLab From 52f9e4a960ef477a54750f7b36740693c5018e75 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 14:11:02 -0400 Subject: [PATCH 0294/1243] allow overriding the location of the molfile plugin headers with CMake --- cmake/CMakeLists.txt | 4 ++-- doc/src/Build_extras.txt | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f6f822676e..327a94237b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -613,8 +613,9 @@ if(PKG_USER-PLUMED) endif() if(PKG_USER-MOLFILE) + set(MOLFILE_INCLUDE_DIRS "${LAMMPS_LIB_SOURCE_DIR}/molfile" CACHE STRING "Path to VMD molfile plugin headers") add_library(molfile INTERFACE) - target_include_directories(molfile INTERFACE ${LAMMPS_LIB_SOURCE_DIR}/molfile) + target_include_directories(molfile INTERFACE ${MOLFILE_INCLUDE_DIRS}) target_link_libraries(molfile INTERFACE ${CMAKE_DL_LIBS}) list(APPEND LAMMPS_LINK_LIBS molfile) endif() @@ -626,7 +627,6 @@ if(PKG_USER-NETCDF) add_definitions(-DLMP_HAS_NETCDF -DNC_64BIT_DATA=0x0020) endif() - if(PKG_USER-SMD) option(DOWNLOAD_EIGEN3 "Download Eigen3 instead of using an already installed one)" OFF) if(DOWNLOAD_EIGEN3) diff --git a/doc/src/Build_extras.txt b/doc/src/Build_extras.txt index cbbd9db2f3..3ee8d06b8e 100644 --- a/doc/src/Build_extras.txt +++ b/doc/src/Build_extras.txt @@ -893,7 +893,17 @@ USER-MOLFILE package :h4,link(user-molfile) [CMake build]: -No additional settings are needed besides "-D PKG_USER-MOLFILE=yes". +-D MOLFILE_INCLUDE_DIRS=path # (optional) path where VMD molfile plugin headers are installed +-D PKG_USER-MOLFILE=yes :pre + + +Using "-D PKG_USER-MOLFILE=yes" enables the package, and setting +"-D MOLFILE_INCLUDE DIRS" allows to provide a custom location for +the molfile plugin header files. These should match the ABI of the +plugin files used, and thus one typically sets them to include +folder of the local VMD installation in use. LAMMPS ships with a +couple of default header files that correspond to a popular VMD +version, usually the latest release. [Traditional make]: @@ -902,7 +912,11 @@ loading library libdl.a that is typically present on all systems. It is required for LAMMPS to link with this package. If the setting is not valid for your system, you will need to edit the Makefile.lammps file. See lib/molfile/README and lib/molfile/Makefile.lammps for -details. +details. It is also possible to configure a different folder with +the VMD molfile plugin header files. LAMMPS ships with a couple of +default headers, but these are not compatible with all VMD versions, +so it is often best to change this setting to the location of the +same include files of the local VMD installation in use. :line -- GitLab From f69173f410190f162f00127dec4da41c80b973d8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 17:25:03 -0400 Subject: [PATCH 0295/1243] partial documentation update --- doc/src/Python_install.txt | 68 ++++++++++++++++--------------------- doc/src/Python_overview.txt | 19 ++++++----- python/README | 4 +-- 3 files changed, 42 insertions(+), 49 deletions(-) diff --git a/doc/src/Python_install.txt b/doc/src/Python_install.txt index 97f6bf3c3a..403cf052da 100644 --- a/doc/src/Python_install.txt +++ b/doc/src/Python_install.txt @@ -12,16 +12,22 @@ Installing LAMMPS in Python :h3 For Python to invoke LAMMPS, there are 2 files it needs to know about: python/lammps.py -src/liblammps.so :ul +liblammps.so or liblammps.dylib :ul -Lammps.py is the Python wrapper on the LAMMPS library interface. -Liblammps.so is the shared LAMMPS library that Python loads, as -described above. +The python source code in lammps.py is the Python wrapper on the +LAMMPS library interface. The liblammps.so or liblammps.dylib file +is the shared LAMMPS library that Python loads dynamically. You can insure Python can find these files in one of two ways: -set two environment variables -run the python/install.py script :ul +set two environment variables pointing to the location in the source tree +run "make install-python" or run the python/install.py script explicitly :ul + +When calling "make install-python" LAMMPS will try to install the +python module and the shared library into the python site-packages folders; +either the system-wide ones, or the local users ones (in case of unsufficient +permissions for the global install). Python will then find the module +and shared library file automatically. If you set the paths to these files as environment variables, you only have to do it once. For the csh or tcsh shells, add something like @@ -30,42 +36,28 @@ this to your ~/.cshrc file, one line for each of the two files: setenv PYTHONPATH $\{PYTHONPATH\}:/home/sjplimp/lammps/python setenv LD_LIBRARY_PATH $\{LD_LIBRARY_PATH\}:/home/sjplimp/lammps/src :pre -If you use the python/install.py script, you need to invoke it every -time you rebuild LAMMPS (as a shared library) or make changes to the -python/lammps.py file. - -You can invoke install.py from the python directory as - -% python install.py \[libdir\] \[pydir\] :pre - -The optional libdir is where to copy the LAMMPS shared library to; the -default is /usr/local/lib. The optional pydir is where to copy the -lammps.py file to; the default is the site-packages directory of the -version of Python that is running the install script. - -Note that libdir must be a location that is in your default -LD_LIBRARY_PATH, like /usr/local/lib or /usr/lib. And pydir must be a -location that Python looks in by default for imported modules, like -its site-packages dir. If you want to copy these files to -non-standard locations, such as within your own user space, you will -need to set your PYTHONPATH and LD_LIBRARY_PATH environment variables -accordingly, as above. - -If the install.py script does not allow you to copy files into system -directories, prefix the python command with "sudo". If you do this, -make sure that the Python that root runs is the same as the Python you -run. E.g. you may need to do something like +On MacOSX you may also need to set DYLD_LIBRARY_PATH accordingly. +For Bourne/Korn shells accordingly into the corresponding files using +the "export" shell builtin. -% sudo /usr/local/bin/python install.py \[libdir\] \[pydir\] :pre +If you use "make install-python" or the python/install.py script, you need +to invoke it every time you rebuild LAMMPS (as a shared library) or +make changes to the python/lammps.py file, so that the site-packages +files are updated with the new version. -You can also invoke install.py from the make command in the src -directory as +If the default settings of "make install-python" are not what you want, +you can invoke install.py from the python directory manually as -% make install-python :pre +% python install.py -m \ -l -v \[-d \\] :pre -In this mode you cannot append optional arguments. Again, you may -need to prefix this with "sudo". In this mode you cannot control -which Python is invoked by root. +The -m flag points to the lammps.py python module file to be installed, +the -l flag points to the LAMMPS shared library file to be installed, +the -v flag points to the version.h file in the LAMMPS source and the +optional -d flag to the desired installation folder, if you don't want +the Python specific site-packages folder. If you want to copy these files to +non-standard locations, you will need to set your PYTHONPATH and +LD_LIBRARY_PATH (and DYLD_LIBRARY_PATH) environment variables +accordingly, as described above. Note that if you want Python to be able to load different versions of the LAMMPS shared library (see "this section"_Python_shlib.html), you will diff --git a/doc/src/Python_overview.txt b/doc/src/Python_overview.txt index a5d6a469ff..0195ec2b20 100644 --- a/doc/src/Python_overview.txt +++ b/doc/src/Python_overview.txt @@ -13,11 +13,11 @@ Overview of Python and LAMMPS :h3 LAMMPS can work together with Python in three ways. First, Python can wrap LAMMPS through the its "library interface"_Howto_library.html, so that a Python script can create one or more instances of LAMMPS and -launch one or more simulations. In Python lingo, this is "extending" -Python with LAMMPS. +launch one or more simulations. In Python lingo, this is called +"extending" Python with a LAMMPS module. Second, a lower-level Python interface can be used indirectly through -provided PyLammps and IPyLammps wrapper classes, written in Python. +the provided PyLammps and IPyLammps wrapper classes, written in Python. These wrappers try to simplify the usage of LAMMPS in Python by providing an object-based interface to common LAMMPS functionality. They also reduces the amount of code necessary to parameterize LAMMPS @@ -25,11 +25,12 @@ scripts through Python and make variables and computes directly accessible. Third, LAMMPS can use the Python interpreter, so that a LAMMPS -input script can invoke Python code directly, and pass information -back-and-forth between the input script and Python functions you -write. This Python code can also callback to LAMMPS to query or change -its attributes. In Python lingo, this is "embedding" Python in -LAMMPS. When used in this mode, Python can perform operations that -the simple LAMMPS input script syntax cannot. +input script or styles can invoke Python code directly, and pass +information back-and-forth between the input script and Python +functions you write. This Python code can also callback to LAMMPS +to query or change its attributes through the LAMMPS Python module +mentioned above. In Python lingo, this is "embedding" Python in +LAMMPS. When used in this mode, Python can perform script operations +that the simple LAMMPS input script syntax can not. diff --git a/python/README b/python/README index 6b13959f4d..204ca2c28d 100644 --- a/python/README +++ b/python/README @@ -9,12 +9,12 @@ doc/Section_python.html and in doc/Section_start.html#start_5. Basically you need to follow these steps in the src directory: % make g++ mode=shlib # build for whatever machine target you wish -% make install-python # may need to do this via sudo +% make install-python # install into site-packages folder You can replace the last step by a one-time setting of environment variables in your shell script. Or you can run the python/install.py script directly to give you more control over where the two relevant -files are installed. See doc/Section_python.html for details. +files are installed. See doc/Python_install.html for details. You should then be able to launch Python and instantiate an instance of LAMMPS: -- GitLab From 22be3bd37ecdd2dfe73e7768b64e518377551d9b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 22 Mar 2019 17:33:16 -0400 Subject: [PATCH 0296/1243] fix spelling error and add false positives for spellchecking --- doc/src/Python_install.txt | 2 +- doc/utils/sphinx-config/false_positives.txt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/src/Python_install.txt b/doc/src/Python_install.txt index 403cf052da..f1a280931f 100644 --- a/doc/src/Python_install.txt +++ b/doc/src/Python_install.txt @@ -25,7 +25,7 @@ run "make install-python" or run the python/install.py script explicitly :ul When calling "make install-python" LAMMPS will try to install the python module and the shared library into the python site-packages folders; -either the system-wide ones, or the local users ones (in case of unsufficient +either the system-wide ones, or the local users ones (in case of insufficient permissions for the global install). Python will then find the module and shared library file automatically. diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 5366a31d5d..2b149ac087 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -250,6 +250,7 @@ Boresch Botero Botu Bouguet +Bourne boxcolor bp bpls @@ -627,6 +628,7 @@ dVx dW dx dy +dylib dyn dyne dynes @@ -1298,6 +1300,7 @@ Kondor konglt Koning Kooser +Korn Koskinen Koster Kosztin -- GitLab From 3464464ea925918a5bf8e4fd71171c6790bcc8fe Mon Sep 17 00:00:00 2001 From: "Ryan S. Elliott" Date: Fri, 22 Mar 2019 20:20:47 -0500 Subject: [PATCH 0297/1243] Update kim example query and log files --- doc/src/kim_query.txt | 3 +-- examples/kim/in.query | 2 +- ...Aug2018.query.g++.1 => log.22Mar2019.query.g++.1} | 12 ++++++------ src/KIM/kim_query.cpp | 4 ++-- src/KIM/kim_query.h | 2 +- 5 files changed, 11 insertions(+), 12 deletions(-) rename examples/kim/{log.16Aug2018.query.g++.1 => log.22Mar2019.query.g++.1} (72%) diff --git a/doc/src/kim_query.txt b/doc/src/kim_query.txt index ffebe698be..be46783d82 100644 --- a/doc/src/kim_query.txt +++ b/doc/src/kim_query.txt @@ -18,7 +18,7 @@ web_query_flags = a series of keyword=value pairs that represent the web query; [Examples:] -kim_query latconst get_test_result test=TE_156715955670_004 model=MO_800509458712_001 & +kim_query latconst get_test_result test=TE_156715955670 model=MO_800509458712 & prop=structure-cubic-crystal-npt species=\["Al"\] keys=\["a"\] units=\["angstrom"\] :pre [Description:] @@ -43,4 +43,3 @@ See the "Build package"_Build_package.html doc page for more info. [Related commands:] "pair_style kim"_pair_kim.html, "variable"_variable.html - diff --git a/examples/kim/in.query b/examples/kim/in.query index 8538cac749..33272dc298 100644 --- a/examples/kim/in.query +++ b/examples/kim/in.query @@ -6,6 +6,6 @@ units metal info variables out log -kim_query latconst get_test_result test=TE_156715955670_004 species=["Al"] model=MO_800509458712_001 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"] +kim_query latconst get_test_result test=TE_156715955670 species=["Al"] model=MO_800509458712 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"] info variables out log lattice fcc ${latconst} diff --git a/examples/kim/log.16Aug2018.query.g++.1 b/examples/kim/log.22Mar2019.query.g++.1 similarity index 72% rename from examples/kim/log.16Aug2018.query.g++.1 rename to examples/kim/log.22Mar2019.query.g++.1 index eb83dd84b1..034bb13bba 100644 --- a/examples/kim/log.16Aug2018.query.g++.1 +++ b/examples/kim/log.22Mar2019.query.g++.1 @@ -1,4 +1,4 @@ -LAMMPS (16 Aug 2018) +LAMMPS (28 Feb 2019) # example for performing a query to the OpenKIM test database to retrieve # a parameter to be used in the input. here it requests the aluminium @@ -9,26 +9,26 @@ units metal info variables out log Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info -Printed on Mon Aug 20 18:44:24 2018 +Printed on Fri Mar 22 20:00:56 2019 Variable information: Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info -kim_query latconst get_test_result test=TE_156715955670_004 species=["Al"] model=MO_800509458712_001 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"] +kim_query latconst get_test_result test=TE_156715955670 species=["Al"] model=MO_800509458712 prop=structure-cubic-crystal-npt keys=["a"] units=["angstrom"] info variables out log Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info -Printed on Mon Aug 20 18:44:24 2018 +Printed on Fri Mar 22 20:00:57 2019 Variable information: -Variable[ 0]: latconst , style = string , def = 4.0320827961 +Variable[ 0]: latconst , style = string , def = 4.03208274841 Info-Info-Info-Info-Info-Info-Info-Info-Info-Info-Info lattice fcc ${latconst} -lattice fcc 4.0320827961 +lattice fcc 4.03208274841 Lattice spacing in x,y,z = 4.03208 4.03208 4.03208 Total wall time: 0:00:00 diff --git a/src/KIM/kim_query.cpp b/src/KIM/kim_query.cpp index 8d400ac333..2e1f752dc1 100644 --- a/src/KIM/kim_query.cpp +++ b/src/KIM/kim_query.cpp @@ -52,7 +52,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package + Designed for use with the kim-api-v2-2.0.0 (and newer) package ------------------------------------------------------------------------- */ #include @@ -114,7 +114,7 @@ void KimQuery::command(int narg, char **arg) varcmd[2] = value; input->variable->set(3,varcmd); - + delete[] varcmd; delete[] value; #else diff --git a/src/KIM/kim_query.h b/src/KIM/kim_query.h index 92972d804d..ed5a7c88f3 100644 --- a/src/KIM/kim_query.h +++ b/src/KIM/kim_query.h @@ -51,7 +51,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Designed for use with the kim-api-v2.0.0-beta.1 (and newer) package + Designed for use with the kim-api-v2-2.0.0 (and newer) package ------------------------------------------------------------------------- */ #ifdef COMMAND_CLASS -- GitLab From 414f9b25d15c583763f7cd0e7d0c3fcf02a8b80b Mon Sep 17 00:00:00 2001 From: Christoph Junghans Date: Sat, 23 Mar 2019 08:01:41 -0600 Subject: [PATCH 0298/1243] cmake: move lmpgitversion generation to build phase --- cmake/CMakeLists.txt | 38 +++++----------------- cmake/Modules/generate_lmpgitversion.cmake | 30 +++++++++++++++++ 2 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 cmake/Modules/generate_lmpgitversion.cmake diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f6f822676e..088b712856 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1331,36 +1331,14 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HE ###################################### # Generate lmpgitversion.h ###################################### -set(temp "#ifndef LMP_GIT_VERSION_H\n#define LMP_GIT_VERSION_H\n") -set(temp_git_commit "(unknown)") -set(temp_git_branch "(unknown)") -set(temp_git_describe "(unknown)") -set(temp_git_info "false") -if(GIT_FOUND AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../.git) - set(temp_git_info "true") - execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git rev-parse HEAD - OUTPUT_VARIABLE temp_git_commit - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git rev-parse --abbrev-ref HEAD - OUTPUT_VARIABLE temp_git_branch - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git describe --dirty=-modified - OUTPUT_VARIABLE temp_git_describe - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) -endif() - -set(temp "${temp}const bool LAMMPS_NS::LAMMPS::has_git_info = ${temp_git_info};\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_commit[] = \"${temp_git_commit}\";\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_branch[] = \"${temp_git_branch}\";\n") -set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_descriptor[] = \"${temp_git_describe}\";\n") -set(temp "${temp}#endif\n\n") - -message(STATUS "Generating lmpgitversion.h...") -file(WRITE "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${temp}" ) -execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h") +add_custom_target(gitversion COMMAND ${CMAKE_COMMAND} + -DCMAKE_CURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" + -DGIT_EXECUTABLE="${GIT_EXECUTABLE}" + -DGIT_FOUND="${GIT_FOUND}" + -DLAMMPS_STYLE_HEADERS_DIR="${LAMMPS_STYLE_HEADERS_DIR}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/Modules/generate_lmpgitversion.cmake) +set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${LAMMPS_STYLE_HEADERS_DIR}/gitversion.h) +list(APPEND LAMMPS_DEPS gitversion) ########################################### # Actually add executable and lib to build diff --git a/cmake/Modules/generate_lmpgitversion.cmake b/cmake/Modules/generate_lmpgitversion.cmake new file mode 100644 index 0000000000..8aead88f5f --- /dev/null +++ b/cmake/Modules/generate_lmpgitversion.cmake @@ -0,0 +1,30 @@ +set(temp "#ifndef LMP_GIT_VERSION_H\n#define LMP_GIT_VERSION_H\n") +set(temp_git_commit "(unknown)") +set(temp_git_branch "(unknown)") +set(temp_git_describe "(unknown)") +set(temp_git_info "false") +if(GIT_FOUND AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../.git) + set(temp_git_info "true") + execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git rev-parse HEAD + OUTPUT_VARIABLE temp_git_commit + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE temp_git_branch + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${GIT_EXECUTABLE} -C ${CMAKE_CURRENT_SOURCE_DIR}/../.git describe --dirty=-modified + OUTPUT_VARIABLE temp_git_describe + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +set(temp "${temp}const bool LAMMPS_NS::LAMMPS::has_git_info = ${temp_git_info};\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_commit[] = \"${temp_git_commit}\";\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_branch[] = \"${temp_git_branch}\";\n") +set(temp "${temp}const char LAMMPS_NS::LAMMPS::git_descriptor[] = \"${temp_git_describe}\";\n") +set(temp "${temp}#endif\n\n") + +message(STATUS "Generating lmpgitversion.h...") +file(WRITE "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${temp}" ) +execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h.tmp" "${LAMMPS_STYLE_HEADERS_DIR}/lmpgitversion.h") -- GitLab From 111ff4475e86419e21698fe7f950c2e589ba3ebe Mon Sep 17 00:00:00 2001 From: mkanski Date: Mon, 25 Mar 2019 14:18:55 +0100 Subject: [PATCH 0299/1243] Pointer moved to reax lists --- src/USER-REAXC/pair_reaxc.cpp | 21 +- src/USER-REAXC/reaxc_allocate.cpp | 316 +++++++++++++++--------------- src/USER-REAXC/reaxc_allocate.h | 10 +- src/USER-REAXC/reaxc_ffield.cpp | 34 ++-- src/USER-REAXC/reaxc_init_md.cpp | 11 +- src/USER-REAXC/reaxc_list.cpp | 62 +++--- src/USER-REAXC/reaxc_list.h | 4 +- src/USER-REAXC/reaxc_lookup.cpp | 84 ++++---- src/USER-REAXC/reaxc_tool_box.cpp | 18 +- src/USER-REAXC/reaxc_tool_box.h | 6 +- src/USER-REAXC/reaxc_types.h | 4 + 11 files changed, 290 insertions(+), 280 deletions(-) diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index 24612a3a40..58142b122a 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -108,6 +108,8 @@ PairReaxC::PairReaxC(LAMMPS *lmp) : Pair(lmp) system->bndry_cuts.ghost_cutoff = 0; system->my_atoms = NULL; system->pair_ptr = this; + system->error_ptr = this->lmp->error; + control->error_ptr = this->lmp->error; system->omp_active = 0; @@ -139,13 +141,13 @@ PairReaxC::~PairReaxC() if (control->tabulate ) Deallocate_Lookup_Tables( lmp, system); - if (control->hbond_cut > 0 ) Delete_List( lmp, lists+HBONDS, world); - Delete_List( lmp, lists+BONDS, world ); - Delete_List( lmp, lists+THREE_BODIES, world ); - Delete_List( lmp, lists+FAR_NBRS, world ); + if (control->hbond_cut > 0 ) Delete_List( lists+HBONDS, world); + Delete_List( lists+BONDS, world ); + Delete_List( lists+THREE_BODIES, world ); + Delete_List( lists+FAR_NBRS, world ); - DeAllocate_Workspace( lmp, control, workspace ); - DeAllocate_System( lmp, system ); + DeAllocate_Workspace( control, workspace ); + DeAllocate_System( system ); } memory->destroy( system ); @@ -437,13 +439,14 @@ void PairReaxC::setup( ) // initialize my data structures - PreAllocate_Space( lmp, system, control, workspace, world ); + PreAllocate_Space( system, control, workspace, world ); write_reax_atoms(); int num_nbrs = estimate_reax_lists(); - if(!Make_List(lmp, system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, + if(!Make_List(system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, lists+FAR_NBRS, world)) error->one(FLERR,"Pair reax/c problem in far neighbor list"); + (lists+FAR_NBRS)->error_ptr=lmp->error; write_reax_lists(); Initialize( lmp, system, control, data, workspace, &lists, out_control, @@ -466,7 +469,7 @@ void PairReaxC::setup( ) // check if I need to shrink/extend my data-structs - ReAllocate( lmp, system, control, data, workspace, &lists, mpi_data ); + ReAllocate( system, control, data, workspace, &lists, mpi_data ); } bigint local_ngroup = list->inum; diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp index 2f970399f2..8784c854b5 100644 --- a/src/USER-REAXC/reaxc_allocate.cpp +++ b/src/USER-REAXC/reaxc_allocate.cpp @@ -43,7 +43,7 @@ using namespace LAMMPS_NS; important: we cannot know the exact number of atoms that will fall into a process's box throughout the whole simulation. therefore we need to make upper bound estimates for various data structures */ -int PreAllocate_Space( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * /*control*/, +int PreAllocate_Space( reax_system *system, control_params * /*control*/, storage * workspace, MPI_Comm comm ) { int mincap = system->mincap; @@ -55,7 +55,7 @@ int PreAllocate_Space( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_para system->total_cap = MAX( (int)(system->N * safezone), mincap ); system->my_atoms = (reax_atom*) - scalloc(lmp, system->total_cap, sizeof(reax_atom), "my_atoms", comm ); + scalloc(system->error_ptr, system->total_cap, sizeof(reax_atom), "my_atoms", comm ); // Nullify some arrays only used in omp styles // Should be safe to do here since called in pair->setup(); @@ -84,45 +84,45 @@ int Allocate_System( reax_system *system, int /*local_cap*/, int total_cap, } -void DeAllocate_System( LAMMPS_NS::LAMMPS *lmp, reax_system *system ) +void DeAllocate_System( reax_system *system ) { int i, j, k; int ntypes; reax_interaction *ff_params; - // dealloocate the atom list - sfree(lmp, system->my_atoms, "system->my_atoms" ); + // deallocate the atom list + sfree(system->error_ptr, system->my_atoms, "system->my_atoms" ); // deallocate the ffield parameters storage ff_params = &(system->reax_param); ntypes = ff_params->num_atom_types; - sfree(lmp, ff_params->gp.l, "ff:globals" ); + sfree(system->error_ptr, ff_params->gp.l, "ff:globals" ); for( i = 0; i < ntypes; ++i ) { for( j = 0; j < ntypes; ++j ) { for( k = 0; k < ntypes; ++k ) { - sfree(lmp, ff_params->fbp[i][j][k], "ff:fbp[i,j,k]" ); + sfree(system->error_ptr, ff_params->fbp[i][j][k], "ff:fbp[i,j,k]" ); } - sfree(lmp, ff_params->fbp[i][j], "ff:fbp[i,j]" ); - sfree(lmp, ff_params->thbp[i][j], "ff:thbp[i,j]" ); - sfree(lmp, ff_params->hbp[i][j], "ff:hbp[i,j]" ); + sfree(system->error_ptr, ff_params->fbp[i][j], "ff:fbp[i,j]" ); + sfree(system->error_ptr, ff_params->thbp[i][j], "ff:thbp[i,j]" ); + sfree(system->error_ptr, ff_params->hbp[i][j], "ff:hbp[i,j]" ); } - sfree(lmp, ff_params->fbp[i], "ff:fbp[i]" ); - sfree(lmp, ff_params->thbp[i], "ff:thbp[i]" ); - sfree(lmp, ff_params->hbp[i], "ff:hbp[i]" ); - sfree(lmp, ff_params->tbp[i], "ff:tbp[i]" ); + sfree(system->error_ptr, ff_params->fbp[i], "ff:fbp[i]" ); + sfree(system->error_ptr, ff_params->thbp[i], "ff:thbp[i]" ); + sfree(system->error_ptr, ff_params->hbp[i], "ff:hbp[i]" ); + sfree(system->error_ptr, ff_params->tbp[i], "ff:tbp[i]" ); } - sfree(lmp, ff_params->fbp, "ff:fbp" ); - sfree(lmp, ff_params->thbp, "ff:thbp" ); - sfree(lmp, ff_params->hbp, "ff:hbp" ); - sfree(lmp, ff_params->tbp, "ff:tbp" ); - sfree(lmp, ff_params->sbp, "ff:sbp" ); + sfree(system->error_ptr, ff_params->fbp, "ff:fbp" ); + sfree(system->error_ptr, ff_params->thbp, "ff:thbp" ); + sfree(system->error_ptr, ff_params->hbp, "ff:hbp" ); + sfree(system->error_ptr, ff_params->tbp, "ff:tbp" ); + sfree(system->error_ptr, ff_params->sbp, "ff:sbp" ); } /************* workspace *************/ -void DeAllocate_Workspace( LAMMPS_NS::LAMMPS* lmp, control_params * /*control*/, storage *workspace ) +void DeAllocate_Workspace( control_params * control, storage *workspace ) { int i; @@ -133,84 +133,84 @@ void DeAllocate_Workspace( LAMMPS_NS::LAMMPS* lmp, control_params * /*control*/, /* communication storage */ for( i = 0; i < MAX_NBRS; ++i ) { - sfree(lmp, workspace->tmp_dbl[i], "tmp_dbl[i]" ); - sfree(lmp, workspace->tmp_rvec[i], "tmp_rvec[i]" ); - sfree(lmp, workspace->tmp_rvec2[i], "tmp_rvec2[i]" ); + sfree(control->error_ptr, workspace->tmp_dbl[i], "tmp_dbl[i]" ); + sfree(control->error_ptr, workspace->tmp_rvec[i], "tmp_rvec[i]" ); + sfree(control->error_ptr, workspace->tmp_rvec2[i], "tmp_rvec2[i]" ); } /* bond order storage */ - sfree(lmp, workspace->within_bond_box, "skin" ); - sfree(lmp, workspace->total_bond_order, "total_bo" ); - sfree(lmp, workspace->Deltap, "Deltap" ); - sfree(lmp, workspace->Deltap_boc, "Deltap_boc" ); - sfree(lmp, workspace->dDeltap_self, "dDeltap_self" ); - sfree(lmp, workspace->Delta, "Delta" ); - sfree(lmp, workspace->Delta_lp, "Delta_lp" ); - sfree(lmp, workspace->Delta_lp_temp, "Delta_lp_temp" ); - sfree(lmp, workspace->dDelta_lp, "dDelta_lp" ); - sfree(lmp, workspace->dDelta_lp_temp, "dDelta_lp_temp" ); - sfree(lmp, workspace->Delta_e, "Delta_e" ); - sfree(lmp, workspace->Delta_boc, "Delta_boc" ); - sfree(lmp, workspace->Delta_val, "Delta_val" ); - sfree(lmp, workspace->nlp, "nlp" ); - sfree(lmp, workspace->nlp_temp, "nlp_temp" ); - sfree(lmp, workspace->Clp, "Clp" ); - sfree(lmp, workspace->vlpex, "vlpex" ); - sfree(lmp, workspace->bond_mark, "bond_mark" ); - sfree(lmp, workspace->done_after, "done_after" ); + sfree(control->error_ptr, workspace->within_bond_box, "skin" ); + sfree(control->error_ptr, workspace->total_bond_order, "total_bo" ); + sfree(control->error_ptr, workspace->Deltap, "Deltap" ); + sfree(control->error_ptr, workspace->Deltap_boc, "Deltap_boc" ); + sfree(control->error_ptr, workspace->dDeltap_self, "dDeltap_self" ); + sfree(control->error_ptr, workspace->Delta, "Delta" ); + sfree(control->error_ptr, workspace->Delta_lp, "Delta_lp" ); + sfree(control->error_ptr, workspace->Delta_lp_temp, "Delta_lp_temp" ); + sfree(control->error_ptr, workspace->dDelta_lp, "dDelta_lp" ); + sfree(control->error_ptr, workspace->dDelta_lp_temp, "dDelta_lp_temp" ); + sfree(control->error_ptr, workspace->Delta_e, "Delta_e" ); + sfree(control->error_ptr, workspace->Delta_boc, "Delta_boc" ); + sfree(control->error_ptr, workspace->Delta_val, "Delta_val" ); + sfree(control->error_ptr, workspace->nlp, "nlp" ); + sfree(control->error_ptr, workspace->nlp_temp, "nlp_temp" ); + sfree(control->error_ptr, workspace->Clp, "Clp" ); + sfree(control->error_ptr, workspace->vlpex, "vlpex" ); + sfree(control->error_ptr, workspace->bond_mark, "bond_mark" ); + sfree(control->error_ptr, workspace->done_after, "done_after" ); /* QEq storage */ - sfree(lmp, workspace->Hdia_inv, "Hdia_inv" ); - sfree(lmp, workspace->b_s, "b_s" ); - sfree(lmp, workspace->b_t, "b_t" ); - sfree(lmp, workspace->b_prc, "b_prc" ); - sfree(lmp, workspace->b_prm, "b_prm" ); - sfree(lmp, workspace->s, "s" ); - sfree(lmp, workspace->t, "t" ); - sfree(lmp, workspace->droptol, "droptol" ); - sfree(lmp, workspace->b, "b" ); - sfree(lmp, workspace->x, "x" ); + sfree(control->error_ptr, workspace->Hdia_inv, "Hdia_inv" ); + sfree(control->error_ptr, workspace->b_s, "b_s" ); + sfree(control->error_ptr, workspace->b_t, "b_t" ); + sfree(control->error_ptr, workspace->b_prc, "b_prc" ); + sfree(control->error_ptr, workspace->b_prm, "b_prm" ); + sfree(control->error_ptr, workspace->s, "s" ); + sfree(control->error_ptr, workspace->t, "t" ); + sfree(control->error_ptr, workspace->droptol, "droptol" ); + sfree(control->error_ptr, workspace->b, "b" ); + sfree(control->error_ptr, workspace->x, "x" ); /* GMRES storage */ for( i = 0; i < RESTART+1; ++i ) { - sfree(lmp, workspace->h[i], "h[i]" ); - sfree(lmp, workspace->v[i], "v[i]" ); + sfree(control->error_ptr, workspace->h[i], "h[i]" ); + sfree(control->error_ptr, workspace->v[i], "v[i]" ); } - sfree(lmp, workspace->h, "h" ); - sfree(lmp, workspace->v, "v" ); - sfree(lmp, workspace->y, "y" ); - sfree(lmp, workspace->z, "z" ); - sfree(lmp, workspace->g, "g" ); - sfree(lmp, workspace->hs, "hs" ); - sfree(lmp, workspace->hc, "hc" ); + sfree(control->error_ptr, workspace->h, "h" ); + sfree(control->error_ptr, workspace->v, "v" ); + sfree(control->error_ptr, workspace->y, "y" ); + sfree(control->error_ptr, workspace->z, "z" ); + sfree(control->error_ptr, workspace->g, "g" ); + sfree(control->error_ptr, workspace->hs, "hs" ); + sfree(control->error_ptr, workspace->hc, "hc" ); /* CG storage */ - sfree(lmp, workspace->r, "r" ); - sfree(lmp, workspace->d, "d" ); - sfree(lmp, workspace->q, "q" ); - sfree(lmp, workspace->p, "p" ); - sfree(lmp, workspace->r2, "r2" ); - sfree(lmp, workspace->d2, "d2" ); - sfree(lmp, workspace->q2, "q2" ); - sfree(lmp, workspace->p2, "p2" ); + sfree(control->error_ptr, workspace->r, "r" ); + sfree(control->error_ptr, workspace->d, "d" ); + sfree(control->error_ptr, workspace->q, "q" ); + sfree(control->error_ptr, workspace->p, "p" ); + sfree(control->error_ptr, workspace->r2, "r2" ); + sfree(control->error_ptr, workspace->d2, "d2" ); + sfree(control->error_ptr, workspace->q2, "q2" ); + sfree(control->error_ptr, workspace->p2, "p2" ); /* integrator storage */ - sfree(lmp, workspace->v_const, "v_const" ); + sfree(control->error_ptr, workspace->v_const, "v_const" ); /* force related storage */ - sfree(lmp, workspace->f, "f" ); - sfree(lmp, workspace->CdDelta, "CdDelta" ); + sfree(control->error_ptr, workspace->f, "f" ); + sfree(control->error_ptr, workspace->CdDelta, "CdDelta" ); /* reductions */ #ifdef LMP_USER_OMP - if (workspace->CdDeltaReduction) sfree(lmp, workspace->CdDeltaReduction, "cddelta_reduce" ); - if (workspace->forceReduction) sfree(lmp, workspace->forceReduction, "f_reduce" ); - if (workspace->valence_angle_atom_myoffset) sfree(lmp, workspace->valence_angle_atom_myoffset, "valence_angle_atom_myoffset"); - if (workspace->my_ext_pressReduction) sfree(lmp, workspace->my_ext_pressReduction, "ext_press_reduce"); + if (workspace->CdDeltaReduction) sfree(control->error_ptr, workspace->CdDeltaReduction, "cddelta_reduce" ); + if (workspace->forceReduction) sfree(control->error_ptr, workspace->forceReduction, "f_reduce" ); + if (workspace->valence_angle_atom_myoffset) sfree(control->error_ptr, workspace->valence_angle_atom_myoffset, "valence_angle_atom_myoffset"); + if (workspace->my_ext_pressReduction) sfree(control->error_ptr, workspace->my_ext_pressReduction, "ext_press_reduce"); #endif } -int Allocate_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system * /*system*/, control_params * control, +int Allocate_Workspace( reax_system * /*system*/, control_params * control, storage *workspace, int local_cap, int total_cap, MPI_Comm comm, char * /*msg*/ ) { @@ -224,94 +224,94 @@ int Allocate_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system * /*system*/, contro /* communication storage */ for( i = 0; i < MAX_NBRS; ++i ) { workspace->tmp_dbl[i] = (double*) - scalloc(lmp, total_cap, sizeof(double), "tmp_dbl", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "tmp_dbl", comm ); workspace->tmp_rvec[i] = (rvec*) - scalloc(lmp, total_cap, sizeof(rvec), "tmp_rvec", comm ); + scalloc(control->error_ptr, total_cap, sizeof(rvec), "tmp_rvec", comm ); workspace->tmp_rvec2[i] = (rvec2*) - scalloc(lmp, total_cap, sizeof(rvec2), "tmp_rvec2", comm ); + scalloc(control->error_ptr, total_cap, sizeof(rvec2), "tmp_rvec2", comm ); } /* bond order related storage */ workspace->within_bond_box = (int*) - scalloc(lmp, total_cap, sizeof(int), "skin", comm ); - workspace->total_bond_order = (double*) smalloc(lmp, total_real, "total_bo", comm ); - workspace->Deltap = (double*) smalloc(lmp, total_real, "Deltap", comm ); - workspace->Deltap_boc = (double*) smalloc(lmp, total_real, "Deltap_boc", comm ); - workspace->dDeltap_self = (rvec*) smalloc(lmp, total_rvec, "dDeltap_self", comm ); - workspace->Delta = (double*) smalloc(lmp, total_real, "Delta", comm ); - workspace->Delta_lp = (double*) smalloc(lmp, total_real, "Delta_lp", comm ); + scalloc(control->error_ptr, total_cap, sizeof(int), "skin", comm ); + workspace->total_bond_order = (double*) smalloc(control->error_ptr, total_real, "total_bo", comm ); + workspace->Deltap = (double*) smalloc(control->error_ptr, total_real, "Deltap", comm ); + workspace->Deltap_boc = (double*) smalloc(control->error_ptr, total_real, "Deltap_boc", comm ); + workspace->dDeltap_self = (rvec*) smalloc(control->error_ptr, total_rvec, "dDeltap_self", comm ); + workspace->Delta = (double*) smalloc(control->error_ptr, total_real, "Delta", comm ); + workspace->Delta_lp = (double*) smalloc(control->error_ptr, total_real, "Delta_lp", comm ); workspace->Delta_lp_temp = (double*) - smalloc(lmp, total_real, "Delta_lp_temp", comm ); - workspace->dDelta_lp = (double*) smalloc(lmp, total_real, "dDelta_lp", comm ); + smalloc(control->error_ptr, total_real, "Delta_lp_temp", comm ); + workspace->dDelta_lp = (double*) smalloc(control->error_ptr, total_real, "dDelta_lp", comm ); workspace->dDelta_lp_temp = (double*) - smalloc(lmp, total_real, "dDelta_lp_temp", comm ); - workspace->Delta_e = (double*) smalloc(lmp, total_real, "Delta_e", comm ); - workspace->Delta_boc = (double*) smalloc(lmp, total_real, "Delta_boc", comm ); - workspace->Delta_val = (double*) smalloc(lmp, total_real, "Delta_val", comm ); - workspace->nlp = (double*) smalloc(lmp, total_real, "nlp", comm ); - workspace->nlp_temp = (double*) smalloc(lmp, total_real, "nlp_temp", comm ); - workspace->Clp = (double*) smalloc(lmp, total_real, "Clp", comm ); - workspace->vlpex = (double*) smalloc(lmp, total_real, "vlpex", comm ); + smalloc(control->error_ptr, total_real, "dDelta_lp_temp", comm ); + workspace->Delta_e = (double*) smalloc(control->error_ptr, total_real, "Delta_e", comm ); + workspace->Delta_boc = (double*) smalloc(control->error_ptr, total_real, "Delta_boc", comm ); + workspace->Delta_val = (double*) smalloc(control->error_ptr, total_real, "Delta_val", comm ); + workspace->nlp = (double*) smalloc(control->error_ptr, total_real, "nlp", comm ); + workspace->nlp_temp = (double*) smalloc(control->error_ptr, total_real, "nlp_temp", comm ); + workspace->Clp = (double*) smalloc(control->error_ptr, total_real, "Clp", comm ); + workspace->vlpex = (double*) smalloc(control->error_ptr, total_real, "vlpex", comm ); workspace->bond_mark = (int*) - scalloc(lmp, total_cap, sizeof(int), "bond_mark", comm ); + scalloc(control->error_ptr, total_cap, sizeof(int), "bond_mark", comm ); workspace->done_after = (int*) - scalloc(lmp, total_cap, sizeof(int), "done_after", comm ); + scalloc(control->error_ptr, total_cap, sizeof(int), "done_after", comm ); /* QEq storage */ workspace->Hdia_inv = (double*) - scalloc(lmp, total_cap, sizeof(double), "Hdia_inv", comm ); - workspace->b_s = (double*) scalloc(lmp, total_cap, sizeof(double), "b_s", comm ); - workspace->b_t = (double*) scalloc(lmp, total_cap, sizeof(double), "b_t", comm ); - workspace->b_prc = (double*) scalloc(lmp, total_cap, sizeof(double), "b_prc", comm ); - workspace->b_prm = (double*) scalloc(lmp, total_cap, sizeof(double), "b_prm", comm ); - workspace->s = (double*) scalloc(lmp, total_cap, sizeof(double), "s", comm ); - workspace->t = (double*) scalloc(lmp, total_cap, sizeof(double), "t", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "Hdia_inv", comm ); + workspace->b_s = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_s", comm ); + workspace->b_t = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_t", comm ); + workspace->b_prc = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_prc", comm ); + workspace->b_prm = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_prm", comm ); + workspace->s = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "s", comm ); + workspace->t = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "t", comm ); workspace->droptol = (double*) - scalloc(lmp, total_cap, sizeof(double), "droptol", comm ); - workspace->b = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "b", comm ); - workspace->x = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "x", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "droptol", comm ); + workspace->b = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "b", comm ); + workspace->x = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "x", comm ); /* GMRES storage */ - workspace->y = (double*) scalloc(lmp, RESTART+1, sizeof(double), "y", comm ); - workspace->z = (double*) scalloc(lmp, RESTART+1, sizeof(double), "z", comm ); - workspace->g = (double*) scalloc(lmp, RESTART+1, sizeof(double), "g", comm ); - workspace->h = (double**) scalloc(lmp, RESTART+1, sizeof(double*), "h", comm ); - workspace->hs = (double*) scalloc(lmp, RESTART+1, sizeof(double), "hs", comm ); - workspace->hc = (double*) scalloc(lmp, RESTART+1, sizeof(double), "hc", comm ); - workspace->v = (double**) scalloc(lmp, RESTART+1, sizeof(double*), "v", comm ); + workspace->y = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "y", comm ); + workspace->z = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "z", comm ); + workspace->g = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "g", comm ); + workspace->h = (double**) scalloc(control->error_ptr, RESTART+1, sizeof(double*), "h", comm ); + workspace->hs = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "hs", comm ); + workspace->hc = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "hc", comm ); + workspace->v = (double**) scalloc(control->error_ptr, RESTART+1, sizeof(double*), "v", comm ); for( i = 0; i < RESTART+1; ++i ) { - workspace->h[i] = (double*) scalloc(lmp, RESTART+1, sizeof(double), "h[i]", comm ); - workspace->v[i] = (double*) scalloc(lmp, total_cap, sizeof(double), "v[i]", comm ); + workspace->h[i] = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "h[i]", comm ); + workspace->v[i] = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "v[i]", comm ); } /* CG storage */ - workspace->r = (double*) scalloc(lmp, total_cap, sizeof(double), "r", comm ); - workspace->d = (double*) scalloc(lmp, total_cap, sizeof(double), "d", comm ); - workspace->q = (double*) scalloc(lmp, total_cap, sizeof(double), "q", comm ); - workspace->p = (double*) scalloc(lmp, total_cap, sizeof(double), "p", comm ); - workspace->r2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "r2", comm ); - workspace->d2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "d2", comm ); - workspace->q2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "q2", comm ); - workspace->p2 = (rvec2*) scalloc(lmp, total_cap, sizeof(rvec2), "p2", comm ); + workspace->r = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "r", comm ); + workspace->d = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "d", comm ); + workspace->q = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "q", comm ); + workspace->p = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "p", comm ); + workspace->r2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "r2", comm ); + workspace->d2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "d2", comm ); + workspace->q2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "q2", comm ); + workspace->p2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "p2", comm ); /* integrator storage */ - workspace->v_const = (rvec*) smalloc(lmp, local_rvec, "v_const", comm ); + workspace->v_const = (rvec*) smalloc(control->error_ptr, local_rvec, "v_const", comm ); /* force related storage */ - workspace->f = (rvec*) scalloc(lmp, total_cap, sizeof(rvec), "f", comm ); + workspace->f = (rvec*) scalloc(control->error_ptr, total_cap, sizeof(rvec), "f", comm ); workspace->CdDelta = (double*) - scalloc(lmp, total_cap, sizeof(double), "CdDelta", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "CdDelta", comm ); // storage for reductions with multiple threads #ifdef LMP_USER_OMP - workspace->CdDeltaReduction = (double *) scalloc(lmp, sizeof(double), total_cap*control->nthreads, + workspace->CdDeltaReduction = (double *) scalloc(control->error_ptr, sizeof(double), total_cap*control->nthreads, "cddelta_reduce", comm); - workspace->forceReduction = (rvec *) scalloc(lmp, sizeof(rvec), total_cap*control->nthreads, + workspace->forceReduction = (rvec *) scalloc(control->error_ptr, sizeof(rvec), total_cap*control->nthreads, "forceReduction", comm); - workspace->valence_angle_atom_myoffset = (int *) scalloc(lmp, sizeof(int), total_cap, "valence_angle_atom_myoffset", comm); + workspace->valence_angle_atom_myoffset = (int *) scalloc(control->error_ptr, sizeof(int), total_cap, "valence_angle_atom_myoffset", comm); workspace->my_ext_pressReduction = (rvec *) calloc(sizeof(rvec), control->nthreads); #else LMP_UNUSED_PARAM(control); @@ -321,17 +321,17 @@ int Allocate_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system * /*system*/, contro } -static void Reallocate_Neighbor_List( LAMMPS* lmp, reax_list *far_nbrs, int n, +static void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, int num_intrs, MPI_Comm comm ) { - Delete_List( lmp, far_nbrs, comm ); - if(!Make_List( lmp, n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs, comm )){ - lmp->error->one(FLERR,"Problem in initializing far neighbors list"); + Delete_List( far_nbrs, comm ); + if(!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs, comm )){ + far_nbrs->error_ptr->one(FLERR,"Problem in initializing far neighbors list"); } } -static int Reallocate_HBonds_List( LAMMPS *lmp, reax_system *system, reax_list *hbonds, +static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, MPI_Comm comm ) { int i, total_hbonds; @@ -346,16 +346,16 @@ static int Reallocate_HBonds_List( LAMMPS *lmp, reax_system *system, reax_list * } total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS )); - Delete_List( lmp, hbonds, comm ); - if (!Make_List( lmp, system->Hcap, total_hbonds, TYP_HBOND, hbonds, comm )) { - lmp->error->one(FLERR, "Not enough space for hydrogen bonds list"); + Delete_List( hbonds, comm ); + if (!Make_List( system->Hcap, total_hbonds, TYP_HBOND, hbonds, comm )) { + hbonds->error_ptr->one(FLERR, "Not enough space for hydrogen bonds list"); } return total_hbonds; } -static int Reallocate_Bonds_List( LAMMPS *lmp, reax_system *system, reax_list *bonds, +static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, int *total_bonds, int *est_3body, MPI_Comm comm ) { @@ -375,12 +375,12 @@ static int Reallocate_Bonds_List( LAMMPS *lmp, reax_system *system, reax_list *b #ifdef LMP_USER_OMP if (system->omp_active) for (i = 0; i < bonds->num_intrs; ++i) - sfree(lmp, bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction"); + sfree(system->error_ptr, bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction"); #endif - Delete_List( lmp, bonds, comm ); - if(!Make_List(lmp, system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) { - lmp->error->one(FLERR, "Not enough space for bonds list"); + Delete_List( bonds, comm ); + if(!Make_List(system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) { + bonds->error_ptr->one(FLERR, "Not enough space for bonds list"); } #ifdef LMP_USER_OMP @@ -393,14 +393,14 @@ static int Reallocate_Bonds_List( LAMMPS *lmp, reax_system *system, reax_list *b if (system->omp_active) for (i = 0; i < bonds->num_intrs; ++i) bonds->select.bond_list[i].bo_data.CdboReduction = - (double*) smalloc(lmp, sizeof(double)*nthreads, "CdboReduction", comm); + (double*) smalloc(system->error_ptr, sizeof(double)*nthreads, "CdboReduction", comm); #endif return SUCCESS; } -void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, +void ReAllocate( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, mpi_datatypes *mpi_data ) { @@ -436,17 +436,17 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, if (ret != SUCCESS) { char errmsg[128]; snprintf(errmsg, 128, "Not enough space for atom_list: total_cap=%d", system->total_cap); - lmp->error->one(FLERR, errmsg); + system->error_ptr->one(FLERR, errmsg); } /* workspace */ - DeAllocate_Workspace( lmp, control, workspace ); - ret = Allocate_Workspace( lmp, system, control, workspace, system->local_cap, + DeAllocate_Workspace( control, workspace ); + ret = Allocate_Workspace( system, control, workspace, system->local_cap, system->total_cap, comm, msg ); if (ret != SUCCESS) { char errmsg[128]; snprintf(errmsg, 128, "Not enough space for workspace: local_cap=%d total_cap=%d", system->local_cap, system->total_cap); - lmp->error->one(FLERR, errmsg); + system->error_ptr->one(FLERR, errmsg); } } @@ -460,13 +460,13 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, if (realloc->num_far > far_nbrs->num_intrs) { char errmsg[128]; snprintf(errmsg, 128, "step%d-ran out of space on far_nbrs: top=%d, max=%d", data->step, realloc->num_far, far_nbrs->num_intrs); - lmp->error->one(FLERR, errmsg); + system->error_ptr->one(FLERR, errmsg); } newsize = static_cast (MAX( realloc->num_far*safezone, mincap*MIN_NBRS )); - Reallocate_Neighbor_List( lmp, far_nbrs, system->total_cap, newsize, comm ); + Reallocate_Neighbor_List( far_nbrs, system->total_cap, newsize, comm ); realloc->num_far = 0; } } @@ -481,7 +481,7 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, } if (Hflag || realloc->hbonds) { - ret = Reallocate_HBonds_List( lmp, system, (*lists)+HBONDS, comm ); + ret = Reallocate_HBonds_List( system, (*lists)+HBONDS, comm ); realloc->hbonds = 0; } } @@ -489,7 +489,7 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, /* bonds list */ num_bonds = est_3body = -1; if (Nflag || realloc->bonds) { - Reallocate_Bonds_List( lmp, system, (*lists)+BONDS, &num_bonds, + Reallocate_Bonds_List( system, (*lists)+BONDS, &num_bonds, &est_3body, comm ); realloc->bonds = 0; realloc->num_3body = MAX( realloc->num_3body, est_3body ) * 2; @@ -497,16 +497,16 @@ void ReAllocate( LAMMPS *lmp, reax_system *system, control_params *control, /* 3-body list */ if (realloc->num_3body > 0) { - Delete_List( lmp, (*lists)+THREE_BODIES, comm ); + Delete_List( (*lists)+THREE_BODIES, comm ); if (num_bonds == -1) num_bonds = ((*lists)+BONDS)->num_intrs; realloc->num_3body = (int)(MAX(realloc->num_3body*safezone, MIN_3BODIES)); - if( !Make_List( lmp, num_bonds, realloc->num_3body, TYP_THREE_BODY, + if( !Make_List( num_bonds, realloc->num_3body, TYP_THREE_BODY, (*lists)+THREE_BODIES, comm ) ) { - lmp->error->one(FLERR, "Problem in initializing angles list"); + system->error_ptr->one(FLERR, "Problem in initializing angles list"); } realloc->num_3body = -1; } diff --git a/src/USER-REAXC/reaxc_allocate.h b/src/USER-REAXC/reaxc_allocate.h index 9f009b0916..f813204006 100644 --- a/src/USER-REAXC/reaxc_allocate.h +++ b/src/USER-REAXC/reaxc_allocate.h @@ -33,15 +33,15 @@ #include "error.h" using namespace LAMMPS_NS; -int PreAllocate_Space( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, storage*, MPI_Comm ); +int PreAllocate_Space( reax_system*, control_params*, storage*, MPI_Comm ); int Allocate_System( reax_system*, int, int, char* ); -void DeAllocate_System( LAMMPS_NS::LAMMPS*, reax_system* ); +void DeAllocate_System( reax_system* ); -int Allocate_Workspace( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, storage*, +int Allocate_Workspace( reax_system*, control_params*, storage*, int, int, MPI_Comm, char* ); -void DeAllocate_Workspace( LAMMPS_NS::LAMMPS*, control_params*, storage* ); +void DeAllocate_Workspace( control_params*, storage* ); -void ReAllocate( LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, +void ReAllocate( reax_system*, control_params*, simulation_data*, storage*, reax_list**, mpi_datatypes* ); #endif diff --git a/src/USER-REAXC/reaxc_ffield.cpp b/src/USER-REAXC/reaxc_ffield.cpp index 6096e3e614..8316c188b3 100644 --- a/src/USER-REAXC/reaxc_ffield.cpp +++ b/src/USER-REAXC/reaxc_ffield.cpp @@ -99,54 +99,54 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Allocating structures in reax_interaction */ reax->sbp = (single_body_parameters*) - scalloc(lmp, reax->num_atom_types, sizeof(single_body_parameters), "sbp", + scalloc(lmp->error, reax->num_atom_types, sizeof(single_body_parameters), "sbp", comm ); reax->tbp = (two_body_parameters**) - scalloc(lmp, reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); reax->thbp= (three_body_header***) - scalloc(lmp, reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); reax->hbp = (hbond_parameters***) - scalloc(lmp, reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); reax->fbp = (four_body_header****) - scalloc(lmp, reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); tor_flag = (char****) - scalloc(lmp, reax->num_atom_types, sizeof(char***), "tor_flag", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(char***), "tor_flag", comm ); for( i = 0; i < reax->num_atom_types; i++ ) { reax->tbp[i] = (two_body_parameters*) - scalloc(lmp, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", + scalloc(lmp->error, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", comm ); reax->thbp[i]= (three_body_header**) - scalloc(lmp, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", + scalloc(lmp->error, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", comm ); reax->hbp[i] = (hbond_parameters**) - scalloc(lmp, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", + scalloc(lmp->error, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", comm ); reax->fbp[i] = (four_body_header***) - scalloc(lmp, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", + scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", comm ); tor_flag[i] = (char***) - scalloc(lmp, reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); for( j = 0; j < reax->num_atom_types; j++ ) { reax->thbp[i][j]= (three_body_header*) - scalloc(lmp, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", + scalloc(lmp->error, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", comm ); reax->hbp[i][j] = (hbond_parameters*) - scalloc(lmp, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", + scalloc(lmp->error, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", comm ); reax->fbp[i][j] = (four_body_header**) - scalloc(lmp, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", + scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", comm ); tor_flag[i][j] = (char**) - scalloc(lmp, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); + scalloc(lmp->error, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); for (k=0; k < reax->num_atom_types; k++) { reax->fbp[i][j][k] = (four_body_header*) - scalloc(lmp, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", + scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", comm ); tor_flag[i][j][k] = (char*) - scalloc(lmp, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", + scalloc(lmp->error, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", comm ); } } diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index 6ee68d6c46..8c60db0846 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -127,7 +127,7 @@ int Init_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params { int ret; - ret = Allocate_Workspace( lmp, system, control, workspace, + ret = Allocate_Workspace( system, control, workspace, system->local_cap, system->total_cap, comm, msg ); if (ret != SUCCESS) return ret; @@ -181,10 +181,11 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, } total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS )); - if( !Make_List( lmp, system->Hcap, total_hbonds, TYP_HBOND, + if( !Make_List( system->Hcap, total_hbonds, TYP_HBOND, *lists+HBONDS, comm ) ) { lmp->error->one(FLERR, "Not enough space for hbonds list."); } + (*lists+HBONDS)->error_ptr = system->error_ptr; } total_bonds = 0; @@ -194,17 +195,19 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, } bond_cap = (int)(MAX( total_bonds*safezone, mincap*MIN_BONDS )); - if( !Make_List( lmp, system->total_cap, bond_cap, TYP_BOND, + if( !Make_List( system->total_cap, bond_cap, TYP_BOND, *lists+BONDS, comm ) ) { lmp->error->one(FLERR, "Not enough space for bonds list."); } + (*lists+BONDS)->error_ptr = system->error_ptr; /* 3bodies list */ cap_3body = (int)(MAX( num_3body*safezone, MIN_3BODIES )); - if( !Make_List( lmp, bond_cap, cap_3body, TYP_THREE_BODY, + if( !Make_List( bond_cap, cap_3body, TYP_THREE_BODY, *lists+THREE_BODIES, comm ) ){ lmp->error->one(FLERR,"Problem in initializing angles list."); } + (*lists+THREE_BODIES)->error_ptr = system->error_ptr; free( hb_top ); free( bond_top ); diff --git a/src/USER-REAXC/reaxc_list.cpp b/src/USER-REAXC/reaxc_list.cpp index 5d4ab2f3c8..f103e520e8 100644 --- a/src/USER-REAXC/reaxc_list.cpp +++ b/src/USER-REAXC/reaxc_list.cpp @@ -29,118 +29,118 @@ #include "reaxc_tool_box.h" /************* allocate list space ******************/ -int Make_List( LAMMPS_NS::LAMMPS *lmp, int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) +int Make_List( int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) { l->allocated = 1; l->n = n; l->num_intrs = num_intrs; - if (l->index) sfree(lmp, l->index, "list:index"); - if (l->end_index) sfree(lmp, l->end_index, "list:end_index"); - l->index = (int*) smalloc(lmp, n * sizeof(int), "list:index", comm ); - l->end_index = (int*) smalloc(lmp, n * sizeof(int), "list:end_index", comm ); + if (l->index) sfree(l->error_ptr, l->index, "list:index"); + if (l->end_index) sfree(l->error_ptr, l->end_index, "list:end_index"); + l->index = (int*) smalloc(l->error_ptr, n * sizeof(int), "list:index", comm ); + l->end_index = (int*) smalloc(l->error_ptr, n * sizeof(int), "list:end_index", comm ); l->type = type; switch(l->type) { case TYP_VOID: - if (l->select.v) sfree(lmp, l->select.v, "list:v"); - l->select.v = (void*) smalloc(lmp, l->num_intrs * sizeof(void*), "list:v", comm); + if (l->select.v) sfree(l->error_ptr, l->select.v, "list:v"); + l->select.v = (void*) smalloc(l->error_ptr, l->num_intrs * sizeof(void*), "list:v", comm); break; case TYP_THREE_BODY: - if (l->select.three_body_list) sfree(lmp, l->select.three_body_list,"list:three_bodies"); + if (l->select.three_body_list) sfree(l->error_ptr, l->select.three_body_list,"list:three_bodies"); l->select.three_body_list = (three_body_interaction_data*) - smalloc(lmp, l->num_intrs * sizeof(three_body_interaction_data), + smalloc(l->error_ptr, l->num_intrs * sizeof(three_body_interaction_data), "list:three_bodies", comm ); break; case TYP_BOND: - if (l->select.bond_list) sfree(lmp, l->select.bond_list,"list:bonds"); + if (l->select.bond_list) sfree(l->error_ptr, l->select.bond_list,"list:bonds"); l->select.bond_list = (bond_data*) - smalloc(lmp, l->num_intrs * sizeof(bond_data), "list:bonds", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(bond_data), "list:bonds", comm ); break; case TYP_DBO: - if (l->select.dbo_list) sfree(lmp, l->select.dbo_list,"list:dbonds"); + if (l->select.dbo_list) sfree(l->error_ptr, l->select.dbo_list,"list:dbonds"); l->select.dbo_list = (dbond_data*) - smalloc(lmp, l->num_intrs * sizeof(dbond_data), "list:dbonds", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(dbond_data), "list:dbonds", comm ); break; case TYP_DDELTA: - if (l->select.dDelta_list) sfree(lmp, l->select.dDelta_list,"list:dDeltas"); + if (l->select.dDelta_list) sfree(l->error_ptr, l->select.dDelta_list,"list:dDeltas"); l->select.dDelta_list = (dDelta_data*) - smalloc(lmp, l->num_intrs * sizeof(dDelta_data), "list:dDeltas", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(dDelta_data), "list:dDeltas", comm ); break; case TYP_FAR_NEIGHBOR: - if (l->select.far_nbr_list) sfree(lmp, l->select.far_nbr_list,"list:far_nbrs"); + if (l->select.far_nbr_list) sfree(l->error_ptr, l->select.far_nbr_list,"list:far_nbrs"); l->select.far_nbr_list = (far_neighbor_data*) - smalloc(lmp, l->num_intrs * sizeof(far_neighbor_data), "list:far_nbrs", comm); + smalloc(l->error_ptr, l->num_intrs * sizeof(far_neighbor_data), "list:far_nbrs", comm); break; case TYP_HBOND: - if (l->select.hbond_list) sfree(lmp, l->select.hbond_list,"list:hbonds"); + if (l->select.hbond_list) sfree(l->error_ptr, l->select.hbond_list,"list:hbonds"); l->select.hbond_list = (hbond_data*) - smalloc(lmp, l->num_intrs * sizeof(hbond_data), "list:hbonds", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(hbond_data), "list:hbonds", comm ); break; default: char errmsg[128]; snprintf(errmsg, 128, "No %d list type defined", l->type); - lmp->error->all(FLERR,errmsg); + l->error_ptr->all(FLERR,errmsg); } return SUCCESS; } -void Delete_List( LAMMPS_NS::LAMMPS *lmp, reax_list *l, MPI_Comm comm ) +void Delete_List( reax_list *l, MPI_Comm comm ) { if (l->allocated == 0) return; l->allocated = 0; - sfree(lmp, l->index, "list:index" ); - sfree(lmp, l->end_index, "list:end_index" ); + sfree(l->error_ptr, l->index, "list:index" ); + sfree(l->error_ptr, l->end_index, "list:end_index" ); l->index = NULL; l->end_index = NULL; switch(l->type) { case TYP_VOID: - sfree(lmp, l->select.v, "list:v" ); + sfree(l->error_ptr, l->select.v, "list:v" ); l->select.v = NULL; break; case TYP_HBOND: - sfree(lmp, l->select.hbond_list, "list:hbonds" ); + sfree(l->error_ptr, l->select.hbond_list, "list:hbonds" ); l->select.hbond_list = NULL; break; case TYP_FAR_NEIGHBOR: - sfree(lmp, l->select.far_nbr_list, "list:far_nbrs" ); + sfree(l->error_ptr, l->select.far_nbr_list, "list:far_nbrs" ); l->select.far_nbr_list = NULL; break; case TYP_BOND: - sfree(lmp, l->select.bond_list, "list:bonds" ); + sfree(l->error_ptr, l->select.bond_list, "list:bonds" ); l->select.bond_list = NULL; break; case TYP_DBO: - sfree(lmp, l->select.dbo_list, "list:dbos" ); + sfree(l->error_ptr, l->select.dbo_list, "list:dbos" ); l->select.dbo_list = NULL; break; case TYP_DDELTA: - sfree(lmp, l->select.dDelta_list, "list:dDeltas" ); + sfree(l->error_ptr, l->select.dDelta_list, "list:dDeltas" ); l->select.dDelta_list = NULL; break; case TYP_THREE_BODY: - sfree(lmp, l->select.three_body_list, "list:three_bodies" ); + sfree(l->error_ptr, l->select.three_body_list, "list:three_bodies" ); l->select.three_body_list = NULL; break; default: char errmsg[128]; snprintf(errmsg, 128, "No %d list type defined", l->type); - lmp->error->all(FLERR,errmsg); + l->error_ptr->all(FLERR,errmsg); } } diff --git a/src/USER-REAXC/reaxc_list.h b/src/USER-REAXC/reaxc_list.h index 1df2338b0f..ab7fbce19c 100644 --- a/src/USER-REAXC/reaxc_list.h +++ b/src/USER-REAXC/reaxc_list.h @@ -29,8 +29,8 @@ #include "reaxc_types.h" -int Make_List( LAMMPS_NS::LAMMPS*, int, int, int, reax_list*, MPI_Comm ); -void Delete_List( LAMMPS_NS::LAMMPS*, reax_list*, MPI_Comm ); +int Make_List( int, int, int, reax_list*, MPI_Comm ); +void Delete_List( reax_list*, MPI_Comm ); inline int Num_Entries(int,reax_list*); inline int Start_Index( int, reax_list* ); diff --git a/src/USER-REAXC/reaxc_lookup.cpp b/src/USER-REAXC/reaxc_lookup.cpp index 41ad5e99d4..c16ca9af52 100644 --- a/src/USER-REAXC/reaxc_lookup.cpp +++ b/src/USER-REAXC/reaxc_lookup.cpp @@ -58,11 +58,11 @@ void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + b = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + c = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + d = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + v = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); /* build the linear system */ a[0] = a[1] = a[n-1] = 0; @@ -92,11 +92,11 @@ void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double coef[i-1].a = f[i]; } - sfree(lmp, a, "cubic_spline:a" ); - sfree(lmp, b, "cubic_spline:b" ); - sfree(lmp, c, "cubic_spline:c" ); - sfree(lmp, d, "cubic_spline:d" ); - sfree(lmp, v, "cubic_spline:v" ); + sfree(lmp->error, a, "cubic_spline:a" ); + sfree(lmp->error, b, "cubic_spline:b" ); + sfree(lmp->error, c, "cubic_spline:c" ); + sfree(lmp->error, d, "cubic_spline:d" ); + sfree(lmp->error, v, "cubic_spline:v" ); } @@ -109,11 +109,11 @@ void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const doubl double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc(lmp, n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + b = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + c = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + d = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + v = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); /* build the linear system */ a[0] = 0; @@ -142,11 +142,11 @@ void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const doubl coef[i-1].a = f[i]; } - sfree(lmp, a, "cubic_spline:a" ); - sfree(lmp, b, "cubic_spline:b" ); - sfree(lmp, c, "cubic_spline:c" ); - sfree(lmp, d, "cubic_spline:d" ); - sfree(lmp, v, "cubic_spline:v" ); + sfree(lmp->error, a, "cubic_spline:a" ); + sfree(lmp->error, b, "cubic_spline:b" ); + sfree(lmp->error, c, "cubic_spline:c" ); + sfree(lmp->error, d, "cubic_spline:d" ); + sfree(lmp->error, v, "cubic_spline:v" ); } @@ -171,23 +171,23 @@ int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_par num_atom_types = system->reax_param.num_atom_types; dr = control->nonb_cut / control->tabulate; h = (double*) - smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:h", comm ); + smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:h", comm ); fh = (double*) - smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); + smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); fvdw = (double*) - smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); + smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); fCEvd = (double*) - smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); + smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); fele = (double*) - smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); + smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); fCEclmb = (double*) - smalloc(lmp, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); + smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); LR = (LR_lookup_table**) - scalloc(lmp, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); + scalloc(lmp->error, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); for( i = 0; i < num_atom_types; ++i ) LR[i] = (LR_lookup_table*) - scalloc(lmp, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); + scalloc(lmp->error, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); for( i = 0; i < MAX_ATOM_TYPES; ++i ) existing_types[i] = 0; @@ -207,21 +207,21 @@ int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_par LR[i][j].dx = dr; LR[i][j].inv_dx = control->tabulate / control->nonb_cut; LR[i][j].y = (LR_data*) - smalloc(lmp, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); + smalloc(lmp->error, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); LR[i][j].H = (cubic_spline_coef*) - smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , + smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , comm ); LR[i][j].vdW = (cubic_spline_coef*) - smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", + smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", comm); LR[i][j].CEvd = (cubic_spline_coef*) - smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", + smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", comm); LR[i][j].ele = (cubic_spline_coef*) - smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", + smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", comm ); LR[i][j].CEclmb = (cubic_spline_coef*) - smalloc(lmp, LR[i][j].n*sizeof(cubic_spline_coef), + smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef), "lookup:LR[i,j].CEclmb", comm ); for( r = 1; r <= control->tabulate; ++r ) { @@ -291,14 +291,14 @@ void Deallocate_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system ) for( i = 0; i < ntypes; ++i ) { for( j = i; j < ntypes; ++j ) if (LR[i][j].n) { - sfree(lmp, LR[i][j].y, "LR[i,j].y" ); - sfree(lmp, LR[i][j].H, "LR[i,j].H" ); - sfree(lmp, LR[i][j].vdW, "LR[i,j].vdW" ); - sfree(lmp, LR[i][j].CEvd, "LR[i,j].CEvd" ); - sfree(lmp, LR[i][j].ele, "LR[i,j].ele" ); - sfree(lmp, LR[i][j].CEclmb, "LR[i,j].CEclmb" ); + sfree(lmp->error, LR[i][j].y, "LR[i,j].y" ); + sfree(lmp->error, LR[i][j].H, "LR[i,j].H" ); + sfree(lmp->error, LR[i][j].vdW, "LR[i,j].vdW" ); + sfree(lmp->error, LR[i][j].CEvd, "LR[i,j].CEvd" ); + sfree(lmp->error, LR[i][j].ele, "LR[i,j].ele" ); + sfree(lmp->error, LR[i][j].CEclmb, "LR[i,j].CEclmb" ); } - sfree(lmp, LR[i], "LR[i]" ); + sfree(lmp->error, LR[i], "LR[i]" ); } - sfree(lmp, LR, "LR" ); + sfree(lmp->error, LR, "LR" ); } diff --git a/src/USER-REAXC/reaxc_tool_box.cpp b/src/USER-REAXC/reaxc_tool_box.cpp index eaa6765f36..cd339af556 100644 --- a/src/USER-REAXC/reaxc_tool_box.cpp +++ b/src/USER-REAXC/reaxc_tool_box.cpp @@ -56,7 +56,7 @@ int Tokenize( char* s, char*** tok ) /* safe malloc */ -void *smalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, const char *name, MPI_Comm comm ) +void *smalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, const char *name, MPI_Comm comm ) { void *ptr; char errmsg[256]; @@ -64,14 +64,14 @@ void *smalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, const char *name, MPI_Comm c if (n <= 0) { snprintf(errmsg, 256, "Trying to allocate %ld bytes for array %s. " "returning NULL.", n, name); - lmp->error->warning(FLERR,errmsg); + error_ptr->warning(FLERR,errmsg); return NULL; } ptr = malloc( n ); if (ptr == NULL) { snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n, name); - lmp->error->one(FLERR,errmsg); + error_ptr->one(FLERR,errmsg); } return ptr; @@ -79,7 +79,7 @@ void *smalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, const char *name, MPI_Comm c /* safe calloc */ -void *scalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, rc_bigint size, const char *name, MPI_Comm comm ) +void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const char *name, MPI_Comm comm ) { void *ptr; char errmsg[256]; @@ -87,14 +87,14 @@ void *scalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, rc_bigint size, const char * if (n <= 0) { snprintf(errmsg, 256, "Trying to allocate %ld elements for array %s. " "returning NULL.\n", n, name ); - lmp->error->warning(FLERR,errmsg); + error_ptr->warning(FLERR,errmsg); return NULL; } if (size <= 0) { snprintf(errmsg, 256, "Elements size for array %s is %ld. " "returning NULL", name, size ); - lmp->error->warning(FLERR,errmsg); + error_ptr->warning(FLERR,errmsg); return NULL; } @@ -102,7 +102,7 @@ void *scalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, rc_bigint size, const char * if (ptr == NULL) { char errmsg[256]; snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n*size, name); - lmp->error->one(FLERR,errmsg); + error_ptr->one(FLERR,errmsg); } return ptr; @@ -110,12 +110,12 @@ void *scalloc( LAMMPS_NS::LAMMPS *lmp, rc_bigint n, rc_bigint size, const char * /* safe free */ -void sfree( LAMMPS_NS::LAMMPS* lmp, void *ptr, const char *name ) +void sfree( LAMMPS_NS::Error* error_ptr, void *ptr, const char *name ) { if (ptr == NULL) { char errmsg[256]; snprintf(errmsg, 256, "Trying to free the already NULL pointer %s", name ); - lmp->error->one(FLERR,errmsg); + error_ptr->one(FLERR,errmsg); return; } diff --git a/src/USER-REAXC/reaxc_tool_box.h b/src/USER-REAXC/reaxc_tool_box.h index 7c5ab12587..257ff1813f 100644 --- a/src/USER-REAXC/reaxc_tool_box.h +++ b/src/USER-REAXC/reaxc_tool_box.h @@ -37,7 +37,7 @@ double Get_Time( ); int Tokenize( char*, char*** ); /* from lammps */ -void *smalloc( LAMMPS_NS::LAMMPS*, rc_bigint, const char*, MPI_Comm ); -void *scalloc( LAMMPS_NS::LAMMPS*, rc_bigint, rc_bigint, const char*, MPI_Comm ); -void sfree( LAMMPS_NS::LAMMPS*, void*, const char* ); +void *smalloc( LAMMPS_NS::Error*, rc_bigint, const char*, MPI_Comm ); +void *scalloc( LAMMPS_NS::Error*, rc_bigint, rc_bigint, const char*, MPI_Comm ); +void sfree( LAMMPS_NS::Error*, void*, const char* ); #endif diff --git a/src/USER-REAXC/reaxc_types.h b/src/USER-REAXC/reaxc_types.h index cf6d5dcddc..b7845a0510 100644 --- a/src/USER-REAXC/reaxc_types.h +++ b/src/USER-REAXC/reaxc_types.h @@ -41,6 +41,7 @@ #include "lammps.h" #include "error.h" +using LAMMPS_NS::Error; #if defined LMP_USER_OMP #define OMP_TIMING 0 @@ -414,6 +415,7 @@ struct _reax_system boundary_cutoff bndry_cuts; reax_atom *my_atoms; + class Error *error_ptr; class Pair *pair_ptr; int my_bonds; int mincap; @@ -491,6 +493,7 @@ typedef struct int lgflag; int enobondsflag; + class Error *error_ptr; } control_params; @@ -777,6 +780,7 @@ struct _reax_list int type; list_type select; + class Error *error_ptr; }; typedef _reax_list reax_list; -- GitLab From 99acb4ac541847c4620208831e2e2d9cfa03297e Mon Sep 17 00:00:00 2001 From: mkanski Date: Mon, 25 Mar 2019 15:00:52 +0100 Subject: [PATCH 0300/1243] Cleaning changes 1 --- src/USER-REAXC/pair_reaxc.cpp | 10 +-- src/USER-REAXC/reaxc_control.cpp | 7 +- src/USER-REAXC/reaxc_control.h | 2 +- src/USER-REAXC/reaxc_ffield.cpp | 60 +++++++++--------- src/USER-REAXC/reaxc_ffield.h | 2 +- src/USER-REAXC/reaxc_init_md.cpp | 45 +++++++------ src/USER-REAXC/reaxc_init_md.h | 2 +- src/USER-REAXC/reaxc_io_tools.cpp | 8 +-- src/USER-REAXC/reaxc_io_tools.h | 4 +- src/USER-REAXC/reaxc_lookup.cpp | 102 +++++++++++++++--------------- src/USER-REAXC/reaxc_lookup.h | 4 +- src/USER-REAXC/reaxc_traj.cpp | 48 +++++++------- src/USER-REAXC/reaxc_traj.h | 4 +- 13 files changed, 148 insertions(+), 150 deletions(-) diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index 58142b122a..b1f7799cb2 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -139,7 +139,7 @@ PairReaxC::~PairReaxC() // deallocate reax data-structures - if (control->tabulate ) Deallocate_Lookup_Tables( lmp, system); + if (control->tabulate ) Deallocate_Lookup_Tables( system); if (control->hbond_cut > 0 ) Delete_List( lists+HBONDS, world); Delete_List( lists+BONDS, world ); @@ -225,7 +225,7 @@ void PairReaxC::settings(int narg, char **arg) out_control->atom_info = 0; out_control->bond_info = 0; out_control->angle_info = 0; - } else Read_Control_File(lmp, arg[0], control, out_control); + } else Read_Control_File(arg[0], control, out_control); // default values @@ -300,7 +300,7 @@ void PairReaxC::coeff( int nargs, char **args ) FILE *fp; fp = force->open_potential(file); if (fp != NULL) - Read_Force_Field(lmp, fp, &(system->reax_param), control); + Read_Force_Field(fp, &(system->reax_param), control); else { char str[128]; snprintf(str,128,"Cannot open ReaxFF potential file %s",file); @@ -449,7 +449,7 @@ void PairReaxC::setup( ) (lists+FAR_NBRS)->error_ptr=lmp->error; write_reax_lists(); - Initialize( lmp, system, control, data, workspace, &lists, out_control, + Initialize( system, control, data, workspace, &lists, out_control, mpi_data, world ); for( int k = 0; k < system->N; ++k ) { num_bonds[k] = system->my_atoms[k].num_bonds; @@ -585,7 +585,7 @@ void PairReaxC::compute(int eflag, int vflag) data->step = update->ntimestep; - Output_Results( lmp, system, control, data, &lists, out_control, mpi_data ); + Output_Results( system, control, data, &lists, out_control, mpi_data ); // populate tmpid and tmpbo arrays for fix reax/c/species int i, j; diff --git a/src/USER-REAXC/reaxc_control.cpp b/src/USER-REAXC/reaxc_control.cpp index bf221a6266..14b28615fb 100644 --- a/src/USER-REAXC/reaxc_control.cpp +++ b/src/USER-REAXC/reaxc_control.cpp @@ -28,9 +28,8 @@ #include "reaxc_control.h" #include "reaxc_tool_box.h" -using namespace LAMMPS_NS; -char Read_Control_File( LAMMPS *lmp, char *control_file, control_params* control, +char Read_Control_File( char *control_file, control_params* control, output_controls *out_control ) { FILE *fp; @@ -40,7 +39,7 @@ char Read_Control_File( LAMMPS *lmp, char *control_file, control_params* control /* open control file */ if ( (fp = fopen( control_file, "r" ) ) == NULL ) { - lmp->error->all(FLERR, "The control file cannot be opened"); + control->error_ptr->all(FLERR, "The control file cannot be opened"); } /* assign default values */ @@ -367,7 +366,7 @@ char Read_Control_File( LAMMPS *lmp, char *control_file, control_params* control else { char errmsg[128]; snprintf(errmsg,128,"Unknown parameter %s in the control file", tmp[0]); - lmp->error->all(FLERR, errmsg); + control->error_ptr->all(FLERR, errmsg); } } diff --git a/src/USER-REAXC/reaxc_control.h b/src/USER-REAXC/reaxc_control.h index 4546a894f6..47627aed61 100644 --- a/src/USER-REAXC/reaxc_control.h +++ b/src/USER-REAXC/reaxc_control.h @@ -32,6 +32,6 @@ #include "lammps.h" #include "error.h" -char Read_Control_File( LAMMPS_NS::LAMMPS *lmp, char*, control_params*, output_controls* ); +char Read_Control_File( char*, control_params*, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_ffield.cpp b/src/USER-REAXC/reaxc_ffield.cpp index 8316c188b3..987a11d252 100644 --- a/src/USER-REAXC/reaxc_ffield.cpp +++ b/src/USER-REAXC/reaxc_ffield.cpp @@ -32,7 +32,7 @@ #include "lammps.h" #include "error.h" -char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, +char Read_Force_Field( FILE *fp, reax_interaction *reax, control_params *control ) { char *s; @@ -64,7 +64,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, n = atoi(tmp[0]); if (n < 1) { if (me == 0) - lmp->error->warning( FLERR, "Number of globals in ffield file is 0" ); + control->error_ptr->warning( FLERR, "Number of globals in ffield file is 0" ); fclose(fp); free(s); free(tmp); @@ -99,54 +99,54 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Allocating structures in reax_interaction */ reax->sbp = (single_body_parameters*) - scalloc(lmp->error, reax->num_atom_types, sizeof(single_body_parameters), "sbp", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(single_body_parameters), "sbp", comm ); reax->tbp = (two_body_parameters**) - scalloc(lmp->error, reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); reax->thbp= (three_body_header***) - scalloc(lmp->error, reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); reax->hbp = (hbond_parameters***) - scalloc(lmp->error, reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); reax->fbp = (four_body_header****) - scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); tor_flag = (char****) - scalloc(lmp->error, reax->num_atom_types, sizeof(char***), "tor_flag", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char***), "tor_flag", comm ); for( i = 0; i < reax->num_atom_types; i++ ) { reax->tbp[i] = (two_body_parameters*) - scalloc(lmp->error, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", comm ); reax->thbp[i]= (three_body_header**) - scalloc(lmp->error, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", comm ); reax->hbp[i] = (hbond_parameters**) - scalloc(lmp->error, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", comm ); reax->fbp[i] = (four_body_header***) - scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", comm ); tor_flag[i] = (char***) - scalloc(lmp->error, reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); for( j = 0; j < reax->num_atom_types; j++ ) { reax->thbp[i][j]= (three_body_header*) - scalloc(lmp->error, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", comm ); reax->hbp[i][j] = (hbond_parameters*) - scalloc(lmp->error, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", comm ); reax->fbp[i][j] = (four_body_header**) - scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", comm ); tor_flag[i][j] = (char**) - scalloc(lmp->error, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); for (k=0; k < reax->num_atom_types; k++) { reax->fbp[i][j][k] = (four_body_header*) - scalloc(lmp->error, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", comm ); tor_flag[i][j][k] = (char*) - scalloc(lmp->error, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", comm ); } } @@ -163,7 +163,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Sanity checks */ if (c < 9) { - lmp->error->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->one(FLERR,"Inconsistent ffield file"); } for( j = 0; j < (int)(strlen(tmp[0])); ++j ) @@ -185,7 +185,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - lmp->error->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->one(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].alpha = val; @@ -203,7 +203,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - lmp->error->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->one(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].r_pi_pi = val; @@ -221,7 +221,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - lmp->error->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->one(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].p_ovun2 = val; @@ -240,7 +240,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, /* Sanity check */ if (c > 2) { - lmp->error->one(FLERR,"Force field file incompatible with 'lgvdw yes'"); + control->error_ptr->one(FLERR,"Force field file incompatible with 'lgvdw yes'"); } val = atof(tmp[0]); reax->sbp[i].lgcij = val; @@ -258,7 +258,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, "This may cause division-by-zero errors. " "Keeping vdWaals-setting for earlier atoms.", reax->sbp[i].name); - lmp->error->warning(FLERR,errmsg); + control->error_ptr->warning(FLERR,errmsg); } errorflag = 0; } else { @@ -274,7 +274,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, "This may cause division-by-zero errors. " "Keeping vdWaals-setting for earlier atoms.", reax->sbp[i].name); - lmp->error->warning(FLERR,errmsg); + control->error_ptr->warning(FLERR,errmsg); } } else { reax->gp.vdw_type = 2; @@ -291,7 +291,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, "This may cause division-by-zero errors. " "Keeping vdWaals-setting for earlier atoms.", reax->sbp[i].name); - lmp->error->warning(FLERR,errmsg); + control->error_ptr->warning(FLERR,errmsg); } } else { reax->gp.vdw_type = 1; @@ -301,7 +301,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, snprintf(errmsg, 256, "Inconsistent vdWaals-parameters " "No shielding or inner-wall set for element %s", reax->sbp[i].name); - lmp->error->all(FLERR, errmsg); + control->error_ptr->all(FLERR, errmsg); } } } @@ -314,7 +314,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, char errmsg[256]; snprintf(errmsg, 256, "Changed valency_val to valency_boc for %s", reax->sbp[i].name); - lmp->error->warning(FLERR,errmsg); + control->error_ptr->warning(FLERR,errmsg); } reax->sbp[i].valency_val = reax->sbp[i].valency_boc; } @@ -324,7 +324,7 @@ char Read_Force_Field( LAMMPS_NS::LAMMPS* lmp, FILE *fp, reax_interaction *reax, c=Tokenize(s,&tmp); if (c == 2 && !lgflag) { - lmp->error->all(FLERR, "Force field file requires using 'lgvdw yes'"); + control->error_ptr->all(FLERR, "Force field file requires using 'lgvdw yes'"); } l = atoi(tmp[0]); diff --git a/src/USER-REAXC/reaxc_ffield.h b/src/USER-REAXC/reaxc_ffield.h index 225f207de9..7cef730f91 100644 --- a/src/USER-REAXC/reaxc_ffield.h +++ b/src/USER-REAXC/reaxc_ffield.h @@ -29,6 +29,6 @@ #include "reaxc_types.h" -char Read_Force_Field( LAMMPS_NS::LAMMPS*, FILE*, reax_interaction*, control_params* ); +char Read_Force_Field( FILE*, reax_interaction*, control_params* ); #endif diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index 8c60db0846..27e60c580c 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -36,7 +36,6 @@ #include "reaxc_tool_box.h" #include "reaxc_vector.h" -using namespace LAMMPS_NS; int Init_System( reax_system *system, control_params *control, char * /*msg*/ ) { @@ -82,7 +81,7 @@ int Init_Simulation_Data( reax_system *system, control_params *control, return SUCCESS; } -void Init_Taper( LAMMPS_NS::LAMMPS* lmp, control_params *control, storage *workspace, MPI_Comm comm ) +void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) { double d1, d7; double swa, swa2, swa3; @@ -92,15 +91,15 @@ void Init_Taper( LAMMPS_NS::LAMMPS* lmp, control_params *control, storage *work swb = control->nonb_cut; if (fabs( swa ) > 0.01) - lmp->error->warning( FLERR, "Non-zero lower Taper-radius cutoff" ); + control->error_ptr->warning( FLERR, "Non-zero lower Taper-radius cutoff" ); if (swb < 0) { - lmp->error->all(FLERR,"Negative upper Taper-radius cutoff"); + control->error_ptr->all(FLERR,"Negative upper Taper-radius cutoff"); } else if( swb < 5 ) { char errmsg[256]; snprintf(errmsg, 256, "Very low Taper-radius cutoff: %f", swb ); - lmp->error->warning( FLERR, errmsg ); + control->error_ptr->warning( FLERR, errmsg ); } d1 = swb - swa; @@ -122,7 +121,7 @@ void Init_Taper( LAMMPS_NS::LAMMPS* lmp, control_params *control, storage *work } -int Init_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Init_Workspace( reax_system *system, control_params *control, storage *workspace, MPI_Comm comm, char *msg ) { int ret; @@ -136,7 +135,7 @@ int Init_Workspace( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params Reset_Workspace( system, workspace ); /* Initialize the Taper function */ - Init_Taper( lmp, control, workspace, comm ); + Init_Taper( control, workspace, comm ); return SUCCESS; } @@ -154,7 +153,7 @@ int Init_MPI_Datatypes( reax_system *system, storage * /*workspace*/, return SUCCESS; } -int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, +int Init_Lists( reax_system *system, control_params *control, simulation_data * /*data*/, storage * /*workspace*/, reax_list **lists, mpi_datatypes *mpi_data, char * /*msg*/ ) { @@ -183,7 +182,7 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, if( !Make_List( system->Hcap, total_hbonds, TYP_HBOND, *lists+HBONDS, comm ) ) { - lmp->error->one(FLERR, "Not enough space for hbonds list."); + control->error_ptr->one(FLERR, "Not enough space for hbonds list."); } (*lists+HBONDS)->error_ptr = system->error_ptr; } @@ -197,7 +196,7 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, if( !Make_List( system->total_cap, bond_cap, TYP_BOND, *lists+BONDS, comm ) ) { - lmp->error->one(FLERR, "Not enough space for bonds list."); + control->error_ptr->one(FLERR, "Not enough space for bonds list."); } (*lists+BONDS)->error_ptr = system->error_ptr; @@ -205,7 +204,7 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, cap_3body = (int)(MAX( num_3body*safezone, MIN_3BODIES )); if( !Make_List( bond_cap, cap_3body, TYP_THREE_BODY, *lists+THREE_BODIES, comm ) ){ - lmp->error->one(FLERR,"Problem in initializing angles list."); + control->error_ptr->one(FLERR,"Problem in initializing angles list."); } (*lists+THREE_BODIES)->error_ptr = system->error_ptr; @@ -215,7 +214,7 @@ int Init_Lists( LAMMPS *lmp, reax_system *system, control_params *control, return SUCCESS; } -void Initialize( LAMMPS *lmp, reax_system *system, control_params *control, +void Initialize( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data, MPI_Comm comm ) @@ -228,46 +227,46 @@ void Initialize( LAMMPS *lmp, reax_system *system, control_params *control, snprintf(errmsg, 128, "Could not create datatypes on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } if (Init_System(system, control, msg) == FAILURE) { snprintf(errmsg, 128, "System could not be initialized on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } if (Init_Simulation_Data( system, control, data, msg ) == FAILURE) { snprintf(errmsg, 128, "Sim_data could not be initialized on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } - if (Init_Workspace( lmp, system, control, workspace, mpi_data->world, msg ) == + if (Init_Workspace( system, control, workspace, mpi_data->world, msg ) == FAILURE) { snprintf(errmsg, 128, "Workspace could not be initialized on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } - if (Init_Lists( lmp, system, control, data, workspace, lists, mpi_data, msg ) == + if (Init_Lists( system, control, data, workspace, lists, mpi_data, msg ) == FAILURE) { snprintf(errmsg, 128, "System could not be initialized on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } - if (Init_Output_Files(lmp, system,control,out_control,mpi_data,msg)== FAILURE) { + if (Init_Output_Files(system,control,out_control,mpi_data,msg)== FAILURE) { snprintf(errmsg, 128, "Could not open output files on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } if (control->tabulate) { - if (Init_Lookup_Tables( lmp, system, control, workspace, mpi_data, msg ) == FAILURE) { + if (Init_Lookup_Tables( system, control, workspace, mpi_data, msg ) == FAILURE) { snprintf(errmsg, 128, "Lookup table could not be created on thread %d", system->my_rank); - lmp->error->one(FLERR,errmsg); + control->error_ptr->one(FLERR,errmsg); } } diff --git a/src/USER-REAXC/reaxc_init_md.h b/src/USER-REAXC/reaxc_init_md.h index 2baa70245b..546a9e33c9 100644 --- a/src/USER-REAXC/reaxc_init_md.h +++ b/src/USER-REAXC/reaxc_init_md.h @@ -32,6 +32,6 @@ #include "lammps.h" #include "error.h" -void Initialize( LAMMPS_NS::LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, +void Initialize( reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes*, MPI_Comm ); #endif diff --git a/src/USER-REAXC/reaxc_io_tools.cpp b/src/USER-REAXC/reaxc_io_tools.cpp index aa7e7fcea7..f71fcbec8e 100644 --- a/src/USER-REAXC/reaxc_io_tools.cpp +++ b/src/USER-REAXC/reaxc_io_tools.cpp @@ -34,7 +34,7 @@ #include "reaxc_traj.h" #include "reaxc_vector.h" -int Init_Output_Files( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Init_Output_Files( reax_system *system, control_params *control, output_controls *out_control, mpi_datatypes *mpi_data, char *msg ) { @@ -42,7 +42,7 @@ int Init_Output_Files( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_para int ret; if (out_control->write_steps > 0) { - ret = Init_Traj( lmp, system, control, out_control, mpi_data, msg ); + ret = Init_Traj( system, control, out_control, mpi_data, msg ); if (ret == FAILURE) return ret; } @@ -107,7 +107,7 @@ int Close_Output_Files( reax_system *system, control_params *control, } -void Output_Results( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +void Output_Results( reax_system *system, control_params *control, simulation_data *data, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -146,7 +146,7 @@ void Output_Results( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params /* write current frame */ if( out_control->write_steps > 0 && (data->step-data->prev_steps) % out_control->write_steps == 0 ) { - Append_Frame( lmp, system, control, data, lists, out_control, mpi_data ); + Append_Frame( system, control, data, lists, out_control, mpi_data ); } } diff --git a/src/USER-REAXC/reaxc_io_tools.h b/src/USER-REAXC/reaxc_io_tools.h index 80202d5c83..a3f22fccc2 100644 --- a/src/USER-REAXC/reaxc_io_tools.h +++ b/src/USER-REAXC/reaxc_io_tools.h @@ -29,10 +29,10 @@ #include "reaxc_types.h" -int Init_Output_Files( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, +int Init_Output_Files( reax_system*, control_params*, output_controls*, mpi_datatypes*, char* ); int Close_Output_Files( reax_system*, control_params*, output_controls*, mpi_datatypes* ); -void Output_Results( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, simulation_data*, +void Output_Results( reax_system*, control_params*, simulation_data*, reax_list**, output_controls*, mpi_datatypes* ); #endif diff --git a/src/USER-REAXC/reaxc_lookup.cpp b/src/USER-REAXC/reaxc_lookup.cpp index c16ca9af52..b140b0cadf 100644 --- a/src/USER-REAXC/reaxc_lookup.cpp +++ b/src/USER-REAXC/reaxc_lookup.cpp @@ -50,7 +50,7 @@ void Tridiagonal_Solve( const double *a, const double *b, } -void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double *f, +void Natural_Cubic_Spline( LAMMPS_NS::Error* error_ptr, const double *h, const double *f, cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ) { @@ -58,11 +58,11 @@ void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + b = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + c = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + d = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + v = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); /* build the linear system */ a[0] = a[1] = a[n-1] = 0; @@ -92,16 +92,16 @@ void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double coef[i-1].a = f[i]; } - sfree(lmp->error, a, "cubic_spline:a" ); - sfree(lmp->error, b, "cubic_spline:b" ); - sfree(lmp->error, c, "cubic_spline:c" ); - sfree(lmp->error, d, "cubic_spline:d" ); - sfree(lmp->error, v, "cubic_spline:v" ); + sfree(error_ptr, a, "cubic_spline:a" ); + sfree(error_ptr, b, "cubic_spline:b" ); + sfree(error_ptr, c, "cubic_spline:c" ); + sfree(error_ptr, d, "cubic_spline:d" ); + sfree(error_ptr, v, "cubic_spline:v" ); } -void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const double *f, double v0, double vlast, +void Complete_Cubic_Spline( LAMMPS_NS::Error* error_ptr, const double *h, const double *f, double v0, double vlast, cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ) { @@ -109,11 +109,11 @@ void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const doubl double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc(lmp->error, n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + b = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + c = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + d = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + v = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); /* build the linear system */ a[0] = 0; @@ -142,15 +142,15 @@ void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS* lmp, const double *h, const doubl coef[i-1].a = f[i]; } - sfree(lmp->error, a, "cubic_spline:a" ); - sfree(lmp->error, b, "cubic_spline:b" ); - sfree(lmp->error, c, "cubic_spline:c" ); - sfree(lmp->error, d, "cubic_spline:d" ); - sfree(lmp->error, v, "cubic_spline:v" ); + sfree(error_ptr, a, "cubic_spline:a" ); + sfree(error_ptr, b, "cubic_spline:b" ); + sfree(error_ptr, c, "cubic_spline:c" ); + sfree(error_ptr, d, "cubic_spline:d" ); + sfree(error_ptr, v, "cubic_spline:v" ); } -int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Init_Lookup_Tables( reax_system *system, control_params *control, storage *workspace, mpi_datatypes *mpi_data, char * /*msg*/ ) { int i, j, r; @@ -171,23 +171,23 @@ int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_par num_atom_types = system->reax_param.num_atom_types; dr = control->nonb_cut / control->tabulate; h = (double*) - smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:h", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:h", comm ); fh = (double*) - smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); fvdw = (double*) - smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); fCEvd = (double*) - smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); fele = (double*) - smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); fCEclmb = (double*) - smalloc(lmp->error, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); LR = (LR_lookup_table**) - scalloc(lmp->error, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); + scalloc(system->error_ptr, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); for( i = 0; i < num_atom_types; ++i ) LR[i] = (LR_lookup_table*) - scalloc(lmp->error, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); + scalloc(system->error_ptr, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); for( i = 0; i < MAX_ATOM_TYPES; ++i ) existing_types[i] = 0; @@ -207,21 +207,21 @@ int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_par LR[i][j].dx = dr; LR[i][j].inv_dx = control->tabulate / control->nonb_cut; LR[i][j].y = (LR_data*) - smalloc(lmp->error, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); + smalloc(system->error_ptr, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); LR[i][j].H = (cubic_spline_coef*) - smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , comm ); LR[i][j].vdW = (cubic_spline_coef*) - smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", comm); LR[i][j].CEvd = (cubic_spline_coef*) - smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", comm); LR[i][j].ele = (cubic_spline_coef*) - smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", comm ); LR[i][j].CEclmb = (cubic_spline_coef*) - smalloc(lmp->error, LR[i][j].n*sizeof(cubic_spline_coef), + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef), "lookup:LR[i,j].CEclmb", comm ); for( r = 1; r <= control->tabulate; ++r ) { @@ -246,22 +246,22 @@ int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_par vlast_vdw = fCEvd[r-1]; vlast_ele = fele[r-1]; - Natural_Cubic_Spline( lmp, &h[1], &fh[1], + Natural_Cubic_Spline( control->error_ptr, &h[1], &fh[1], &(LR[i][j].H[1]), control->tabulate+1, comm ); - Complete_Cubic_Spline( lmp, &h[1], &fvdw[1], v0_vdw, vlast_vdw, + Complete_Cubic_Spline( control->error_ptr, &h[1], &fvdw[1], v0_vdw, vlast_vdw, &(LR[i][j].vdW[1]), control->tabulate+1, comm ); - Natural_Cubic_Spline( lmp, &h[1], &fCEvd[1], + Natural_Cubic_Spline( control->error_ptr, &h[1], &fCEvd[1], &(LR[i][j].CEvd[1]), control->tabulate+1, comm ); - Complete_Cubic_Spline( lmp, &h[1], &fele[1], v0_ele, vlast_ele, + Complete_Cubic_Spline( control->error_ptr, &h[1], &fele[1], v0_ele, vlast_ele, &(LR[i][j].ele[1]), control->tabulate+1, comm ); - Natural_Cubic_Spline( lmp, &h[1], &fCEclmb[1], + Natural_Cubic_Spline( control->error_ptr, &h[1], &fCEclmb[1], &(LR[i][j].CEclmb[1]), control->tabulate+1, comm ); } else { @@ -281,7 +281,7 @@ int Init_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_par } -void Deallocate_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system ) +void Deallocate_Lookup_Tables( reax_system *system ) { int i, j; int ntypes; @@ -291,14 +291,14 @@ void Deallocate_Lookup_Tables( LAMMPS_NS::LAMMPS* lmp, reax_system *system ) for( i = 0; i < ntypes; ++i ) { for( j = i; j < ntypes; ++j ) if (LR[i][j].n) { - sfree(lmp->error, LR[i][j].y, "LR[i,j].y" ); - sfree(lmp->error, LR[i][j].H, "LR[i,j].H" ); - sfree(lmp->error, LR[i][j].vdW, "LR[i,j].vdW" ); - sfree(lmp->error, LR[i][j].CEvd, "LR[i,j].CEvd" ); - sfree(lmp->error, LR[i][j].ele, "LR[i,j].ele" ); - sfree(lmp->error, LR[i][j].CEclmb, "LR[i,j].CEclmb" ); + sfree(system->error_ptr, LR[i][j].y, "LR[i,j].y" ); + sfree(system->error_ptr, LR[i][j].H, "LR[i,j].H" ); + sfree(system->error_ptr, LR[i][j].vdW, "LR[i,j].vdW" ); + sfree(system->error_ptr, LR[i][j].CEvd, "LR[i,j].CEvd" ); + sfree(system->error_ptr, LR[i][j].ele, "LR[i,j].ele" ); + sfree(system->error_ptr, LR[i][j].CEclmb, "LR[i,j].CEclmb" ); } - sfree(lmp->error, LR[i], "LR[i]" ); + sfree(system->error_ptr, LR[i], "LR[i]" ); } - sfree(lmp->error, LR, "LR" ); + sfree(system->error_ptr, LR, "LR" ); } diff --git a/src/USER-REAXC/reaxc_lookup.h b/src/USER-REAXC/reaxc_lookup.h index 2d33ad82de..9b1b14a34d 100644 --- a/src/USER-REAXC/reaxc_lookup.h +++ b/src/USER-REAXC/reaxc_lookup.h @@ -40,9 +40,9 @@ void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS*, const double *h, const double *f cubic_spline_coef *coef, unsigned int n, MPI_Comm comm ); -int Init_Lookup_Tables( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, storage*, +int Init_Lookup_Tables( reax_system*, control_params*, storage*, mpi_datatypes*, char* ); -void Deallocate_Lookup_Tables( LAMMPS_NS::LAMMPS*, reax_system* ); +void Deallocate_Lookup_Tables( reax_system* ); #endif diff --git a/src/USER-REAXC/reaxc_traj.cpp b/src/USER-REAXC/reaxc_traj.cpp index ee2939d662..d3b9e799d2 100644 --- a/src/USER-REAXC/reaxc_traj.cpp +++ b/src/USER-REAXC/reaxc_traj.cpp @@ -29,7 +29,7 @@ #include "reaxc_list.h" #include "reaxc_tool_box.h" -int Reallocate_Output_Buffer( LAMMPS_NS::LAMMPS *lmp, output_controls *out_control, int req_space, +int Reallocate_Output_Buffer( LAMMPS_NS::Error *error_ptr, output_controls *out_control, int req_space, MPI_Comm comm ) { if (out_control->buffer_len > 0) @@ -40,7 +40,7 @@ int Reallocate_Output_Buffer( LAMMPS_NS::LAMMPS *lmp, output_controls *out_contr if (out_control->buffer == NULL) { char errmsg[256]; snprintf(errmsg, 256, "Insufficient memory for required buffer size %d", (int) (req_space*SAFE_ZONE)); - lmp->error->one(FLERR,errmsg); + error_ptr->one(FLERR,errmsg); } return SUCCESS; @@ -56,7 +56,7 @@ void Write_Skip_Line( output_controls *out_control, mpi_datatypes * /*mpi_data*/ } -int Write_Header( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Write_Header( reax_system *system, control_params *control, output_controls *out_control, mpi_datatypes *mpi_data ) { int num_hdr_lines, my_hdr_lines, buffer_req; @@ -82,7 +82,7 @@ int Write_Header( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *c my_hdr_lines = num_hdr_lines * ( system->my_rank == MASTER_NODE ); buffer_req = my_hdr_lines * HEADER_LINE_LEN; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( control->error_ptr, out_control, buffer_req, mpi_data->world ); /* only the master node writes into trajectory header */ if (system->my_rank == MASTER_NODE) { @@ -258,7 +258,7 @@ int Write_Header( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *c } -int Write_Init_Desc( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params * /*control*/, +int Write_Init_Desc( reax_system *system, control_params * /*control*/, output_controls *out_control, mpi_datatypes *mpi_data ) { int i, me, np, cnt, buffer_len, buffer_req; @@ -277,7 +277,7 @@ int Write_Init_Desc( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params else buffer_req = system->n * INIT_DESC_LEN + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); out_control->line[0] = 0; out_control->buffer[0] = 0; @@ -310,7 +310,7 @@ int Write_Init_Desc( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params } -int Init_Traj( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Init_Traj( reax_system *system, control_params *control, output_controls *out_control, mpi_datatypes *mpi_data, char *msg ) { @@ -347,14 +347,14 @@ int Init_Traj( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *cont strcpy( msg, "init_traj: unknown trajectory option" ); return FAILURE; } - Write_Header( lmp, system, control, out_control, mpi_data ); - Write_Init_Desc( lmp, system, control, out_control, mpi_data ); + Write_Header( system, control, out_control, mpi_data ); + Write_Init_Desc( system, control, out_control, mpi_data ); return SUCCESS; } -int Write_Frame_Header( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params *control, +int Write_Frame_Header( reax_system *system, control_params *control, simulation_data *data, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -366,7 +366,7 @@ int Write_Frame_Header( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_par my_frm_hdr_lines = num_frm_hdr_lines * ( me == MASTER_NODE ); buffer_req = my_frm_hdr_lines * HEADER_LINE_LEN; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( control->error_ptr, out_control, buffer_req, mpi_data->world ); /* only the master node writes into trajectory header */ if (me == MASTER_NODE) { @@ -480,7 +480,7 @@ int Write_Frame_Header( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_par -int Write_Atoms( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * /*control*/, +int Write_Atoms( reax_system *system, control_params * /*control*/, output_controls *out_control, mpi_datatypes *mpi_data ) { int i, me, np, line_len, buffer_len, buffer_req, cnt; @@ -499,7 +499,7 @@ int Write_Atoms( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * / else buffer_req = system->n * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); /* fill in buffer */ out_control->line[0] = 0; @@ -530,7 +530,7 @@ int Write_Atoms( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * / p_atom->f[0], p_atom->f[1], p_atom->f[2], p_atom->q ); break; default: - lmp->error->all(FLERR,"Write_traj_atoms: unknown atom trajectory format"); + system->error_ptr->all(FLERR,"Write_traj_atoms: unknown atom trajectory format"); } strncpy( out_control->buffer + i*line_len, out_control->line, line_len+1 ); @@ -556,7 +556,7 @@ int Write_Atoms( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params * / } -int Write_Bonds( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, reax_list *bonds, +int Write_Bonds( reax_system *system, control_params *control, reax_list *bonds, output_controls *out_control, mpi_datatypes *mpi_data) { int i, j, pj, me, np; @@ -589,7 +589,7 @@ int Write_Bonds( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *co else buffer_req = my_bonds * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); /* fill in the buffer */ out_control->line[0] = 0; @@ -616,7 +616,7 @@ int Write_Bonds( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *co bo_ij->bo_data.BO_pi, bo_ij->bo_data.BO_pi2 ); break; default: - lmp->error->all(FLERR, "Write_traj_bonds: FATAL! invalid bond_info option"); + system->error_ptr->all(FLERR, "Write_traj_bonds: FATAL! invalid bond_info option"); } strncpy( out_control->buffer + my_bonds*line_len, out_control->line, line_len+1 ); @@ -645,7 +645,7 @@ int Write_Bonds( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *co } -int Write_Angles( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Write_Angles( reax_system *system, control_params *control, reax_list *bonds, reax_list *thb_intrs, output_controls *out_control, mpi_datatypes *mpi_data ) { @@ -689,7 +689,7 @@ int Write_Angles( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *c else buffer_req = my_angles * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( lmp, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); /* fill in the buffer */ my_angles = 0; @@ -740,20 +740,20 @@ int Write_Angles( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *c } -int Append_Frame( LAMMPS_NS::LAMMPS* lmp, reax_system *system, control_params *control, +int Append_Frame( reax_system *system, control_params *control, simulation_data *data, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { - Write_Frame_Header( lmp, system, control, data, out_control, mpi_data ); + Write_Frame_Header( system, control, data, out_control, mpi_data ); if (out_control->write_atoms) - Write_Atoms( lmp, system, control, out_control, mpi_data ); + Write_Atoms( system, control, out_control, mpi_data ); if (out_control->write_bonds) - Write_Bonds( lmp, system, control, (*lists + BONDS), out_control, mpi_data ); + Write_Bonds( system, control, (*lists + BONDS), out_control, mpi_data ); if (out_control->write_angles) - Write_Angles( lmp, system, control, (*lists + BONDS), (*lists + THREE_BODIES), + Write_Angles( system, control, (*lists + BONDS), (*lists + THREE_BODIES), out_control, mpi_data ); return SUCCESS; diff --git a/src/USER-REAXC/reaxc_traj.h b/src/USER-REAXC/reaxc_traj.h index 5508d27cdb..72c56637eb 100644 --- a/src/USER-REAXC/reaxc_traj.h +++ b/src/USER-REAXC/reaxc_traj.h @@ -73,11 +73,11 @@ enum BOND_LINE_OPTS { OPT_NOBOND, OPT_BOND_BASIC, OPT_BOND_FULL, NR_OPT_BOND }; enum ANGLE_LINE_OPTS { OPT_NOANGLE, OPT_ANGLE_BASIC, NR_OPT_ANGLE }; -int Init_Traj( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, output_controls*, +int Init_Traj( reax_system*, control_params*, output_controls*, mpi_datatypes*, char* ); int End_Traj( int, output_controls* ); -int Append_Frame( LAMMPS_NS::LAMMPS*, reax_system*, control_params*, simulation_data*, +int Append_Frame( reax_system*, control_params*, simulation_data*, reax_list**, output_controls*, mpi_datatypes* ); #endif -- GitLab From 83e458af0bb552c94b0aa1e48132cdcbca23aa8b Mon Sep 17 00:00:00 2001 From: mkanski Date: Mon, 25 Mar 2019 15:22:20 +0100 Subject: [PATCH 0301/1243] Cleaning changes 2 --- src/USER-REAXC/pair_reaxc.cpp | 4 ++-- src/USER-REAXC/reaxc_bond_orders.cpp | 3 +-- src/USER-REAXC/reaxc_bond_orders.h | 2 +- src/USER-REAXC/reaxc_bonds.cpp | 2 +- src/USER-REAXC/reaxc_bonds.h | 2 +- src/USER-REAXC/reaxc_forces.cpp | 18 +++++++++--------- src/USER-REAXC/reaxc_forces.h | 2 +- src/USER-REAXC/reaxc_hydrogen_bonds.cpp | 2 +- src/USER-REAXC/reaxc_hydrogen_bonds.h | 2 +- src/USER-REAXC/reaxc_multi_body.cpp | 2 +- src/USER-REAXC/reaxc_multi_body.h | 2 +- src/USER-REAXC/reaxc_reset_tools.cpp | 11 +++++------ src/USER-REAXC/reaxc_reset_tools.h | 8 ++------ src/USER-REAXC/reaxc_torsion_angles.cpp | 3 +-- src/USER-REAXC/reaxc_torsion_angles.h | 3 +-- src/USER-REAXC/reaxc_traj.cpp | 2 +- src/USER-REAXC/reaxc_types.h | 4 ++-- src/USER-REAXC/reaxc_valence_angles.cpp | 4 ++-- src/USER-REAXC/reaxc_valence_angles.h | 2 +- 19 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index b1f7799cb2..a9501dac9d 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -521,7 +521,7 @@ void PairReaxC::compute(int eflag, int vflag) setup(); - Reset( lmp, system, control, data, workspace, &lists, world ); + Reset( system, control, data, workspace, &lists, world ); workspace->realloc.num_far = write_reax_lists(); // timing for filling in the reax lists if (comm->me == 0) { @@ -531,7 +531,7 @@ void PairReaxC::compute(int eflag, int vflag) // forces - Compute_Forces(lmp, system,control,data,workspace,&lists,out_control,mpi_data); + Compute_Forces(system,control,data,workspace,&lists,out_control,mpi_data); read_reax_forces(vflag); for(int k = 0; k < system->N; ++k) { diff --git a/src/USER-REAXC/reaxc_bond_orders.cpp b/src/USER-REAXC/reaxc_bond_orders.cpp index 924be8809d..1ed58a0bfd 100644 --- a/src/USER-REAXC/reaxc_bond_orders.cpp +++ b/src/USER-REAXC/reaxc_bond_orders.cpp @@ -360,8 +360,7 @@ int BOp( storage *workspace, reax_list *bonds, double bo_cut, void BO( reax_system *system, control_params * /*control*/, simulation_data * /*data*/, - storage *workspace, reax_list **lists, output_controls * /*out_control*/, - LAMMPS_NS::LAMMPS* lmp ) + storage *workspace, reax_list **lists, output_controls * /*out_control*/ ) { int i, j, pj, type_i, type_j; int start_i, end_i, sym_index; diff --git a/src/USER-REAXC/reaxc_bond_orders.h b/src/USER-REAXC/reaxc_bond_orders.h index 8de60ba2f2..3631d90c89 100644 --- a/src/USER-REAXC/reaxc_bond_orders.h +++ b/src/USER-REAXC/reaxc_bond_orders.h @@ -42,5 +42,5 @@ void Add_dBond_to_Forces_NPT( int, int, simulation_data*, int BOp(storage*, reax_list*, double, int, int, far_neighbor_data*, single_body_parameters*, single_body_parameters*, two_body_parameters*); void BO( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); + storage*, reax_list**, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_bonds.cpp b/src/USER-REAXC/reaxc_bonds.cpp index d5ac4f1ed4..48fb872324 100644 --- a/src/USER-REAXC/reaxc_bonds.cpp +++ b/src/USER-REAXC/reaxc_bonds.cpp @@ -33,7 +33,7 @@ void Bonds( reax_system *system, control_params * /*control*/, simulation_data *data, storage *workspace, reax_list **lists, - output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp ) + output_controls * /*out_control*/ ) { int i, j, pj, natoms; int start_i, end_i; diff --git a/src/USER-REAXC/reaxc_bonds.h b/src/USER-REAXC/reaxc_bonds.h index b425598b42..a4a1fb0b44 100644 --- a/src/USER-REAXC/reaxc_bonds.h +++ b/src/USER-REAXC/reaxc_bonds.h @@ -30,5 +30,5 @@ #include "reaxc_types.h" void Bonds( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); + storage*, reax_list**, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_forces.cpp b/src/USER-REAXC/reaxc_forces.cpp index 4adec04f0c..ff1dd839fb 100644 --- a/src/USER-REAXC/reaxc_forces.cpp +++ b/src/USER-REAXC/reaxc_forces.cpp @@ -44,7 +44,7 @@ interaction_function Interaction_Functions[NUM_INTRS]; void Dummy_Interaction( reax_system * /*system*/, control_params * /*control*/, simulation_data * /*data*/, storage * /*workspace*/, - reax_list ** /*lists*/, output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* = NULL ) + reax_list ** /*lists*/, output_controls * /*out_control*/ ) { } @@ -76,7 +76,7 @@ void Compute_Bonded_Forces( reax_system *system, control_params *control, /* Implement all force calls as function pointers */ for( i = 0; i < NUM_INTRS; i++ ) { (Interaction_Functions[i])( system, control, data, workspace, - lists, out_control, NULL ); + lists, out_control ); } } @@ -115,7 +115,7 @@ void Compute_Total_Force( reax_system *system, control_params *control, } -void Validate_Lists( LAMMPS_NS::LAMMPS *lmp, reax_system *system, storage * /*workspace*/, reax_list **lists, +void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **lists, int step, int /*n*/, int N, int numH, MPI_Comm comm ) { int i, comp, Hindex; @@ -138,7 +138,7 @@ void Validate_Lists( LAMMPS_NS::LAMMPS *lmp, reax_system *system, storage * /*wo char errmsg[256]; snprintf(errmsg, 256, "step%d-bondchk failed: i=%d end(i)=%d str(i+1)=%d\n", step, i, End_Index(i,bonds), comp ); - lmp->error->all(FLERR,errmsg); + system->error_ptr->all(FLERR,errmsg); } } } @@ -166,7 +166,7 @@ void Validate_Lists( LAMMPS_NS::LAMMPS *lmp, reax_system *system, storage * /*wo char errmsg[256]; snprintf(errmsg, 256, "step%d-hbondchk failed: H=%d end(H)=%d str(H+1)=%d\n", step, Hindex, End_Index(Hindex,hbonds), comp ); - lmp->error->all(FLERR, errmsg); + system->error_ptr->all(FLERR, errmsg); } } } @@ -174,7 +174,7 @@ void Validate_Lists( LAMMPS_NS::LAMMPS *lmp, reax_system *system, storage * /*wo } -void Init_Forces_noQEq( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params *control, +void Init_Forces_noQEq( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls * /*out_control*/, MPI_Comm comm ) { @@ -310,7 +310,7 @@ void Init_Forces_noQEq( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_par workspace->realloc.num_bonds = num_bonds; workspace->realloc.num_hbonds = num_hbonds; - Validate_Lists( lmp, system, workspace, lists, data->step, + Validate_Lists( system, workspace, lists, data->step, system->n, system->N, system->numH, comm ); } @@ -434,14 +434,14 @@ void Estimate_Storages( reax_system *system, control_params *control, } -void Compute_Forces( LAMMPS_NS::LAMMPS *lmp, reax_system *system, control_params *control, +void Compute_Forces( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { MPI_Comm comm = mpi_data->world; - Init_Forces_noQEq( lmp, system, control, data, workspace, + Init_Forces_noQEq( system, control, data, workspace, lists, out_control, comm ); /********* bonded interactions ************/ diff --git a/src/USER-REAXC/reaxc_forces.h b/src/USER-REAXC/reaxc_forces.h index 31cfc03a6b..6c839a7023 100644 --- a/src/USER-REAXC/reaxc_forces.h +++ b/src/USER-REAXC/reaxc_forces.h @@ -33,7 +33,7 @@ extern interaction_function Interaction_Functions[NUM_INTRS]; void Init_Force_Functions( control_params* ); -void Compute_Forces( LAMMPS_NS::LAMMPS *lmp, reax_system*, control_params*, simulation_data*, +void Compute_Forces( reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes* ); void Estimate_Storages( reax_system*, control_params*, reax_list**, int*, int*, int*, int*, MPI_Comm ); diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp index 489a43cfc1..be34df7571 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.cpp +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.cpp @@ -33,7 +33,7 @@ void Hydrogen_Bonds( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp ) + reax_list **lists, output_controls * /*out_control*/ ) { int i, j, k, pi, pk; int type_i, type_j, type_k; diff --git a/src/USER-REAXC/reaxc_hydrogen_bonds.h b/src/USER-REAXC/reaxc_hydrogen_bonds.h index 2a448439ea..04d3d26d5c 100644 --- a/src/USER-REAXC/reaxc_hydrogen_bonds.h +++ b/src/USER-REAXC/reaxc_hydrogen_bonds.h @@ -30,6 +30,6 @@ #include "reaxc_types.h" void Hydrogen_Bonds( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); + storage*, reax_list**, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_multi_body.cpp b/src/USER-REAXC/reaxc_multi_body.cpp index a16c4eb42b..f7d72a2678 100644 --- a/src/USER-REAXC/reaxc_multi_body.cpp +++ b/src/USER-REAXC/reaxc_multi_body.cpp @@ -32,7 +32,7 @@ void Atom_Energy( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, - output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp ) + output_controls * /*out_control*/ ) { int i, j, pj, type_i, type_j; double Delta_lpcorr, dfvl; diff --git a/src/USER-REAXC/reaxc_multi_body.h b/src/USER-REAXC/reaxc_multi_body.h index dc2c1040eb..a17c9f484e 100644 --- a/src/USER-REAXC/reaxc_multi_body.h +++ b/src/USER-REAXC/reaxc_multi_body.h @@ -30,6 +30,6 @@ #include "reaxc_types.h" void Atom_Energy( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL ); + storage*, reax_list**, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_reset_tools.cpp b/src/USER-REAXC/reaxc_reset_tools.cpp index 49a9f096dd..d273a417f8 100644 --- a/src/USER-REAXC/reaxc_reset_tools.cpp +++ b/src/USER-REAXC/reaxc_reset_tools.cpp @@ -30,7 +30,6 @@ #include "reaxc_tool_box.h" #include "reaxc_vector.h" -using namespace LAMMPS_NS; void Reset_Atoms( reax_system* system, control_params *control ) { @@ -121,7 +120,7 @@ void Reset_Workspace( reax_system *system, storage *workspace ) } -void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system *system, control_params *control, +void Reset_Neighbor_Lists( reax_system *system, control_params *control, storage *workspace, reax_list **lists, MPI_Comm comm ) { @@ -147,7 +146,7 @@ void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system *system, control_params *con char errmsg[256]; snprintf(errmsg, 256, "p%d: not enough space for bonds! total=%d allocated=%d\n", system->my_rank, total_bonds, bonds->num_intrs); - lmp->error->one(FLERR, errmsg); + control->error_ptr->one(FLERR, errmsg); } } } @@ -173,14 +172,14 @@ void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system *system, control_params *con char errmsg[256]; snprintf(errmsg, 256, "p%d: not enough space for hbonds! total=%d allocated=%d\n", system->my_rank, total_hbonds, hbonds->num_intrs); - lmp->error->one(FLERR, errmsg); + control->error_ptr->one(FLERR, errmsg); } } } } -void Reset( LAMMPS *lmp, reax_system *system, control_params *control, simulation_data *data, +void Reset( reax_system *system, control_params *control, simulation_data *data, storage *workspace, reax_list **lists, MPI_Comm comm ) { Reset_Atoms( system, control ); @@ -189,6 +188,6 @@ void Reset( LAMMPS *lmp, reax_system *system, control_params *control, simulatio Reset_Workspace( system, workspace ); - Reset_Neighbor_Lists( lmp, system, control, workspace, lists, comm ); + Reset_Neighbor_Lists( system, control, workspace, lists, comm ); } diff --git a/src/USER-REAXC/reaxc_reset_tools.h b/src/USER-REAXC/reaxc_reset_tools.h index 9e2b9de980..c2a90072d5 100644 --- a/src/USER-REAXC/reaxc_reset_tools.h +++ b/src/USER-REAXC/reaxc_reset_tools.h @@ -29,16 +29,12 @@ #include "reaxc_types.h" -#include "lammps.h" -#include "error.h" -using namespace LAMMPS_NS; - void Reset_Pressures( simulation_data* ); void Reset_Simulation_Data( simulation_data*, int ); void Reset_Timing( reax_timing* ); void Reset_Workspace( reax_system*, storage* ); -void Reset_Neighbor_Lists( LAMMPS *lmp, reax_system*, control_params*, storage*, +void Reset_Neighbor_Lists( reax_system*, control_params*, storage*, reax_list**, MPI_Comm ); -void Reset( LAMMPS *lmp, reax_system*, control_params*, simulation_data*, storage*, +void Reset( reax_system*, control_params*, simulation_data*, storage*, reax_list**, MPI_Comm ); #endif diff --git a/src/USER-REAXC/reaxc_torsion_angles.cpp b/src/USER-REAXC/reaxc_torsion_angles.cpp index 50c3412928..ed76368d68 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.cpp +++ b/src/USER-REAXC/reaxc_torsion_angles.cpp @@ -120,8 +120,7 @@ double Calculate_Omega( rvec dvec_ij, double r_ij, void Torsion_Angles( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls *out_control, - LAMMPS_NS::LAMMPS* lmp ) + reax_list **lists, output_controls *out_control ) { int i, j, k, l, pi, pj, pk, pl, pij, plk, natoms; int type_i, type_j, type_k, type_l; diff --git a/src/USER-REAXC/reaxc_torsion_angles.h b/src/USER-REAXC/reaxc_torsion_angles.h index 38236cb7dc..755e8c6532 100644 --- a/src/USER-REAXC/reaxc_torsion_angles.h +++ b/src/USER-REAXC/reaxc_torsion_angles.h @@ -30,7 +30,6 @@ #include "reaxc_types.h" void Torsion_Angles( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*, - LAMMPS_NS::LAMMPS* = NULL ); + storage*, reax_list**, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_traj.cpp b/src/USER-REAXC/reaxc_traj.cpp index d3b9e799d2..90f3d1e668 100644 --- a/src/USER-REAXC/reaxc_traj.cpp +++ b/src/USER-REAXC/reaxc_traj.cpp @@ -556,7 +556,7 @@ int Write_Atoms( reax_system *system, control_params * /*control*/, } -int Write_Bonds( reax_system *system, control_params *control, reax_list *bonds, +int Write_Bonds(reax_system *system, control_params *control, reax_list *bonds, output_controls *out_control, mpi_datatypes *mpi_data) { int i, j, pj, me, np; diff --git a/src/USER-REAXC/reaxc_types.h b/src/USER-REAXC/reaxc_types.h index b7845a0510..310ef42bdf 100644 --- a/src/USER-REAXC/reaxc_types.h +++ b/src/USER-REAXC/reaxc_types.h @@ -906,9 +906,9 @@ typedef void (*evolve_function)(reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes* ); -typedef void (*interaction_function) ( reax_system*, control_params*, +typedef void (*interaction_function) (reax_system*, control_params*, simulation_data*, storage*, - reax_list**, output_controls*, LAMMPS_NS::LAMMPS*); + reax_list**, output_controls*); typedef void (*print_interaction)(reax_system*, control_params*, simulation_data*, storage*, diff --git a/src/USER-REAXC/reaxc_valence_angles.cpp b/src/USER-REAXC/reaxc_valence_angles.cpp index d762dc1611..e0e94d18f8 100644 --- a/src/USER-REAXC/reaxc_valence_angles.cpp +++ b/src/USER-REAXC/reaxc_valence_angles.cpp @@ -76,7 +76,7 @@ void Calculate_dCos_Theta( rvec dvec_ji, double d_ji, rvec dvec_jk, double d_jk, void Valence_Angles( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls * /*out_control*/, LAMMPS_NS::LAMMPS* lmp) + reax_list **lists, output_controls * /*out_control*/ ) { int i, j, pi, k, pk, t; int type_i, type_j, type_k; @@ -408,7 +408,7 @@ void Valence_Angles( reax_system *system, control_params *control, char errmsg[128]; snprintf(errmsg, 128, "step%d-ran out of space on angle_list: top=%d, max=%d", data->step, num_thb_intrs, thb_intrs->num_intrs); - lmp->error->one(FLERR, errmsg); + control->error_ptr->one(FLERR, errmsg); } } diff --git a/src/USER-REAXC/reaxc_valence_angles.h b/src/USER-REAXC/reaxc_valence_angles.h index 27bda3ba09..51eac5a95e 100644 --- a/src/USER-REAXC/reaxc_valence_angles.h +++ b/src/USER-REAXC/reaxc_valence_angles.h @@ -30,7 +30,7 @@ #include "reaxc_types.h" void Valence_Angles( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*, LAMMPS_NS::LAMMPS* = NULL); + storage*, reax_list**, output_controls*); void Calculate_Theta( rvec, double, rvec, double, double*, double* ); -- GitLab From b2a7205abe96f328b7e08e756bac3df6b48176c0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 25 Mar 2019 11:31:23 -0400 Subject: [PATCH 0302/1243] re-order ev_init() and ev_setup() so that 'init' comes before 'setup' as requested by @sjplimp --- src/angle.h | 2 +- src/bond.h | 2 +- src/dihedral.h | 2 +- src/fix.h | 2 +- src/improper.h | 2 +- src/kspace.h | 2 +- src/pair.h | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/angle.h b/src/angle.h index 196c2a44d1..3d8371242e 100644 --- a/src/angle.h +++ b/src/angle.h @@ -58,11 +58,11 @@ class Angle : protected Pointers { int vflag_either,vflag_global,vflag_atom; int maxeatom,maxvatom; - void ev_setup(int, int, int alloc = 1); void ev_init(int eflag, int vflag, int alloc = 1) { if (eflag||vflag) ev_setup(eflag, vflag, alloc); else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; } + void ev_setup(int, int, int alloc = 1); void ev_tally(int, int, int, int, int, double, double *, double *, double, double, double, double, double, double); }; diff --git a/src/bond.h b/src/bond.h index 1082748403..8fb7040832 100644 --- a/src/bond.h +++ b/src/bond.h @@ -64,11 +64,11 @@ class Bond : protected Pointers { int vflag_either,vflag_global,vflag_atom; int maxeatom,maxvatom; - void ev_setup(int, int, int alloc = 1); void ev_init(int eflag, int vflag, int alloc = 1) { if (eflag||vflag) ev_setup(eflag, vflag, alloc); else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; } + void ev_setup(int, int, int alloc = 1); void ev_tally(int, int, int, int, double, double, double, double, double); }; diff --git a/src/dihedral.h b/src/dihedral.h index 0769d79163..f1b42008bf 100644 --- a/src/dihedral.h +++ b/src/dihedral.h @@ -56,11 +56,11 @@ class Dihedral : protected Pointers { int vflag_either,vflag_global,vflag_atom; int maxeatom,maxvatom; - void ev_setup(int, int, int alloc = 1); void ev_init(int eflag, int vflag, int alloc = 1) { if (eflag||vflag) ev_setup(eflag, vflag, alloc); else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; } + void ev_setup(int, int, int alloc = 1); void ev_tally(int, int, int, int, int, int, double, double *, double *, double *, double, double, double, double, double, double, double, double, double); diff --git a/src/fix.h b/src/fix.h index f5b3338aee..7eaff38bd3 100644 --- a/src/fix.h +++ b/src/fix.h @@ -223,11 +223,11 @@ class Fix : protected Pointers { int dynamic; // recount atoms for temperature computes - void ev_setup(int, int); void ev_init(int eflag, int vflag) { if (eflag||vflag) ev_setup(eflag, vflag); else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; } + void ev_setup(int, int); void ev_tally(int, int *, double, double, double *); void v_setup(int); void v_tally(int, int *, double, double *); diff --git a/src/improper.h b/src/improper.h index 8ee2c2996d..d940b43a13 100644 --- a/src/improper.h +++ b/src/improper.h @@ -56,11 +56,11 @@ class Improper : protected Pointers { int vflag_either,vflag_global,vflag_atom; int maxeatom,maxvatom; - void ev_setup(int, int, int alloc = 1); void ev_init(int eflag, int vflag, int alloc = 1) { if (eflag||vflag) ev_setup(eflag, vflag, alloc); else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; } + void ev_setup(int, int, int alloc = 1); void ev_tally(int, int, int, int, int, int, double, double *, double *, double *, double, double, double, double, double, double, double, double, double); diff --git a/src/kspace.h b/src/kspace.h index 12cb16c929..2345cebf24 100644 --- a/src/kspace.h +++ b/src/kspace.h @@ -194,11 +194,11 @@ class KSpace : protected Pointers { int kx_ewald,ky_ewald,kz_ewald; // kspace settings for Ewald sum void pair_check(); - void ev_setup(int, int, int alloc = 1); void ev_init(int eflag, int vflag, int alloc = 1) { if (eflag||vflag) ev_setup(eflag, vflag, alloc); else evflag = eflag_either = eflag_global = eflag_atom = vflag_either = vflag_global = vflag_atom = 0; } + void ev_setup(int, int, int alloc = 1); double estimate_table_accuracy(double, double); }; diff --git a/src/pair.h b/src/pair.h index 37606ed595..5ce62f1b35 100644 --- a/src/pair.h +++ b/src/pair.h @@ -218,12 +218,12 @@ class Pair : protected Pointers { int copymode; // if set, do not deallocate during destruction // required when classes are used as functors by Kokkos - virtual void ev_setup(int, int, int alloc = 1); - void ev_unset(); void ev_init(int eflag, int vflag, int alloc = 1) { if (eflag||vflag) ev_setup(eflag, vflag, alloc); else ev_unset(); } + virtual void ev_setup(int, int, int alloc = 1); + void ev_unset(); void ev_tally_full(int, double, double, double, double, double, double); void ev_tally_xyz_full(int, double, double, double, double, double, double, double, double); -- GitLab From a89a2de9d4a9912aaa5f50feed6e2e020c5cfee4 Mon Sep 17 00:00:00 2001 From: mkanski Date: Mon, 25 Mar 2019 16:45:59 +0100 Subject: [PATCH 0303/1243] Removed unnecessary MPI_comm --- src/USER-REAXC/pair_reaxc.cpp | 16 +-- src/USER-REAXC/reaxc_allocate.cpp | 159 +++++++++++++------------- src/USER-REAXC/reaxc_allocate.h | 11 +- src/USER-REAXC/reaxc_control.cpp | 1 - src/USER-REAXC/reaxc_control.h | 3 - src/USER-REAXC/reaxc_ffield.cpp | 57 ++++----- src/USER-REAXC/reaxc_forces.cpp | 12 +- src/USER-REAXC/reaxc_forces.h | 2 +- src/USER-REAXC/reaxc_init_md.cpp | 20 ++-- src/USER-REAXC/reaxc_init_md.h | 2 - src/USER-REAXC/reaxc_list.cpp | 22 ++-- src/USER-REAXC/reaxc_list.h | 4 +- src/USER-REAXC/reaxc_lookup.cpp | 74 +++++------- src/USER-REAXC/reaxc_lookup.h | 6 +- src/USER-REAXC/reaxc_reset_tools.cpp | 15 ++- src/USER-REAXC/reaxc_reset_tools.h | 4 +- src/USER-REAXC/reaxc_tool_box.cpp | 4 +- src/USER-REAXC/reaxc_tool_box.h | 4 +- src/USER-REAXC/reaxc_traj.cpp | 15 ++- src/USER-REAXC/reaxc_valence_angles.h | 2 +- 20 files changed, 192 insertions(+), 241 deletions(-) diff --git a/src/USER-REAXC/pair_reaxc.cpp b/src/USER-REAXC/pair_reaxc.cpp index a9501dac9d..8b36019881 100644 --- a/src/USER-REAXC/pair_reaxc.cpp +++ b/src/USER-REAXC/pair_reaxc.cpp @@ -141,10 +141,10 @@ PairReaxC::~PairReaxC() if (control->tabulate ) Deallocate_Lookup_Tables( system); - if (control->hbond_cut > 0 ) Delete_List( lists+HBONDS, world); - Delete_List( lists+BONDS, world ); - Delete_List( lists+THREE_BODIES, world ); - Delete_List( lists+FAR_NBRS, world ); + if (control->hbond_cut > 0 ) Delete_List( lists+HBONDS ); + Delete_List( lists+BONDS ); + Delete_List( lists+THREE_BODIES ); + Delete_List( lists+FAR_NBRS ); DeAllocate_Workspace( control, workspace ); DeAllocate_System( system ); @@ -439,12 +439,12 @@ void PairReaxC::setup( ) // initialize my data structures - PreAllocate_Space( system, control, workspace, world ); + PreAllocate_Space( system, control, workspace ); write_reax_atoms(); int num_nbrs = estimate_reax_lists(); if(!Make_List(system->total_cap, num_nbrs, TYP_FAR_NEIGHBOR, - lists+FAR_NBRS, world)) + lists+FAR_NBRS)) error->one(FLERR,"Pair reax/c problem in far neighbor list"); (lists+FAR_NBRS)->error_ptr=lmp->error; @@ -469,7 +469,7 @@ void PairReaxC::setup( ) // check if I need to shrink/extend my data-structs - ReAllocate( system, control, data, workspace, &lists, mpi_data ); + ReAllocate( system, control, data, workspace, &lists ); } bigint local_ngroup = list->inum; @@ -521,7 +521,7 @@ void PairReaxC::compute(int eflag, int vflag) setup(); - Reset( system, control, data, workspace, &lists, world ); + Reset( system, control, data, workspace, &lists ); workspace->realloc.num_far = write_reax_lists(); // timing for filling in the reax lists if (comm->me == 0) { diff --git a/src/USER-REAXC/reaxc_allocate.cpp b/src/USER-REAXC/reaxc_allocate.cpp index 8784c854b5..7649c110ef 100644 --- a/src/USER-REAXC/reaxc_allocate.cpp +++ b/src/USER-REAXC/reaxc_allocate.cpp @@ -44,7 +44,7 @@ using namespace LAMMPS_NS; process's box throughout the whole simulation. therefore we need to make upper bound estimates for various data structures */ int PreAllocate_Space( reax_system *system, control_params * /*control*/, - storage * workspace, MPI_Comm comm ) + storage * workspace ) { int mincap = system->mincap; double safezone = system->safezone; @@ -55,7 +55,7 @@ int PreAllocate_Space( reax_system *system, control_params * /*control*/, system->total_cap = MAX( (int)(system->N * safezone), mincap ); system->my_atoms = (reax_atom*) - scalloc(system->error_ptr, system->total_cap, sizeof(reax_atom), "my_atoms", comm ); + scalloc(system->error_ptr, system->total_cap, sizeof(reax_atom), "my_atoms"); // Nullify some arrays only used in omp styles // Should be safe to do here since called in pair->setup(); @@ -212,7 +212,7 @@ void DeAllocate_Workspace( control_params * control, storage *workspace ) int Allocate_Workspace( reax_system * /*system*/, control_params * control, storage *workspace, int local_cap, int total_cap, - MPI_Comm comm, char * /*msg*/ ) + char * /*msg*/ ) { int i, total_real, total_rvec, local_rvec; @@ -224,84 +224,84 @@ int Allocate_Workspace( reax_system * /*system*/, control_params * control, /* communication storage */ for( i = 0; i < MAX_NBRS; ++i ) { workspace->tmp_dbl[i] = (double*) - scalloc(control->error_ptr, total_cap, sizeof(double), "tmp_dbl", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "tmp_dbl"); workspace->tmp_rvec[i] = (rvec*) - scalloc(control->error_ptr, total_cap, sizeof(rvec), "tmp_rvec", comm ); + scalloc(control->error_ptr, total_cap, sizeof(rvec), "tmp_rvec"); workspace->tmp_rvec2[i] = (rvec2*) - scalloc(control->error_ptr, total_cap, sizeof(rvec2), "tmp_rvec2", comm ); + scalloc(control->error_ptr, total_cap, sizeof(rvec2), "tmp_rvec2"); } /* bond order related storage */ workspace->within_bond_box = (int*) - scalloc(control->error_ptr, total_cap, sizeof(int), "skin", comm ); - workspace->total_bond_order = (double*) smalloc(control->error_ptr, total_real, "total_bo", comm ); - workspace->Deltap = (double*) smalloc(control->error_ptr, total_real, "Deltap", comm ); - workspace->Deltap_boc = (double*) smalloc(control->error_ptr, total_real, "Deltap_boc", comm ); - workspace->dDeltap_self = (rvec*) smalloc(control->error_ptr, total_rvec, "dDeltap_self", comm ); - workspace->Delta = (double*) smalloc(control->error_ptr, total_real, "Delta", comm ); - workspace->Delta_lp = (double*) smalloc(control->error_ptr, total_real, "Delta_lp", comm ); + scalloc(control->error_ptr, total_cap, sizeof(int), "skin"); + workspace->total_bond_order = (double*) smalloc(control->error_ptr, total_real, "total_bo"); + workspace->Deltap = (double*) smalloc(control->error_ptr, total_real, "Deltap"); + workspace->Deltap_boc = (double*) smalloc(control->error_ptr, total_real, "Deltap_boc"); + workspace->dDeltap_self = (rvec*) smalloc(control->error_ptr, total_rvec, "dDeltap_self"); + workspace->Delta = (double*) smalloc(control->error_ptr, total_real, "Delta"); + workspace->Delta_lp = (double*) smalloc(control->error_ptr, total_real, "Delta_lp"); workspace->Delta_lp_temp = (double*) - smalloc(control->error_ptr, total_real, "Delta_lp_temp", comm ); - workspace->dDelta_lp = (double*) smalloc(control->error_ptr, total_real, "dDelta_lp", comm ); + smalloc(control->error_ptr, total_real, "Delta_lp_temp"); + workspace->dDelta_lp = (double*) smalloc(control->error_ptr, total_real, "dDelta_lp"); workspace->dDelta_lp_temp = (double*) - smalloc(control->error_ptr, total_real, "dDelta_lp_temp", comm ); - workspace->Delta_e = (double*) smalloc(control->error_ptr, total_real, "Delta_e", comm ); - workspace->Delta_boc = (double*) smalloc(control->error_ptr, total_real, "Delta_boc", comm ); - workspace->Delta_val = (double*) smalloc(control->error_ptr, total_real, "Delta_val", comm ); - workspace->nlp = (double*) smalloc(control->error_ptr, total_real, "nlp", comm ); - workspace->nlp_temp = (double*) smalloc(control->error_ptr, total_real, "nlp_temp", comm ); - workspace->Clp = (double*) smalloc(control->error_ptr, total_real, "Clp", comm ); - workspace->vlpex = (double*) smalloc(control->error_ptr, total_real, "vlpex", comm ); + smalloc(control->error_ptr, total_real, "dDelta_lp_temp"); + workspace->Delta_e = (double*) smalloc(control->error_ptr, total_real, "Delta_e"); + workspace->Delta_boc = (double*) smalloc(control->error_ptr, total_real, "Delta_boc"); + workspace->Delta_val = (double*) smalloc(control->error_ptr, total_real, "Delta_val"); + workspace->nlp = (double*) smalloc(control->error_ptr, total_real, "nlp"); + workspace->nlp_temp = (double*) smalloc(control->error_ptr, total_real, "nlp_temp"); + workspace->Clp = (double*) smalloc(control->error_ptr, total_real, "Clp"); + workspace->vlpex = (double*) smalloc(control->error_ptr, total_real, "vlpex"); workspace->bond_mark = (int*) - scalloc(control->error_ptr, total_cap, sizeof(int), "bond_mark", comm ); + scalloc(control->error_ptr, total_cap, sizeof(int), "bond_mark"); workspace->done_after = (int*) - scalloc(control->error_ptr, total_cap, sizeof(int), "done_after", comm ); + scalloc(control->error_ptr, total_cap, sizeof(int), "done_after"); /* QEq storage */ workspace->Hdia_inv = (double*) - scalloc(control->error_ptr, total_cap, sizeof(double), "Hdia_inv", comm ); - workspace->b_s = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_s", comm ); - workspace->b_t = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_t", comm ); - workspace->b_prc = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_prc", comm ); - workspace->b_prm = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_prm", comm ); - workspace->s = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "s", comm ); - workspace->t = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "t", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "Hdia_inv"); + workspace->b_s = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_s"); + workspace->b_t = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_t"); + workspace->b_prc = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_prc"); + workspace->b_prm = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "b_prm"); + workspace->s = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "s"); + workspace->t = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "t"); workspace->droptol = (double*) - scalloc(control->error_ptr, total_cap, sizeof(double), "droptol", comm ); - workspace->b = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "b", comm ); - workspace->x = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "x", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "droptol"); + workspace->b = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "b"); + workspace->x = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "x"); /* GMRES storage */ - workspace->y = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "y", comm ); - workspace->z = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "z", comm ); - workspace->g = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "g", comm ); - workspace->h = (double**) scalloc(control->error_ptr, RESTART+1, sizeof(double*), "h", comm ); - workspace->hs = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "hs", comm ); - workspace->hc = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "hc", comm ); - workspace->v = (double**) scalloc(control->error_ptr, RESTART+1, sizeof(double*), "v", comm ); + workspace->y = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "y"); + workspace->z = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "z"); + workspace->g = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "g"); + workspace->h = (double**) scalloc(control->error_ptr, RESTART+1, sizeof(double*), "h"); + workspace->hs = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "hs"); + workspace->hc = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "hc"); + workspace->v = (double**) scalloc(control->error_ptr, RESTART+1, sizeof(double*), "v"); for( i = 0; i < RESTART+1; ++i ) { - workspace->h[i] = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "h[i]", comm ); - workspace->v[i] = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "v[i]", comm ); + workspace->h[i] = (double*) scalloc(control->error_ptr, RESTART+1, sizeof(double), "h[i]"); + workspace->v[i] = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "v[i]"); } /* CG storage */ - workspace->r = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "r", comm ); - workspace->d = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "d", comm ); - workspace->q = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "q", comm ); - workspace->p = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "p", comm ); - workspace->r2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "r2", comm ); - workspace->d2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "d2", comm ); - workspace->q2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "q2", comm ); - workspace->p2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "p2", comm ); + workspace->r = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "r"); + workspace->d = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "d"); + workspace->q = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "q"); + workspace->p = (double*) scalloc(control->error_ptr, total_cap, sizeof(double), "p"); + workspace->r2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "r2"); + workspace->d2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "d2"); + workspace->q2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "q2"); + workspace->p2 = (rvec2*) scalloc(control->error_ptr, total_cap, sizeof(rvec2), "p2"); /* integrator storage */ - workspace->v_const = (rvec*) smalloc(control->error_ptr, local_rvec, "v_const", comm ); + workspace->v_const = (rvec*) smalloc(control->error_ptr, local_rvec, "v_const"); /* force related storage */ - workspace->f = (rvec*) scalloc(control->error_ptr, total_cap, sizeof(rvec), "f", comm ); + workspace->f = (rvec*) scalloc(control->error_ptr, total_cap, sizeof(rvec), "f"); workspace->CdDelta = (double*) - scalloc(control->error_ptr, total_cap, sizeof(double), "CdDelta", comm ); + scalloc(control->error_ptr, total_cap, sizeof(double), "CdDelta"); // storage for reductions with multiple threads #ifdef LMP_USER_OMP @@ -322,17 +322,16 @@ int Allocate_Workspace( reax_system * /*system*/, control_params * control, static void Reallocate_Neighbor_List( reax_list *far_nbrs, int n, - int num_intrs, MPI_Comm comm ) + int num_intrs ) { - Delete_List( far_nbrs, comm ); - if(!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs, comm )){ + Delete_List( far_nbrs); + if(!Make_List( n, num_intrs, TYP_FAR_NEIGHBOR, far_nbrs )){ far_nbrs->error_ptr->one(FLERR,"Problem in initializing far neighbors list"); } } -static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, - MPI_Comm comm ) +static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds ) { int i, total_hbonds; @@ -346,8 +345,8 @@ static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, } total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS )); - Delete_List( hbonds, comm ); - if (!Make_List( system->Hcap, total_hbonds, TYP_HBOND, hbonds, comm )) { + Delete_List( hbonds); + if (!Make_List( system->Hcap, total_hbonds, TYP_HBOND, hbonds )) { hbonds->error_ptr->one(FLERR, "Not enough space for hydrogen bonds list"); } @@ -356,8 +355,7 @@ static int Reallocate_HBonds_List( reax_system *system, reax_list *hbonds, static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, - int *total_bonds, int *est_3body, - MPI_Comm comm ) + int *total_bonds, int *est_3body ) { int i; @@ -378,8 +376,8 @@ static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, sfree(system->error_ptr, bonds->select.bond_list[i].bo_data.CdboReduction, "CdboReduction"); #endif - Delete_List( bonds, comm ); - if(!Make_List(system->total_cap, *total_bonds, TYP_BOND, bonds, comm)) { + Delete_List( bonds); + if(!Make_List(system->total_cap, *total_bonds, TYP_BOND, bonds)) { bonds->error_ptr->one(FLERR, "Not enough space for bonds list"); } @@ -401,14 +399,12 @@ static int Reallocate_Bonds_List( reax_system *system, reax_list *bonds, void ReAllocate( reax_system *system, control_params *control, - simulation_data *data, storage *workspace, reax_list **lists, - mpi_datatypes *mpi_data ) + simulation_data *data, storage *workspace, reax_list **lists ) { int num_bonds, est_3body, Hflag, ret; int renbr, newsize; reallocate_data *realloc; reax_list *far_nbrs; - MPI_Comm comm; char msg[200]; int mincap = system->mincap; @@ -416,7 +412,6 @@ void ReAllocate( reax_system *system, control_params *control, double saferzone = system->saferzone; realloc = &(workspace->realloc); - comm = mpi_data->world; if( system->n >= DANGER_ZONE * system->local_cap || (0 && system->n <= LOOSE_ZONE * system->local_cap) ) { @@ -434,18 +429,18 @@ void ReAllocate( reax_system *system, control_params *control, /* system */ ret = Allocate_System( system, system->local_cap, system->total_cap, msg ); if (ret != SUCCESS) { - char errmsg[128]; - snprintf(errmsg, 128, "Not enough space for atom_list: total_cap=%d", system->total_cap); + char errmsg[256]; + snprintf(errmsg, 256, "Not enough space for atom_list: total_cap=%d", system->total_cap); system->error_ptr->one(FLERR, errmsg); } /* workspace */ DeAllocate_Workspace( control, workspace ); ret = Allocate_Workspace( system, control, workspace, system->local_cap, - system->total_cap, comm, msg ); + system->total_cap, msg ); if (ret != SUCCESS) { - char errmsg[128]; - snprintf(errmsg, 128, "Not enough space for workspace: local_cap=%d total_cap=%d", system->local_cap, system->total_cap); + char errmsg[256]; + snprintf(errmsg, 256, "Not enough space for workspace: local_cap=%d total_cap=%d", system->local_cap, system->total_cap); system->error_ptr->one(FLERR, errmsg); } } @@ -458,15 +453,15 @@ void ReAllocate( reax_system *system, control_params *control, if (Nflag || realloc->num_far >= far_nbrs->num_intrs * DANGER_ZONE) { if (realloc->num_far > far_nbrs->num_intrs) { - char errmsg[128]; - snprintf(errmsg, 128, "step%d-ran out of space on far_nbrs: top=%d, max=%d", data->step, realloc->num_far, far_nbrs->num_intrs); + char errmsg[256]; + snprintf(errmsg, 256, "step%d-ran out of space on far_nbrs: top=%d, max=%d", data->step, realloc->num_far, far_nbrs->num_intrs); system->error_ptr->one(FLERR, errmsg); } newsize = static_cast (MAX( realloc->num_far*safezone, mincap*MIN_NBRS )); - Reallocate_Neighbor_List( far_nbrs, system->total_cap, newsize, comm ); + Reallocate_Neighbor_List( far_nbrs, system->total_cap, newsize); realloc->num_far = 0; } } @@ -481,7 +476,7 @@ void ReAllocate( reax_system *system, control_params *control, } if (Hflag || realloc->hbonds) { - ret = Reallocate_HBonds_List( system, (*lists)+HBONDS, comm ); + ret = Reallocate_HBonds_List( system, (*lists)+HBONDS); realloc->hbonds = 0; } } @@ -490,14 +485,14 @@ void ReAllocate( reax_system *system, control_params *control, num_bonds = est_3body = -1; if (Nflag || realloc->bonds) { Reallocate_Bonds_List( system, (*lists)+BONDS, &num_bonds, - &est_3body, comm ); + &est_3body); realloc->bonds = 0; realloc->num_3body = MAX( realloc->num_3body, est_3body ) * 2; } /* 3-body list */ if (realloc->num_3body > 0) { - Delete_List( (*lists)+THREE_BODIES, comm ); + Delete_List( (*lists)+THREE_BODIES); if (num_bonds == -1) num_bonds = ((*lists)+BONDS)->num_intrs; @@ -505,7 +500,7 @@ void ReAllocate( reax_system *system, control_params *control, realloc->num_3body = (int)(MAX(realloc->num_3body*safezone, MIN_3BODIES)); if( !Make_List( num_bonds, realloc->num_3body, TYP_THREE_BODY, - (*lists)+THREE_BODIES, comm ) ) { + (*lists)+THREE_BODIES ) ) { system->error_ptr->one(FLERR, "Problem in initializing angles list"); } realloc->num_3body = -1; diff --git a/src/USER-REAXC/reaxc_allocate.h b/src/USER-REAXC/reaxc_allocate.h index f813204006..be203340f6 100644 --- a/src/USER-REAXC/reaxc_allocate.h +++ b/src/USER-REAXC/reaxc_allocate.h @@ -28,20 +28,15 @@ #define __ALLOCATE_H_ #include "reaxc_types.h" - -#include "lammps.h" -#include "error.h" -using namespace LAMMPS_NS; - -int PreAllocate_Space( reax_system*, control_params*, storage*, MPI_Comm ); +int PreAllocate_Space( reax_system*, control_params*, storage* ); int Allocate_System( reax_system*, int, int, char* ); void DeAllocate_System( reax_system* ); int Allocate_Workspace( reax_system*, control_params*, storage*, - int, int, MPI_Comm, char* ); + int, int, char* ); void DeAllocate_Workspace( control_params*, storage* ); void ReAllocate( reax_system*, control_params*, simulation_data*, storage*, - reax_list**, mpi_datatypes* ); + reax_list** ); #endif diff --git a/src/USER-REAXC/reaxc_control.cpp b/src/USER-REAXC/reaxc_control.cpp index 14b28615fb..0caae40156 100644 --- a/src/USER-REAXC/reaxc_control.cpp +++ b/src/USER-REAXC/reaxc_control.cpp @@ -28,7 +28,6 @@ #include "reaxc_control.h" #include "reaxc_tool_box.h" - char Read_Control_File( char *control_file, control_params* control, output_controls *out_control ) { diff --git a/src/USER-REAXC/reaxc_control.h b/src/USER-REAXC/reaxc_control.h index 47627aed61..b2b455d6b8 100644 --- a/src/USER-REAXC/reaxc_control.h +++ b/src/USER-REAXC/reaxc_control.h @@ -29,9 +29,6 @@ #include "reaxc_types.h" -#include "lammps.h" -#include "error.h" - char Read_Control_File( char*, control_params*, output_controls* ); #endif diff --git a/src/USER-REAXC/reaxc_ffield.cpp b/src/USER-REAXC/reaxc_ffield.cpp index 987a11d252..28bc0429cc 100644 --- a/src/USER-REAXC/reaxc_ffield.cpp +++ b/src/USER-REAXC/reaxc_ffield.cpp @@ -44,7 +44,6 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, double val; MPI_Comm comm; int me; - comm = MPI_COMM_WORLD; MPI_Comm_rank(comm, &me); @@ -99,55 +98,45 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Allocating structures in reax_interaction */ reax->sbp = (single_body_parameters*) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(single_body_parameters), "sbp", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(single_body_parameters), "sbp"); reax->tbp = (two_body_parameters**) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(two_body_parameters*), "tbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(two_body_parameters*), "tbp"); reax->thbp= (three_body_header***) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header**), "thbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header**), "thbp"); reax->hbp = (hbond_parameters***) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters**), "hbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters**), "hbp"); reax->fbp = (four_body_header****) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header***), "fbp", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header***), "fbp"); tor_flag = (char****) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(char***), "tor_flag", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char***), "tor_flag"); for( i = 0; i < reax->num_atom_types; i++ ) { reax->tbp[i] = (two_body_parameters*) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(two_body_parameters), "tbp[i]"); reax->thbp[i]= (three_body_header**) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header*), "thbp[i]"); reax->hbp[i] = (hbond_parameters**) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters*), "hbp[i]"); reax->fbp[i] = (four_body_header***) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header**), "fbp[i]"); tor_flag[i] = (char***) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(char**), "tor_flag[i]", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char**), "tor_flag[i]"); for( j = 0; j < reax->num_atom_types; j++ ) { reax->thbp[i][j]= (three_body_header*) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(three_body_header), "thbp[i,j]"); reax->hbp[i][j] = (hbond_parameters*) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(hbond_parameters), "hbp[i,j]"); reax->fbp[i][j] = (four_body_header**) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header*), "fbp[i,j]"); tor_flag[i][j] = (char**) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]", comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char*), "tor_flag[i,j]"); for (k=0; k < reax->num_atom_types; k++) { reax->fbp[i][j][k] = (four_body_header*) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(four_body_header), "fbp[i,j,k]"); tor_flag[i][j][k] = (char*) - scalloc(control->error_ptr, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]", - comm ); + scalloc(control->error_ptr, reax->num_atom_types, sizeof(char), "tor_flag[i,j,k]"); } } } @@ -163,7 +152,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity checks */ if (c < 9) { - control->error_ptr->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->all(FLERR,"Inconsistent ffield file"); } for( j = 0; j < (int)(strlen(tmp[0])); ++j ) @@ -185,7 +174,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - control->error_ptr->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->all(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].alpha = val; @@ -203,7 +192,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - control->error_ptr->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->all(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].r_pi_pi = val; @@ -221,7 +210,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c < 8) { - control->error_ptr->one(FLERR,"Inconsistent ffield file"); + control->error_ptr->all(FLERR,"Inconsistent ffield file"); } val = atof(tmp[0]); reax->sbp[i].p_ovun2 = val; @@ -240,7 +229,7 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, /* Sanity check */ if (c > 2) { - control->error_ptr->one(FLERR,"Force field file incompatible with 'lgvdw yes'"); + control->error_ptr->all(FLERR,"Force field file incompatible with 'lgvdw yes'"); } val = atof(tmp[0]); reax->sbp[i].lgcij = val; @@ -337,8 +326,6 @@ char Read_Force_Field( FILE *fp, reax_interaction *reax, fgets(s,MAX_LINE,fp); c=Tokenize(s,&tmp); - - j = atoi(tmp[0]) - 1; k = atoi(tmp[1]) - 1; diff --git a/src/USER-REAXC/reaxc_forces.cpp b/src/USER-REAXC/reaxc_forces.cpp index ff1dd839fb..afe9a059ed 100644 --- a/src/USER-REAXC/reaxc_forces.cpp +++ b/src/USER-REAXC/reaxc_forces.cpp @@ -116,7 +116,7 @@ void Compute_Total_Force( reax_system *system, control_params *control, } void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **lists, - int step, int /*n*/, int N, int numH, MPI_Comm comm ) + int step, int /*n*/, int N, int numH ) { int i, comp, Hindex; reax_list *bonds, *hbonds; @@ -176,8 +176,7 @@ void Validate_Lists( reax_system *system, storage * /*workspace*/, reax_list **l void Init_Forces_noQEq( reax_system *system, control_params *control, simulation_data *data, storage *workspace, - reax_list **lists, output_controls * /*out_control*/, - MPI_Comm comm ) { + reax_list **lists, output_controls * /*out_control*/ ) { int i, j, pj; int start_i, end_i; int type_i, type_j; @@ -311,13 +310,13 @@ void Init_Forces_noQEq( reax_system *system, control_params *control, workspace->realloc.num_hbonds = num_hbonds; Validate_Lists( system, workspace, lists, data->step, - system->n, system->N, system->numH, comm ); + system->n, system->N, system->numH); } void Estimate_Storages( reax_system *system, control_params *control, reax_list **lists, int *Htop, int *hb_top, - int *bond_top, int *num_3body, MPI_Comm /*comm*/ ) + int *bond_top, int *num_3body ) { int i, j, pj; int start_i, end_i; @@ -439,10 +438,9 @@ void Compute_Forces( reax_system *system, control_params *control, reax_list **lists, output_controls *out_control, mpi_datatypes *mpi_data ) { - MPI_Comm comm = mpi_data->world; Init_Forces_noQEq( system, control, data, workspace, - lists, out_control, comm ); + lists, out_control); /********* bonded interactions ************/ Compute_Bonded_Forces( system, control, data, workspace, diff --git a/src/USER-REAXC/reaxc_forces.h b/src/USER-REAXC/reaxc_forces.h index 6c839a7023..bfad2e9b71 100644 --- a/src/USER-REAXC/reaxc_forces.h +++ b/src/USER-REAXC/reaxc_forces.h @@ -36,5 +36,5 @@ void Init_Force_Functions( control_params* ); void Compute_Forces( reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes* ); void Estimate_Storages( reax_system*, control_params*, reax_list**, - int*, int*, int*, int*, MPI_Comm ); + int*, int*, int*, int* ); #endif diff --git a/src/USER-REAXC/reaxc_init_md.cpp b/src/USER-REAXC/reaxc_init_md.cpp index 27e60c580c..913bc241de 100644 --- a/src/USER-REAXC/reaxc_init_md.cpp +++ b/src/USER-REAXC/reaxc_init_md.cpp @@ -81,7 +81,7 @@ int Init_Simulation_Data( reax_system *system, control_params *control, return SUCCESS; } -void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) +void Init_Taper( control_params *control, storage *workspace ) { double d1, d7; double swa, swa2, swa3; @@ -122,12 +122,12 @@ void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) int Init_Workspace( reax_system *system, control_params *control, - storage *workspace, MPI_Comm comm, char *msg ) + storage *workspace, char *msg ) { int ret; ret = Allocate_Workspace( system, control, workspace, - system->local_cap, system->total_cap, comm, msg ); + system->local_cap, system->total_cap, msg ); if (ret != SUCCESS) return ret; @@ -135,7 +135,7 @@ int Init_Workspace( reax_system *system, control_params *control, Reset_Workspace( system, workspace ); /* Initialize the Taper function */ - Init_Taper( control, workspace, comm ); + Init_Taper( control, workspace); return SUCCESS; } @@ -159,17 +159,15 @@ int Init_Lists( reax_system *system, control_params *control, { int i, total_hbonds, total_bonds, bond_cap, num_3body, cap_3body, Htop; int *hb_top, *bond_top; - MPI_Comm comm; int mincap = system->mincap; double safezone = system->safezone; double saferzone = system->saferzone; - comm = mpi_data->world; bond_top = (int*) calloc( system->total_cap, sizeof(int) ); hb_top = (int*) calloc( system->local_cap, sizeof(int) ); Estimate_Storages( system, control, lists, - &Htop, hb_top, bond_top, &num_3body, comm ); + &Htop, hb_top, bond_top, &num_3body); if (control->hbond_cut > 0) { /* init H indexes */ @@ -181,7 +179,7 @@ int Init_Lists( reax_system *system, control_params *control, total_hbonds = (int)(MAX( total_hbonds*saferzone, mincap*MIN_HBONDS )); if( !Make_List( system->Hcap, total_hbonds, TYP_HBOND, - *lists+HBONDS, comm ) ) { + *lists+HBONDS ) ) { control->error_ptr->one(FLERR, "Not enough space for hbonds list."); } (*lists+HBONDS)->error_ptr = system->error_ptr; @@ -195,7 +193,7 @@ int Init_Lists( reax_system *system, control_params *control, bond_cap = (int)(MAX( total_bonds*safezone, mincap*MIN_BONDS )); if( !Make_List( system->total_cap, bond_cap, TYP_BOND, - *lists+BONDS, comm ) ) { + *lists+BONDS ) ) { control->error_ptr->one(FLERR, "Not enough space for bonds list."); } (*lists+BONDS)->error_ptr = system->error_ptr; @@ -203,7 +201,7 @@ int Init_Lists( reax_system *system, control_params *control, /* 3bodies list */ cap_3body = (int)(MAX( num_3body*safezone, MIN_3BODIES )); if( !Make_List( bond_cap, cap_3body, TYP_THREE_BODY, - *lists+THREE_BODIES, comm ) ){ + *lists+THREE_BODIES ) ){ control->error_ptr->one(FLERR,"Problem in initializing angles list."); } (*lists+THREE_BODIES)->error_ptr = system->error_ptr; @@ -242,7 +240,7 @@ void Initialize( reax_system *system, control_params *control, control->error_ptr->one(FLERR,errmsg); } - if (Init_Workspace( system, control, workspace, mpi_data->world, msg ) == + if (Init_Workspace( system, control, workspace, msg ) == FAILURE) { snprintf(errmsg, 128, "Workspace could not be initialized on thread %d", system->my_rank); diff --git a/src/USER-REAXC/reaxc_init_md.h b/src/USER-REAXC/reaxc_init_md.h index 546a9e33c9..ab519a4c72 100644 --- a/src/USER-REAXC/reaxc_init_md.h +++ b/src/USER-REAXC/reaxc_init_md.h @@ -29,8 +29,6 @@ #include "reaxc_types.h" -#include "lammps.h" -#include "error.h" void Initialize( reax_system*, control_params*, simulation_data*, storage*, reax_list**, output_controls*, mpi_datatypes*, MPI_Comm ); diff --git a/src/USER-REAXC/reaxc_list.cpp b/src/USER-REAXC/reaxc_list.cpp index f103e520e8..d0143ec9ae 100644 --- a/src/USER-REAXC/reaxc_list.cpp +++ b/src/USER-REAXC/reaxc_list.cpp @@ -29,7 +29,7 @@ #include "reaxc_tool_box.h" /************* allocate list space ******************/ -int Make_List( int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) +int Make_List(int n, int num_intrs, int type, reax_list *l ) { l->allocated = 1; @@ -38,52 +38,52 @@ int Make_List( int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) if (l->index) sfree(l->error_ptr, l->index, "list:index"); if (l->end_index) sfree(l->error_ptr, l->end_index, "list:end_index"); - l->index = (int*) smalloc(l->error_ptr, n * sizeof(int), "list:index", comm ); - l->end_index = (int*) smalloc(l->error_ptr, n * sizeof(int), "list:end_index", comm ); + l->index = (int*) smalloc(l->error_ptr, n * sizeof(int), "list:index"); + l->end_index = (int*) smalloc(l->error_ptr, n * sizeof(int), "list:end_index"); l->type = type; switch(l->type) { case TYP_VOID: if (l->select.v) sfree(l->error_ptr, l->select.v, "list:v"); - l->select.v = (void*) smalloc(l->error_ptr, l->num_intrs * sizeof(void*), "list:v", comm); + l->select.v = (void*) smalloc(l->error_ptr, l->num_intrs * sizeof(void*), "list:v"); break; case TYP_THREE_BODY: if (l->select.three_body_list) sfree(l->error_ptr, l->select.three_body_list,"list:three_bodies"); l->select.three_body_list = (three_body_interaction_data*) smalloc(l->error_ptr, l->num_intrs * sizeof(three_body_interaction_data), - "list:three_bodies", comm ); + "list:three_bodies"); break; case TYP_BOND: if (l->select.bond_list) sfree(l->error_ptr, l->select.bond_list,"list:bonds"); l->select.bond_list = (bond_data*) - smalloc(l->error_ptr, l->num_intrs * sizeof(bond_data), "list:bonds", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(bond_data), "list:bonds"); break; case TYP_DBO: if (l->select.dbo_list) sfree(l->error_ptr, l->select.dbo_list,"list:dbonds"); l->select.dbo_list = (dbond_data*) - smalloc(l->error_ptr, l->num_intrs * sizeof(dbond_data), "list:dbonds", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(dbond_data), "list:dbonds"); break; case TYP_DDELTA: if (l->select.dDelta_list) sfree(l->error_ptr, l->select.dDelta_list,"list:dDeltas"); l->select.dDelta_list = (dDelta_data*) - smalloc(l->error_ptr, l->num_intrs * sizeof(dDelta_data), "list:dDeltas", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(dDelta_data), "list:dDeltas"); break; case TYP_FAR_NEIGHBOR: if (l->select.far_nbr_list) sfree(l->error_ptr, l->select.far_nbr_list,"list:far_nbrs"); l->select.far_nbr_list = (far_neighbor_data*) - smalloc(l->error_ptr, l->num_intrs * sizeof(far_neighbor_data), "list:far_nbrs", comm); + smalloc(l->error_ptr, l->num_intrs * sizeof(far_neighbor_data), "list:far_nbrs"); break; case TYP_HBOND: if (l->select.hbond_list) sfree(l->error_ptr, l->select.hbond_list,"list:hbonds"); l->select.hbond_list = (hbond_data*) - smalloc(l->error_ptr, l->num_intrs * sizeof(hbond_data), "list:hbonds", comm ); + smalloc(l->error_ptr, l->num_intrs * sizeof(hbond_data), "list:hbonds"); break; default: @@ -96,7 +96,7 @@ int Make_List( int n, int num_intrs, int type, reax_list *l, MPI_Comm comm) } -void Delete_List( reax_list *l, MPI_Comm comm ) +void Delete_List( reax_list *l ) { if (l->allocated == 0) return; diff --git a/src/USER-REAXC/reaxc_list.h b/src/USER-REAXC/reaxc_list.h index ab7fbce19c..28567252da 100644 --- a/src/USER-REAXC/reaxc_list.h +++ b/src/USER-REAXC/reaxc_list.h @@ -29,8 +29,8 @@ #include "reaxc_types.h" -int Make_List( int, int, int, reax_list*, MPI_Comm ); -void Delete_List( reax_list*, MPI_Comm ); +int Make_List( int, int, int, reax_list* ); +void Delete_List( reax_list* ); inline int Num_Entries(int,reax_list*); inline int Start_Index( int, reax_list* ); diff --git a/src/USER-REAXC/reaxc_lookup.cpp b/src/USER-REAXC/reaxc_lookup.cpp index b140b0cadf..74d8176522 100644 --- a/src/USER-REAXC/reaxc_lookup.cpp +++ b/src/USER-REAXC/reaxc_lookup.cpp @@ -51,18 +51,17 @@ void Tridiagonal_Solve( const double *a, const double *b, void Natural_Cubic_Spline( LAMMPS_NS::Error* error_ptr, const double *h, const double *f, - cubic_spline_coef *coef, unsigned int n, - MPI_Comm comm ) + cubic_spline_coef *coef, unsigned int n ) { int i; double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + b = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + c = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + d = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + v = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); /* build the linear system */ a[0] = a[1] = a[n-1] = 0; @@ -102,18 +101,17 @@ void Natural_Cubic_Spline( LAMMPS_NS::Error* error_ptr, const double *h, const d void Complete_Cubic_Spline( LAMMPS_NS::Error* error_ptr, const double *h, const double *f, double v0, double vlast, - cubic_spline_coef *coef, unsigned int n, - MPI_Comm comm ) + cubic_spline_coef *coef, unsigned int n ) { int i; double *a, *b, *c, *d, *v; /* allocate space for the linear system */ - a = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - b = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - c = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - d = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); - v = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a", comm ); + a = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + b = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + c = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + d = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); + v = (double*) smalloc(error_ptr, n * sizeof(double), "cubic_spline:a"); /* build the linear system */ a[0] = 0; @@ -159,35 +157,33 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, double dr; double *h, *fh, *fvdw, *fele, *fCEvd, *fCEclmb; double v0_vdw, v0_ele, vlast_vdw, vlast_ele; - MPI_Comm comm; /* initializations */ v0_vdw = 0; v0_ele = 0; vlast_vdw = 0; vlast_ele = 0; - comm = mpi_data->world; num_atom_types = system->reax_param.num_atom_types; dr = control->nonb_cut / control->tabulate; h = (double*) - smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:h", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:h"); fh = (double*) - smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fh", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fh"); fvdw = (double*) - smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fvdw", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fvdw"); fCEvd = (double*) - smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fCEvd", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fCEvd"); fele = (double*) - smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fele", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fele"); fCEclmb = (double*) - smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb", comm ); + smalloc(system->error_ptr, (control->tabulate+2) * sizeof(double), "lookup:fCEclmb"); LR = (LR_lookup_table**) - scalloc(system->error_ptr, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR", comm ); + scalloc(system->error_ptr, num_atom_types, sizeof(LR_lookup_table*), "lookup:LR"); for( i = 0; i < num_atom_types; ++i ) LR[i] = (LR_lookup_table*) - scalloc(system->error_ptr, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]", comm ); + scalloc(system->error_ptr, num_atom_types, sizeof(LR_lookup_table), "lookup:LR[i]"); for( i = 0; i < MAX_ATOM_TYPES; ++i ) existing_types[i] = 0; @@ -207,22 +203,18 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, LR[i][j].dx = dr; LR[i][j].inv_dx = control->tabulate / control->nonb_cut; LR[i][j].y = (LR_data*) - smalloc(system->error_ptr, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y", comm ); + smalloc(system->error_ptr, LR[i][j].n * sizeof(LR_data), "lookup:LR[i,j].y"); LR[i][j].H = (cubic_spline_coef*) - smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H" , - comm ); + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].H"); LR[i][j].vdW = (cubic_spline_coef*) - smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW", - comm); + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].vdW"); LR[i][j].CEvd = (cubic_spline_coef*) - smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd", - comm); + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].CEvd"); LR[i][j].ele = (cubic_spline_coef*) - smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele", - comm ); + smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef),"lookup:LR[i,j].ele"); LR[i][j].CEclmb = (cubic_spline_coef*) smalloc(system->error_ptr, LR[i][j].n*sizeof(cubic_spline_coef), - "lookup:LR[i,j].CEclmb", comm ); + "lookup:LR[i,j].CEclmb"); for( r = 1; r <= control->tabulate; ++r ) { LR_vdW_Coulomb( system, workspace, control, i, j, r * dr, &(LR[i][j].y[r]) ); @@ -247,23 +239,19 @@ int Init_Lookup_Tables( reax_system *system, control_params *control, vlast_ele = fele[r-1]; Natural_Cubic_Spline( control->error_ptr, &h[1], &fh[1], - &(LR[i][j].H[1]), control->tabulate+1, comm ); + &(LR[i][j].H[1]), control->tabulate+1); Complete_Cubic_Spline( control->error_ptr, &h[1], &fvdw[1], v0_vdw, vlast_vdw, - &(LR[i][j].vdW[1]), control->tabulate+1, - comm ); + &(LR[i][j].vdW[1]), control->tabulate+1); Natural_Cubic_Spline( control->error_ptr, &h[1], &fCEvd[1], - &(LR[i][j].CEvd[1]), control->tabulate+1, - comm ); + &(LR[i][j].CEvd[1]), control->tabulate+1); Complete_Cubic_Spline( control->error_ptr, &h[1], &fele[1], v0_ele, vlast_ele, - &(LR[i][j].ele[1]), control->tabulate+1, - comm ); + &(LR[i][j].ele[1]), control->tabulate+1); Natural_Cubic_Spline( control->error_ptr, &h[1], &fCEclmb[1], - &(LR[i][j].CEclmb[1]), control->tabulate+1, - comm ); + &(LR[i][j].CEclmb[1]), control->tabulate+1); } else { LR[i][j].n = 0; } diff --git a/src/USER-REAXC/reaxc_lookup.h b/src/USER-REAXC/reaxc_lookup.h index 9b1b14a34d..6d6aae2f8e 100644 --- a/src/USER-REAXC/reaxc_lookup.h +++ b/src/USER-REAXC/reaxc_lookup.h @@ -33,12 +33,10 @@ void Tridiagonal_Solve( const double *a, const double *b, double *c, double *d, double *x, unsigned int n); void Natural_Cubic_Spline( LAMMPS_NS::LAMMPS*, const double *h, const double *f, - cubic_spline_coef *coef, unsigned int n, - MPI_Comm comm ); + cubic_spline_coef *coef, unsigned int n ); void Complete_Cubic_Spline( LAMMPS_NS::LAMMPS*, const double *h, const double *f, double v0, double vlast, - cubic_spline_coef *coef, unsigned int n, - MPI_Comm comm ); + cubic_spline_coef *coef, unsigned int n ); int Init_Lookup_Tables( reax_system*, control_params*, storage*, mpi_datatypes*, char* ); diff --git a/src/USER-REAXC/reaxc_reset_tools.cpp b/src/USER-REAXC/reaxc_reset_tools.cpp index d273a417f8..8954e344df 100644 --- a/src/USER-REAXC/reaxc_reset_tools.cpp +++ b/src/USER-REAXC/reaxc_reset_tools.cpp @@ -121,8 +121,7 @@ void Reset_Workspace( reax_system *system, storage *workspace ) void Reset_Neighbor_Lists( reax_system *system, control_params *control, - storage *workspace, reax_list **lists, - MPI_Comm comm ) + storage *workspace, reax_list **lists ) { int i, total_bonds, Hindex, total_hbonds; reax_list *bonds, *hbonds; @@ -144,8 +143,8 @@ void Reset_Neighbor_Lists( reax_system *system, control_params *control, workspace->realloc.bonds = 1; if (total_bonds >= bonds->num_intrs) { char errmsg[256]; - snprintf(errmsg, 256, "p%d: not enough space for bonds! total=%d allocated=%d\n", - system->my_rank, total_bonds, bonds->num_intrs); + snprintf(errmsg, 256, "Not enough space for bonds! total=%d allocated=%d\n", + total_bonds, bonds->num_intrs); control->error_ptr->one(FLERR, errmsg); } } @@ -170,8 +169,8 @@ void Reset_Neighbor_Lists( reax_system *system, control_params *control, workspace->realloc.hbonds = 1; if (total_hbonds >= hbonds->num_intrs) { char errmsg[256]; - snprintf(errmsg, 256, "p%d: not enough space for hbonds! total=%d allocated=%d\n", - system->my_rank, total_hbonds, hbonds->num_intrs); + snprintf(errmsg, 256, "Not enough space for hbonds! total=%d allocated=%d\n", + total_hbonds, hbonds->num_intrs); control->error_ptr->one(FLERR, errmsg); } } @@ -180,7 +179,7 @@ void Reset_Neighbor_Lists( reax_system *system, control_params *control, void Reset( reax_system *system, control_params *control, simulation_data *data, - storage *workspace, reax_list **lists, MPI_Comm comm ) + storage *workspace, reax_list **lists ) { Reset_Atoms( system, control ); @@ -188,6 +187,6 @@ void Reset( reax_system *system, control_params *control, simulation_data *data, Reset_Workspace( system, workspace ); - Reset_Neighbor_Lists( system, control, workspace, lists, comm ); + Reset_Neighbor_Lists( system, control, workspace, lists ); } diff --git a/src/USER-REAXC/reaxc_reset_tools.h b/src/USER-REAXC/reaxc_reset_tools.h index c2a90072d5..20d1ab6964 100644 --- a/src/USER-REAXC/reaxc_reset_tools.h +++ b/src/USER-REAXC/reaxc_reset_tools.h @@ -34,7 +34,7 @@ void Reset_Simulation_Data( simulation_data*, int ); void Reset_Timing( reax_timing* ); void Reset_Workspace( reax_system*, storage* ); void Reset_Neighbor_Lists( reax_system*, control_params*, storage*, - reax_list**, MPI_Comm ); + reax_list** ); void Reset( reax_system*, control_params*, simulation_data*, storage*, - reax_list**, MPI_Comm ); + reax_list** ); #endif diff --git a/src/USER-REAXC/reaxc_tool_box.cpp b/src/USER-REAXC/reaxc_tool_box.cpp index cd339af556..05ebc34c1b 100644 --- a/src/USER-REAXC/reaxc_tool_box.cpp +++ b/src/USER-REAXC/reaxc_tool_box.cpp @@ -56,7 +56,7 @@ int Tokenize( char* s, char*** tok ) /* safe malloc */ -void *smalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, const char *name, MPI_Comm comm ) +void *smalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, const char *name ) { void *ptr; char errmsg[256]; @@ -79,7 +79,7 @@ void *smalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, const char *name, MPI_C /* safe calloc */ -void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const char *name, MPI_Comm comm ) +void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const char *name ) { void *ptr; char errmsg[256]; diff --git a/src/USER-REAXC/reaxc_tool_box.h b/src/USER-REAXC/reaxc_tool_box.h index 257ff1813f..0465376dba 100644 --- a/src/USER-REAXC/reaxc_tool_box.h +++ b/src/USER-REAXC/reaxc_tool_box.h @@ -37,7 +37,7 @@ double Get_Time( ); int Tokenize( char*, char*** ); /* from lammps */ -void *smalloc( LAMMPS_NS::Error*, rc_bigint, const char*, MPI_Comm ); -void *scalloc( LAMMPS_NS::Error*, rc_bigint, rc_bigint, const char*, MPI_Comm ); +void *smalloc( LAMMPS_NS::Error*, rc_bigint, const char* ); +void *scalloc( LAMMPS_NS::Error*, rc_bigint, rc_bigint, const char* ); void sfree( LAMMPS_NS::Error*, void*, const char* ); #endif diff --git a/src/USER-REAXC/reaxc_traj.cpp b/src/USER-REAXC/reaxc_traj.cpp index 90f3d1e668..27bebb6327 100644 --- a/src/USER-REAXC/reaxc_traj.cpp +++ b/src/USER-REAXC/reaxc_traj.cpp @@ -29,8 +29,7 @@ #include "reaxc_list.h" #include "reaxc_tool_box.h" -int Reallocate_Output_Buffer( LAMMPS_NS::Error *error_ptr, output_controls *out_control, int req_space, - MPI_Comm comm ) +int Reallocate_Output_Buffer( LAMMPS_NS::Error *error_ptr, output_controls *out_control, int req_space ) { if (out_control->buffer_len > 0) free( out_control->buffer ); @@ -82,7 +81,7 @@ int Write_Header( reax_system *system, control_params *control, my_hdr_lines = num_hdr_lines * ( system->my_rank == MASTER_NODE ); buffer_req = my_hdr_lines * HEADER_LINE_LEN; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( control->error_ptr, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( control->error_ptr, out_control, buffer_req ); /* only the master node writes into trajectory header */ if (system->my_rank == MASTER_NODE) { @@ -277,7 +276,7 @@ int Write_Init_Desc( reax_system *system, control_params * /*control*/, else buffer_req = system->n * INIT_DESC_LEN + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req ); out_control->line[0] = 0; out_control->buffer[0] = 0; @@ -366,7 +365,7 @@ int Write_Frame_Header( reax_system *system, control_params *control, my_frm_hdr_lines = num_frm_hdr_lines * ( me == MASTER_NODE ); buffer_req = my_frm_hdr_lines * HEADER_LINE_LEN; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( control->error_ptr, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( control->error_ptr, out_control, buffer_req ); /* only the master node writes into trajectory header */ if (me == MASTER_NODE) { @@ -499,7 +498,7 @@ int Write_Atoms( reax_system *system, control_params * /*control*/, else buffer_req = system->n * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req ); /* fill in buffer */ out_control->line[0] = 0; @@ -589,7 +588,7 @@ int Write_Bonds(reax_system *system, control_params *control, reax_list *bonds, else buffer_req = my_bonds * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req ); /* fill in the buffer */ out_control->line[0] = 0; @@ -689,7 +688,7 @@ int Write_Angles( reax_system *system, control_params *control, else buffer_req = my_angles * line_len + 1; if (buffer_req > out_control->buffer_len * DANGER_ZONE) - Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req, mpi_data->world ); + Reallocate_Output_Buffer( system->error_ptr, out_control, buffer_req ); /* fill in the buffer */ my_angles = 0; diff --git a/src/USER-REAXC/reaxc_valence_angles.h b/src/USER-REAXC/reaxc_valence_angles.h index 51eac5a95e..31936ba190 100644 --- a/src/USER-REAXC/reaxc_valence_angles.h +++ b/src/USER-REAXC/reaxc_valence_angles.h @@ -30,7 +30,7 @@ #include "reaxc_types.h" void Valence_Angles( reax_system*, control_params*, simulation_data*, - storage*, reax_list**, output_controls*); + storage*, reax_list**, output_controls* ); void Calculate_Theta( rvec, double, rvec, double, double*, double* ); -- GitLab From e9384b6b173ebe00f76b5073ab51559f78177b08 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 25 Mar 2019 09:52:16 -0600 Subject: [PATCH 0304/1243] updating output files --- examples/hyper/global.10Oct18.000000.jpg | Bin 72470 -> 0 bytes examples/hyper/global.10Oct18.003000.jpg | Bin 71795 -> 0 bytes examples/hyper/global.10Oct18.038000.jpg | Bin 70395 -> 0 bytes examples/hyper/global.10Oct18.059000.jpg | Bin 71492 -> 0 bytes examples/hyper/local.10Oct18.000000.jpg | Bin 493761 -> 0 bytes examples/hyper/local.10Oct18.000700.jpg | Bin 490185 -> 0 bytes examples/hyper/local.10Oct18.000800.jpg | Bin 488885 -> 0 bytes examples/hyper/local.10Oct18.001100.jpg | Bin 490525 -> 0 bytes examples/hyper/log.10Oct18.hyper.global.g++.4 | 1243 ----------------- examples/hyper/log.10Oct18.hyper.local.g++.16 | 993 ------------- 10 files changed, 2236 deletions(-) delete mode 100644 examples/hyper/global.10Oct18.000000.jpg delete mode 100644 examples/hyper/global.10Oct18.003000.jpg delete mode 100644 examples/hyper/global.10Oct18.038000.jpg delete mode 100644 examples/hyper/global.10Oct18.059000.jpg delete mode 100644 examples/hyper/local.10Oct18.000000.jpg delete mode 100644 examples/hyper/local.10Oct18.000700.jpg delete mode 100644 examples/hyper/local.10Oct18.000800.jpg delete mode 100644 examples/hyper/local.10Oct18.001100.jpg delete mode 100644 examples/hyper/log.10Oct18.hyper.global.g++.4 delete mode 100644 examples/hyper/log.10Oct18.hyper.local.g++.16 diff --git a/examples/hyper/global.10Oct18.000000.jpg b/examples/hyper/global.10Oct18.000000.jpg deleted file mode 100644 index b462983f6a950954a8606f3cf4dfdbcc0ca6ff96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72470 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 N#@y?P-yAM~chyxQJ@ z9qzp((~jkmgH+wB3CYX!%Ij^eADp&p@5|av_wUaCop<=xwX;h3@dF^`G2IjLzJb9r^+xp89^~&)Id!Ja>MZ!a3abc~}Ux+vK|C#D591poKuKu5)vHp|0i$%4? zA??dY-0UV#`pJ`!>%1-EsOq!_m-4JH8s82~QvN{Aal1m;X<1pY6`8 z>q8#uuRH#Cd;P~%ld`R5_4InZ|M#E4{KvHq4}0ow9`me!5dUZ5)1(bQm)=?#Kl|Uk z$$u_>?{E8~{o(fEX@NIiY(JgJQhB54<7`Qlc@dMZ%(}dL>xbM+IXkX3uU~$v@XzXp zy5<2pep}Tp`}E4waGHHa;g5o>$MJFslzA2_q_ z?cE#y8Me3oXOKEKKYSlMXMLId+uilO76r$wqLUy&@7QtZxk>2K&Rzc*WcHuBvGWh%Cx-X=-2w8e~#w)-74AGFxz}FW#`*G%{JxJe@~Sw`{z;pUK`WNtg@-KHYF2xM zHPv2OTK`w&*P-VRuOHH$JoBEp{n!5t3jcgVmj3Ym;1|DNCjH-|AW&iY$@J`>({rbn zC;z)A|0mlhH#*?%r!4V=`s-!?8KidA8242tJ=qTmn&-z7KF_KOIdcEs{mFm%xBRjF zaQwmj_OGjJ(>*@DUH`UQV(GsN6Sut!THcn#&(h~w_BpnqC}Yn`8>cmM4WH}(2!DRA ze^r*ytBFg#UoUcEG}51UxTo;K^L5(G%*$?9WUu+paQ)8yKcS&M%?8WfeBAu|DX7qU z@T1)D*ug8k9;>ah)&Db`m>>VjPUJ`S3d8KvSEkI{|FXw^;+oEV;(w%OOjhXa{LiqW zW&WSgn#si#Ze=mC`hWMF{LgSSEcM#Tl9@NFVO32(@8h)p44}Z9T>r^EHD|N+VW;z= z%Tq1uCw?=L=laKe==P$BE6?pe2~PRX@aF5q7q{daOp5qsuT)_v`On~W_s_}oExM)I zm!5dmm(|+W-G3at&3wgy%FVI%fA@OWPY(5OH@tH9-*){!v;Q+pGCusY@|clKx6s;~ z=i;aK@7B|=u`Lvzs^2knvc&OOi+_b%uJ{rBaNUBV>-B?zs{S)9Gx+DW&$W8B?taak z?2rgwZT0HCvB_l}k2GuKywapFt(xzx8vC{$8&=$uBka|8DtpDZlkU z1KTo{6UsUN8Ll|_|I=FK{h|6n$^O?0pls{~DvO+UU3oXzT0ak5=UipKW@>mjaJT%o zoBNM#TYgyL@8h0H{}~SK|EYZL=)>ZapIO(R{b$&|0JN7Zw>oTi~jtZzCMoOQ1$JVd=-Cx z_t`TC`LDn8_29(ZPE(B=VSoPptiTPxj+lDL+%=m7b9=-)ilC@nv&u z+0TjYlI_p^3^wn&?rR$LXZuh2%9r~XfA}xAsJ2Y*Y*+ZZ^Ze(m*ExDM=E)pg*N<>Y z@fki_`7dc7$A&8@MK-5*FO&cJ>G7{?PxoG(=s)MK@au0U>wm2Jv-mf&tmn&aXh43s z|Fzuw_))7F9VaVK`Tu9gwY%RQ^5N~A@=43KvP|-qli0I(TjAwb*^m3>V~?usUttoY zz1Z)JgdE2j?cK9;1f}ov|E`|$pTTU+?AK>+KHK%_%(P`vdsh1`o;|(vdF}1odFxy! zgr73Z7wuRno^r`^``&5Wy|YEPYF5}>H(gbnY51QZ;Xi}cr9JbjlT9bC@ew-bH#2by z&#&t@6Ek;g>9hGQDYaqF>`UiArQ5T#nV(O-wk2r?OX-?bp-FprYp(^*yLS4z);0Af zrka|w?dtcseGV%+bN8%;kM>J>F{_PR-=x0LiPE1{BEIaFWAnkcA+wVEr!7*MJo(xl zp3A1oJD0qSo@x7^Vcl~-so;fyAhUsbGFx-&Fpa>V`YoYKEqlIrR2qk|7PW(P%;MeYA&yng;E@4Ml3 zX=kUcP@X&G<7DvpxlRVaaJEp2z@2U>dxh~}W zyN~LVtuT`7=zMA+|v43xj*Qr-U5?vc* zZ^~D$o)p1x@5R>_A5+8SB4t&!w>cktv|v(csLBL}HOaM&$4#TEJJlZciC9p?5l02LAecB#b3H^Ix98^jyRwnP5Shdl<*J_5u$-BZWkGj4jpSXC< zdqv&@sdbm1Ps--Z_mI`x6t|m4U*uuq7q_W9I{hQ9HwQiYn)GvfkyZ88)4H)PaBXVKQjJev-~VS|`24bvPi<;k#oHV2?6(}V`|4==?;YdWqKS7r_D0N_ zneQQbZi85r+~!9!uY^tBxC>;N-M1gwtF(*f)vmUSJ}Hstr?pXK&b+PHo%y+ff~L;h zRq}J5o4M88h)+S6&;RLbyB?<5@LcX|LDnkwd+U4*nPvBCzEr!{(xvraMaa~bFQ5Ep zIJ3uG@X<^6X@1Xrz90Q1)wzyAQfCVMtE$ChhDVBqH1>R&&9&bi_9pFzBR#nbBLm$xsx zBkLjfebt`pPj|5G%y>7aG$|{vw(-KON59(jj&J#~EHre>@dCzsvI>X61%5%v-8US3Q_e#HStF;v3~YKe!{yDJx``?3bt++TT~ETw#>2+EKCYS%2@7t_{TxYiXk^S;Bu!;+v6x;=TH)CA@CA;MV``K||r>n286AzSw5%@qasQ)5Z;- z8H{`rvZlvpOwXD>v8wpWm2&f$<%PwSRFvdYWaQ-KK!z}~va+(XvGZ|o z@X3h?ipY@+{vTiv|EDQ{cwTw*63@n1ILW+itY{G$w>`H|qMvW5}awt1(JSZA; z@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76Vi>sTvho@I?NN8AiL}XNQN@`kqMrKxV zNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5LEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o z6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+U%r0({^RE_kiQrin8CgR5fG1|`Ad+2 ziIItgg_(sNL#b+cyaU(qqGsh)1GEAd)ozsj%5_fL18dU20+Q>);UhC3%Lb@dfKHh=nZ z{JMSAe*4xfU*dnVNBw8GKlMKY*DrhLA2}(PkE|8X`LfRW*gOfTYJ=N7;q#+khdrM% z^Xt#56Egc&JN1-&^8f7nPrdQgJ*f>7ImAv%GCVkD_W0B5AJ@g#ybOBzeuDQA|Cl1X z{g300u5l1NakNP4?k-PhZ4HI4R|k?;sb^X*KKy8($iXYip1Wxoy_>r4x6J(Z8r$kM zUS_ME^Lu`tX=%RA{rbcod#^9D#s_}Y?qbTVd3KO>+0V`As!IN}mddl4ocQ|NWqS|5 z*_DpD#wQqRmP?-Fc>jujY4xfavrk{%n;gA;X`a$PZ9%iei()%YZranXarpAeNUf=A zllM%zd{Q@P^R8Qe&(C~UW4L_Le})rQH|lSz{%7ENZn~Z)az|R5z3SiK#>*M7kFLy25TI+wlXr1us%*R=$C9Mxht@wU@^{eUm zd*>BrKe%fp(Y0IKZDTk#4nxohxX09S|?jO?RaIsOjY=l ziuqn*n|9^CjB^d|T=HJie((H+sb4pc@A;c!W=4}+LnU?meX6dn%PM5tk+icZanrTj_bDAaI{Tcy9%PZJD}9x) z@vCK2)qM6Nd(>M)A6wP$_Fa85GyB!syMh(P2QJ^qogQ>&&wqxMPS%1~+t=Ih=VhVX+J6-G_H<1YU7yF<;v5yT(MD-Mefn|KmHFC6LX?ZA7fuy z7`n21-Ok&ae)lgw@L)%|_M}6HW=+|(J?;Lz`41-9AzpZnQ z`EaAXWLis4{b}P9_RewVA4xMZ?|Qtnuxg1zlVNb{v1`k<&GP4eI2Yfw@T^p3S*FVM zI}@LlUAuheuId&+<1=r!D9Akj6}})Nj`S{YZB*U*8g`O;2WLK>5&}X~G;;(Bi zU7mc?cGBnA=-0Jkr*}RGstEQEoV*;C^-f)>v0OgmrrlAl=f78o{7atoOZiwFuT+uw z$)4))$*-p^GE40GoEo-QGV&Nb@JOmFPzu$JHZ zpW*tdD!r+dt7B&53e+std3$L6GXMQQ-^Vqtc3HEAW37G5wTbbsj58fYyq2Gf(Z9#i z;Q4rk#q0BSSKqiBu6`r!^~v61^}!wLvz+EUJ?VSz_2p>wOaB?{m5rS~sBYaM6r;I& z@-^3=?(q+Q$^CqJYs>Nv+vatjo16Wgp)UN7_KUy#4>wLa;B~R=%Q|;R0dlh^d}idM z{|ud$#_x=7q;UQX=6AEIRQvaB_8)(yt9winl>~Gr88II0$vyt``p0$pk(ZWUzOOL7 zW8RJ@we`pLc1JcS3wAwypCk4yk&!uDe)h|Iy9^>*9)8@t`1qqb!9$NkKYR$Bee2Zy z+CJmM`{edsQ zPwaR6M3%q_T?<1>4=^)?Z_q!SukZiaCw8yK>aHV?ZWmlqY&h}BPrfI)%WG-)?yB1- zbtnCd{raZneDT9xTk(I6*AD-?ssAI~a&1M@*~2D=KlxwH;hQ&C`_7*Dh1`;nWsgOl zSFKTuY}4+WrnXn}=E?c4y(d1MsS}@NvN-+8^d}P^|7z{|7BppQ(au8~USyXamJ{4{ zRa8&U+d1dKRPOJ$FMKj!|55#HYw3&ttDU_nw+_55JvB$JrCjuFJeQ5tK9$RF*C+Ta zSxjWPG40y#o6p7UcrL$v+ftv@<@a={!y7-VC;u4~kGhvWTx-ktpP{pM!+(Zt-v30u z99#L}^_y+hXKMFqpQ;I5${iVN_GP`=mW?L&O_u!oR@Xc|_+;URZzUSXPP@Ka|H&pe z=EE83$hYCA>O2_!Ect6)Cwk(}LDfBHMOL@TudVvFT!6JryW^v5*BQs-^}?JdoHLeh(krN$*Rli+xgQ?T^b9}s`Pcg5C3E8Il4c9 zt&*=UBuRkp#tYB?403Z{M?ak27G{w&_2GX8uNlmWwjpxeZ*MDKf1&-Np1sDp`n2nm zqqi^Z;R&-^o4G5*#CzqhXU>Oi)a31EOY(BKcf#Bmlx+xmiV?_^SZ7}&S6>Y(^I3qq^7HX z-~3)Pp=iyi=BZYJ{}~P>|8wunwqn^(wXc|FG;1?yH(u9uG5*=X z5N2WVb^W3PkM4$MzN<4o8e{9PKYOKPlx=vvvsstMdY2!Y?)5H@do8th+T>*i^7Qlb zgl^qZI3TG~#E=YOP7 zt#U?U;g$^*(#4*-m&*5>&DxsVH_POq#!io)`~OKQKU)6hPeu8E24HoKKZ70frzm>_^WnEY$$uvPUi>dLnlI@;1G=vMA1VD^ z^FM!lc>fR2X}EGNepCFBAL|t+ zRn}O2ROvdmKYPNvfJzC&Ys=yK{hPmS{%CUfxX_Ii=?M!a?0E8M%Ic4;b05m@vVWH8 zePh+c!mD?quf00Hpu+#b@}4iVTPMBJwLM^I7xUylgMs#)KZd#WOC#0@X9jI%>{+ZR zzdHPE+5Ii=lsh4 z{|phv8LCmunPpw^zYE{knSXe;d!06SG^1So^CeyO6HTA|I)6}JCT_FDWWSjCk9OGq z@eSPZ{(Ig2k89xcZyg`k)Fy1Qcl*!qCMzrCk=D6SPyREUtUvSO;G-Rr zb(g<+8IW0d)c)^|?7DOR83cSDp1fqh|L4#4{|th$=NtbCSFCrQXQ{9I<_Y)pQ?u>Q za6PbpxU?qu8Ov|eb^bg4Gd#+AyZ$Zvy}|Ig5|c2%;)v?Z0PC%?P@ImaW%Yi-Ortj;(7XJGwP z{UBfXPJC9g@4Q15Ok2V(=M^h$(5g$7VTdVxXYu71+uQZ2m;arYn{1Jjth)I4zt(u2 zm-buQd$wvH&gBs++~D+c!h>Xmvf$Uz>W|C&o!;GDQh)y#DApG~wwO0N^OOFR`ZFIN zH=f+6 zr~7}*O8L(qzo(G%=i5uNWUn`$B>u&GV zL#Kp<$r+X>&-wclKjZ!FSFzXMY}$W@8UGo$E?l(Fh?jnKTKO<< zk5}(@qkTrT87_i!EFcIV0iH zQa5GEatC|2_3|I>5A}<`nrwZLbr$pGnjilhuA8eL`_CY^=*hN8b(28pAte3pf|^3X zpNlqtqcB_QMxXNfk45!Q_CG6sdgVv6*0ol)y-D-`-7)+At@cNwwb1^X%68jz|1%u9 zru+WQ*^f$Pr}lN&ZTJ7ra3rkd{+9lpMZd3IYkyJyTWZbyE$_RhuU#U){6}cee}>59 zH6rz&;y)XoG0u6nZ$?M`la=*vkMH>-@?m>tjqF2dUj6tjeeXWqIZvZpI6b{|wXmntuw%+rN~TuPI!4bLkcBWyjXf(dl!1F!3h; z(#YA5`}>t7)xGT9?fRwQwjKE^{hwjus!4U1<{9=p zT)VcO`9H&r>n6!ZeD7-fXLz#zS#{{=eJVX7T0xuQ@5KL^cokB7t;Sk>>5x)My zYyMto_u@ap%;V$~UqSO9ukU;K`>=QZ_n7|-A4T2bZz&(!`1gfQ|Hb{krDjdF=-Rwz zr~Rk+&sGK%^Hfe}{?b*e-s~RhP6lXB^=D+xy2M_kUFb@`&Q5TUE#qgL_h8koD;qxTp9S)h`qes?AMakC>@7Js|9y=7Kef%e z{~6NfcL?68?EgE#ee3D;{|pYxPXBiOamj8&9}NQ^&wykX|I!#{~5N|pZW55)<-?D{!QP^`hSG~ zXHW^;_jlGlW&gSB7xk~b3`#Dq=5Ky}*k0_9-R3=8uD!`wCl)>5&Qe#eeDc&#g|^UR zX3cZvJo$3mF5&)`=iOI6XXgLx|FHU&`dh)rxe=$I984AHX^0ALIPy&*`0}r=SD_X2 z=HzEYR=WQ=&sDlPCO0lV?atgUo;APb`&2a9ItOevIJnenNl)rshQCsKs*n6<;HrsV z<@26JEQ8+^Ui+wNp5?b)n<> zh~@tow)5`&JHJlB@5u6R9_K-6*|fX*w{ea8+)e8j@k9K%Q2(v+V~u@Z_bz`xY`JAv z`djr+z@&%wEdSVu_BohOO8?K`dL{nDNqJHG=Z_EX{~@XVpFw)k38MkxlZlF z=R-1*B5|IRc0S?1`zvfao<>!Bd{54M36RN#!6BB{_13-q>|X!SzNyam(mFBk6IK7U~@hPvB`Z)L7=07t}Uv$lV8KpC6N2Yk;Ij27N$MJ=eo; z?9HE|r4g6IC*G<%)iD1S`=J!3!eX`B{Y78Dgui{l`Qg-q^r!xRCAL1X-`v-4I{#Qc zk5AH#?xMRJ*pll%u228F{d!qH(|?9d`+rHS?|ZB#J}vgx&%Ai8Ip-EFUlpa7>02je zW$^Xqhs$%f?SD~Y?V1}GwYYie^Xq%l-BSy7FGV{_d#ki_h?JUsw|vg`sHoFC@Sg2| zhVvU+Ie(WeW-a?w{zW_FL*(5%iWR!)QymYc^lUi4T=eBXp${$rt}>gQHs3APb90)< ze~RBHd42rT*pOM=$7UK%{1JXA?A$`}tit^>f6a@0I8SM-sZDAq+rLxc*;lt`f8YAo zpKaEuPa;O%nKl_#o825lxhAcV^kk7~vJT&pB~=j9wDs7JW{2%lwoF_;T|M^no!?!T z`DZ(=-g33i=lS73ZfrI`s^(mKadrO5wf1X|Tr|x$V<|ddW^nkzwJ%nSSs(sqhVonKbC zElZsduxGkX^5V&_u6_Gk6?1gjr?8l}Mf@Ar+`hdnevd@@GS~8QDQTBI3*}prvZShd znzkPH+9P~bKD77LMx$kSv|=7dCGW1QT+7YtEq^rBbT_AxTXq3+mE6?%57&xETnURz zN_FLJF%oXidGJ`a-R9TF*ZrZ#ro1dZxun0Lx28^7X2X}2r-I6>D(mAX-cVa{yY4^3 z>wxns#MpIX);>M^ZEjI+DR<`DWz5zoF)1lMeMeH{+(qTTHQQIUHon?swft!Hq41#S z<%{E1&Mpt1y@_#^zIsvCq;ru?>mp}7U_7ZdIe7biZ=**>E#K^`H=L>!a`(~Je3$jlpFfHEcX8q|kg3xytgp6c~?-&aGXR!>$?UlYP*(|3cQ&88a_mTC{)S;h312{Bc@q`X`A9 zPJSJIYulV9LTvnN3$Jhc)p_Od_Qoi;q%Z9o633g6gPuxd-0z4>|N&I6||cTc?) zRXKNS+rlRYCMwTevCz#wF)Z$1q_}c1e`0V&_MuN4B6sS3g$3^JSz&ko@tv+J8+ulXmNwR?r4_|j&$}zQdjxspLm3w@~ zk5j9@{hGH!{%_U(m4{cqxbg4e=4lo)-g-8i$*DXhz08mE;KAcrZ&tT1*Zj0>{f(b* z_S+r3ba>b2<*L4BJJ-BjUU%PCf9boD&snPNx{=qzcb+#r|DPdKTt>=&OY_OBfP+Qv zLhDq&ow}ITGHII1h~pXTUa`Oolm|J=Zge3h-n?s8X;pNdy5-|75vp>bSLCt z=9Ta_eSF_uHr{e%`DW@8BXPg3ZtK-oQB?xY3hRuIm`xY^Xt-Tn_IOQo`101dR{P!^ zKl1!WP8{3U_&w8e&%WmMekzf5;op^{9rx<3o_yiukKJ{d_3D=BPwrC%6(g@-S8u#6 z`O5h147Ghbw#{ApZo#a3CC6Soby~AiQj&dMOQ<&|=h+n|Z<5_R3N5lko_8+S&|JOj z^5&oaW?5(F`Yn6(pTY8USnS!GMGmGD@@M{O`TK|3^Gc#FPy=xOO)?9=(!P_kv^#U<}WS68VP-T&4yN%Qv3jn`$aYOh{t z;2HjB^%j4AD;NGL4$PM}um5tO;is-LR;9PraIzF~>Me?1Ik({U6(j!d zj`AzNyqyyst=8~ynNLccNZ7eV_N>DFGg9YCJt`CkHQX9%_VsDh{@Hu?8y|eOX-_N9 zhsn3H*IdGimiGKiD^x{lxR(pKrY;cqrD zH5NYGDH$3cU;M)U*Vk9G)LRcJXiD#{uiR;Rw7*v>=;Gad?Uz1GjX5vx^r;_IpImyI zpZBj;uU7uI?3v3yxR3bV{Lj#T&iFq=%(Q)lKTcY9ANzj#)$#ufPNrYpzuB0UQzQL| z!|Scu6Epj_pf38)>yKJDoqcrIvE!U-;;&ghde#+2Uad4;I{#U})I71Ze#+~;gud^6 zTmSaPym*zRohsM#b{9_-(0qNmR=YlW<0O@|?F{A%U&f>yJ+tvv#x%9k&$7xulD$i0|Lvrzph_k$6vu)+NqrG)7*FU;Xetj)tm}E8`VFr zUunnwqwBI?pY59kUH@86Wq9j8JYl2t{n^gh@9yny+GKCO;^*t?X%l&f4k_m zPVS8V3A>W`i+{a)=kZ>z~Pp{0BNGblfPz4WkPZ2RH6k{q7% z4AN%Lc|2im``7;rU&Cd~eimh4sS*0FL+nufOXb`JUf4kEQPy%f!d*{a!aeZf{z!acj~FHuj~l zKXM;sXIrZTow8W`h`;N>&h4e)?EO)H(hL@?sGOe|E;{qdS>5%z=jZS7Pup4zg%yriO$Ylx+*{B?Yc7}iI&>~ey&qn+jaP1 z=H-K{^_81`G(Ysn5&X75V!g;m)?LTmFuaU=`BDAI#MpMO1J_%AOnMpTcJO^f(iPj~ zJF4zj2Md1ne#B=V>JZwRRU@Za`e^Be=PKPjTlWTJSeB{VM=PW*gxnpQ6r6 z{k|8HSll=BXu{S-ckU@!H8nhKl&xL8@OmEei5sT<%Xj>at36t|<*CY?^(((i+zL^( z2zu%npE4=F$g_@p|dObINd;Y_xd$RhKJ?Z&NE0-Ut4db>{PE+1mZMO2U zbnwzQeEZ9kpWHn^jn^!@T{{9_M3HS+vNx&?Y^m>pZAus%*vEj+WGP0l6}nA9!lMKx$PtS+^i19MBfkFW^KAB$<=$V zfX|Bm^Iy$fa~4dqT-(ofs|CfoLG zx2ySRJL|Ca3R&&8D;H|6-i2q5s40u*WuIQM_b>nM_UbIYEfc)8gdU^+_fxcdk71=g~HMX}^{aKhl@J|Nj2RywZ=-56xTF=BhN- z*e-WkzOsq6vyHDJ<)Ey!)F<0ym&-cK^>dfsa(X?-q+r#=AC2)2HJ%?;%(H$+gtt_H zGS#ykhLgX)6?^;Y{JMv0v?A&=oX}Pz*Y|r#ZZo5T6`DDGbD3{^Vck@*zCK+q(c=qbvb({2< z4&`~;6Rs)qtUX#f>+69`X||oZK@N`VWR$YpuNJZ_)bcgHXvYv)f5_!?gvZQDXD8&{ zZV24G{iC%1!@fP&FG|fnbXMuJYsi(7+tDYkybqZtI?*|yr@`?#%jfs;26gAE4rS~Y z)#W}So3HzHyY6neIEKmPe)U%$%aoqa3BOS_y=Sf8^bJ;jZ+%tt>WQ9w=Z8#~y}^3F zxf|YnW5ydIOd_CQ{xY= zul@4i9K|NFUj6EGUS+9IS|?8}oqXZ1FteA)hOD5bpzKAS|2QRYg-)0sB$WIP*08Kz zf9O90yV|0FO)23$6=kmC9{%4~zj)s&^>%Mh=FWzrxxSj$ysBj+ZeBT@x@nqd_1RY? zaS9)J_b!_keVX~{m-T!f+h$F>ysN?L`h|V^A8WTKDX6{VZ*w#$a}{FyWSc29s4;&CO_`=kL#{0PjM#CdS=Qbc~-*p;+t^6 zkj+8OTPE-N>VEY<1DB0-_L`U5u3uzSF+R4*?Y76AHAZ~=w!Ha2t{)7DxV4dkjeTiS z-5EPoZ~eAiQL#RkJeopJZ}SM$Zk74Qz`&lsT52y)6UusZx7H4u@ZhCRBC}pqXv@z^ zD&{yH7oJx0_ffTJTX=w#)WfYN5?SwRA}cm|J&{|sBl;xcl-lf*OZNU={6(f@eS6@% zXYU)gq)rO$4WE{?eW&S{_Qrj3M?u*s;Yn3^%O9JaecDsfl$+yye>fkVw(VBbvajs9 zWeJZt&+ckJTd128Ce7_Pk2kVX>L2r^VAuZWEe;GC{Xg5}FYWXF(a`XtJ1GBGMPhtR zg?*53;MUzUPAIr_{%2Sy|2kgjkMk7uj;$*H8J4%1e*7Zz@AeUmx9gwvPk9)5{%^vR z)ip7j_y1!SZn_#En)T51cfgu-2R1&b-E;jMn`8E^S-4hBh56Iu`10u|4=!Ha{UZ2? zoA;{S##=g@oMzapwEXjW+XWj>(^(Dc+-zT;%T@a{pXJZ8Esu6QZjQfDqkSY~X;Ulb zd(pJL_7CJc!x#Nr*T0~SqheOB_oMf1Z{wT}zU!C#;%0woul%?Bxw~w5|DF2J@FHoC z`L~R%`{bo-3~jc3Qt>W1*xi%--T%htdwWlRyWbVLr9!#2+%ojQ`QJ(V#Xd5d9t!=) zu5%=CPG!Q%yUW(Bwd%dQJhwlYzv)Qu;a$beLDNnyo4v2=Kj|Y3sxn8(1E8^4B zAU6l49ojpVH~CIJcB1x|{IPYJQtgvFW^O!xIzIWhpXEL|iLSgqy>CGShfNdT7v!bu z%$L>*4c9l_e(7xe;mxwIq&B| z_ItZB0^HkYr%e^!>?=F1b(M5E&)V3d{oS#O+|LA$udUd+Y?1Qh)4C_tR&3Ru{{Bkn zp;LMATwerEzYPcekR?>`Bpjl<>-K<=-ToN&hGAEk8@lhelZ=r}RoD5A@_^@eDs%mfWiff(!tm<-;=whmOZy>9 zgV?dE;@JCP&srybT5VlYDD&x}-08(XmOkv@H|Re$cjb?T%baWu)k}T)o$IY-a8>)2 zrF_+ndve*%FCNZ$_+;msb$MB{I;VE(&U&8zu6P2kV{z@guTGxZWhTdl6x`Xh`S6*~ zOT+JWbGIFuJnNf1-;drcZO_q~Cda>7YXV%@R+iwS7Fs&Ed@~W<=Uh2tK>BovHTSHTKm!6EN z^-YiGUc&xFC3(d0x^5KTr@yb9 zT>r`LYf)`nzFRH-w{vpbv&`Ij|2})TH5lexFO`y6emX63 z)4F@RWZ4^@Mdu5<)*L;!%`H{?a-noVJ=6WERde>~m9^*3x@((#v?TjTXXMm_=?72P z?hbnseCO0ok2^i-w#E@jD^H&LzR5PGS=`McRa7q1?0)@gmy%z{HeH_lxiDt$-)lw1 zu7_e1=A><0FPEC*(X(jtLPztRmuIDwDso$F{bX9Q`|LWtDyjD-`a*kmY20&v9OssI zguOC>y~sD~R#w7_!(m%LtbgRr7db!J`({Y`n)?-Nm-e$c)k{73nj5%0$vfPvRHlD# zXrBHt{<9J8ylP)V)yCJ zkBfPZhLz`ht#9A;XI6UK+uX=5QJ%x|&KzxjksTiV(b}h_vgM!YGqdm~t$m8~3`E`Y zm&UQZbDZ14WPG;rYUb&g+ujzx`5W&3h{%7F-aBYDR4r}|ytg;~pd7D& zQ_l;voic_}lGM_S&rDie9#MhJie?Qx|{D=F)41F(? zE_Pn796b%NuI(vGJe zo<6;|Mq!&pw`C^(pUv`De$`Ko>s-|!*&6kswaL3^zs6~q$**6=r?#Kb4p{P7eDTW* zzjbc68C1^G(^|DDYTK5wxApcva=qikKg>H_(#PR>fMKI#+IRJxYj3aTIm=R+;UVw! zJ-@Y1VC#-8?h{3xgiSx9&wKM$)V8C6jR7Bm=h!ZpxAb_I!Ht-pg8@yRnHxVXTe|#b z<*Do1Ya_H5CnWsp`tqMa^!Acs5B9YMQ8VOCixZz~_#NLm`{9a51%J-w^;sYOCow

`xD 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 diff --git a/examples/hyper/global.10Oct18.038000.jpg b/examples/hyper/global.10Oct18.038000.jpg deleted file mode 100644 index 444531312b457e21250706e9564de38a3bfde4b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70395 zcmex=$<%PwSRFvdYWaQ-KK!z}~va+(XvGZ|o z@X3h?ipY@+{vTiv|EDQ{cwTw*63@n1ILW+itY{G$w>`H|qMvW5}awt1(JSZA; z@q>zSQc)8pmzcPOq?D?fx`w8fiK&^ng{76Vi>sTvho@I?NN8AiL}XNQN@`kqMrKxV zNoiSmMP*fUOKV$uM`zch$y26In?7UatVN5LEM2yI#mZHiHgDOwZTpU$yAB;ba`f2o z6DLnyx_ss8wd*%--g@}x@sp>|p1*kc>f@)+U%r0({^RE_kiQrin8CgR5fG1|`Ad+2 ziIItgg_(sNL#P&ktKRn-h$wF~+NB+Unb{Dt}U-^If z#TX;;C;jT8ou!j+{5mK6aR1v?pGu>9HEMkGpG<#t-}O~rwCe}aH6C(Lqh2{Uo-SC- z{(JFW}TYdu=w{>oWc8e_Y@A+U%jk$C#~OyYBgHFgUgGaIN)qH*SMDcIqXSGJ%IIVx0DJXqY5V=; zt`GN`OV|1wGD>Q+$n<(X?*QNPpLLO6bd3-Es@=tuTl4H7>$0Dp&sCNDX)U+sx6zoq z#_ZaMmR>hehZov66MtlH_WSG;yH{gv*O5oJzg4+Jmbp$Y_-mn)6sm1|`>MXmeAk!d z*EfE)J>O>XCH^OSH2?3E{SRZlZGSl1Q)EkEhYTN2GV@1S`?b~cdrSnAmDk-#+VeWB zMcd$L;pHROms(pIzciew7C9p^X0ex9?WFig?)_O|!V#yp`G~5wiEe$kpW|Lur|gk4 z3ES&JlJySvxi3(*uwSMfAKmDGCNP@aB9*01;p_U$AHff=epGGU`h;`Jlp=$Qgo48# z6#5VC&HC}{+>}t$)vxL*rxi?#=E;prR{5zgIq?1Z@T+?Fsy3f}QzN=O+O>b9N=pN` zm-*zrKVSYB`t15}ZC=BFh9moK)ZbS9&%pI7IrvBEw`h5T<9)W;r}hLc>5hyw`?6kZ z%SMy?CQtr-{vxxh&$Fj})8UI<-oID>=@+?fW6XBFI`q^0NeuRy_I~$Ui;8ah%bvg4 zlas2RwW?>D`ZC+>>!ubBI)))zc*V5m2I}4Poaia|J0)TMGwln9(~4Tnp0E6P^E&gT zqe+it^mmr8-L^eE@9*w8-`i@0b)OX8$&yQAd*Z;xXL0QDZJUqR@5pJd?LH(`W56O+ z!@}2k!SK&{(>MQ^J}AF3TwPgHt6hHN9@B5ujrsZ#a#K%-t<&4}JnzK!0tq>}Q%g2% zY?|_G+vNQB`|qsjpS^yM`SO<3-#pwC`;-~}m7aJ#Pg>yJqze=KAE+z*<*hdF$YJ4o z-8c1E)R8)OyvE*0POw)E=O^?4^gc-m+u zte(6)>OaH%ss9nT>Vj$4F0wJ4RNfF8Gl}7(LQ!Gdf5NBT(oFq#Xxqe#kqf7N>^|mkGVE4s zk(G>)E$2G#Zy_pm7vh8z9{*MI|0}Fo+x*+R#_PJB%yGWO%ce|Y3w(CuK>D-;3jdV* zKh-IB8lO4L-Mh5;!0lO{d6W14+;VkwPRYgPoUW(b&;Dola8h2>{`up>`+rEP|7Vb1 z{7+K((egikD$4&eFsuA$cwD;mKLc<6BmbWtHoKKZ70frzm>_({{hae+HGh7ylV%MDr#6XF%81 z|0AWpYyRht5AXlsnf#xj_uBP8ru#eXpC736c1N&aPT@{G6OX3h;(rF7i64Xi)!A78 zXK0*M|8du?{|s&0KdS%v!GAIXiTUkM@}G&n7ynDlvFygsWB+iHomTz%Q>rr*M|1oku>i_e{hxh;3JpVHsd!7AH z>i&`WpC8z(E=I6!f9(I{{;vOL>xO6gXc}JpXK3^IvGPBIy`1cSh65+N>-J9)BDyUa0|8r))C`ZarppJYna*&-LF-pC>Ip@@d7=NLSOR@}KQaD;`VR@?p}#>6f3i%-+9i z_P)6>)2BPXTx|I4+5U%Ep7NY&$=TQ_$Z-2Z$jzVM2S-TbZMN5gcvm(vHSs^gk!ynOg3+$>f2RLA@3*b`NMH86d3$Y-{%1HTxAMb( zhKKt*ZS1vdpDx|AyKuf%K>a-Jt9f!?zx-#|ylkRHPO|Fa;(ts2*sYDzPc)rUlw>Yh&e-|JVEOW|qE}XZ zw6(Z*Vf&K$GauEX&5m7t`Yre5eV6IySAIFRUv6Q2T4J-;OlgVJn;3tYR{Uq^{3r5b zf5^;x96A?-kNy1kr*U1DfA2k8*OR#_e^v7TDXlpF+u_F}`MqNE>Uu#wGu>$89{=dc ze}-j5^ST)a z>vtB^ue#=Pe@lPQqTkoPwZEwUEmgbyt@LBdkDIs+=Li31xN)VZP+afg_P@LTrAM8w z=)JmY`TP3D`cLi`=CNKhwPm}Ryz8=*8}pjH_Ma2OY!a8f+I56icHN8@9{(Ap^)>$# zj^oe&c=~wpx{#ON|31(Er!=j;&(5YJwQovYU;U4++pqU{Ej;-y`jY*#%6z@^svW;h zA3i<%V)VObrd$6rG}oD2Q7LQFWl)Y&#BG+3{%GNh1$8&onIqhGPt`{Bsiiocw6_V0m|`sLG_Yzyh5 zu_on3vP`tsFV($&`jP(V%bYh+@g_>|X5eVqGk^PicgFZ%V$d5T$FoqMBU)nb*&H^S>5 z>N9WNK7Xa#r2VW)>{@&I?Urw|l#luN`cYxXhl|f<|CFDbvXjr)a_yT97cb_kZ~9t4 zDe7P9e}FsX(kE_PcJcZj z?JqrcMsrh3m#=*KT*kELw3f!!GxIu^{PVh3Z`A6~I`{4&@uq8)0WxA9r+I!A#!Y`1 z&va16@!g{6m2(|(UrCDpz2JU%^2^&6>$dr_F7}ym{%MTp=NYcI=Hx%CO$&dxOl_~J zO=_s`{!Lr!ZF4_ezw#mTt=@uw%eQ@nCO5=#_53sCt#(_uT9yHu z^)BxDo$}R((=M!ftC~F7^22`y!N%^noS&l?ht;>W3%h1zO3A)kyt1~>f}X6q(-G5#2y z$=6rf%v-+Jw|ucgBdg(8(Wm~_o4+S6pZR@8JolWH|Nb)wzW>%0_NTPI@uBfy6aGyZ zOFBEw$$D7)$+G%7H{7SoC1sLns;#4>=)u>!)Ne*E*~Xs!-Rhs)?hQM8v|oHlKmGiU zbmytdbL4Gmb^bFv_|v1cIWxJsyg4`9WL0$DQ|B%6#TQD~T|a2Yl|40jtrydo8=Bnd zPv1|IJ-_|=+m~kdBr4WkQIQUGU|>DKd}+gxXCIcUOJ&bozvF9>J-?yEslfHUE8i^o z7N7mRR{Z(PjSnaNsE_F7-a9#gXO7k6pUjb$optm#Wy~{EwkTD2{BeER{!2X$PYYxA zZC!fMCTG%-HMYmSj$@0(+=PjT6_G(qn6%O6*a4FKWsqmA)^G__- zck}akO?+pt{b^)X+svoUQ~zq8ti1DcA20s}<%ez3H|@W*J$*8D-`jfQ!%O=-<}6up z;_<2t2SsjuSzGM6eTS23XS6JT;g9P=w{$OOZM<=SSu&dAOaXiG`~_@#W6Z4PX54+5 z{NVFE(W6hdhA6*Z_GZo2-8Umnuf8_RZFy-k@025=cO<80O?>0WxIW-RdDG%84i9a9 zo;*M6WD~m&-;M|W>`$+me0Y+poR3SL==1C6f^vg;|D0cY>W|4(uflnD+m-86qh4R# zYxktW^jznv+sj_+EIC&AX~OYOl54(&xoMpWZ9K@5&>VMvMdrN-g|$Ud|9W$amh4Hc zkTH1BwZ<&}+*_06xfNv}HWVMal7I3)!>s=d%I7uK*4iKbetp;S8;@g@K7CGp8v36> zKL6#}s`9oy!r56Y6K)%y{?A~m@^k+F2No8OMXz_A$qcw$epB9dVnJHsY;*mG2dyo= zKW=*cvvQuttlHm;c17ITwBgi-&JN}4OWkePUg46e&Ri5!z`c;!zPI}7v6hSaXC>uZ zld`0$);a4IxLfDmJn-w+KM5z3pDQ0p*LB^W`S@G$-mPbfmxoyX>U*?%t#OFEYf4S? zi8XKQ4}ajj6s^$tm;J7N`;Sn6j!di8zb`wTkLOD#xhe1e9)AC4>6i1Nl^2f$ee1n- z{QOgkn)B+%*T^KEJ@;k%^QX(cTYGFZSI|iEe8Fl|y>s@e{ZF!&T>4`YrsK}XzTy1q zpt~>D3e8z&&-L?r6z7XA_VI18opW@py8cc)aPO|ggEq;R6GL2{O4ntty|U%YK~~qo zeTtjsam-x%^Q-K~w{g?N3Rb^+QxjI(dNd(;)!!$(^Kv7yA_Cj~X1iqdZkIk=6vfuQ zF6QO@tZm(O9-kH^x0QZ9`G9Z6`M~)(hjsrR-SRfSl;_&#b>{9`qKOkHPN;m5^|Yns z*%hfW%M~B_)Onred^CB=YFcuutls{zdu~o?xcEv>&^RsM-CF_<%Z&W@hHk4k*D>MUR?j+Rorv2`2A+NR^h#rOX_+UZ+leY+&~aMrw~ z{tCaslONji#BEwL{f*>77PoeV!as4#?dBBTH`(YlCu5~o^z@16CF2dJYMIP^v^C#l z{lEIol2?BJ88njo7p$5d9+WUG{P>0IiSq5UEZUR~$TnT&eygLPu>575(^{5q_RcG( zC8hiS==$f*Us#l4Td{P@-cNHhO_#5Fxxz73B0uW!`h+Wf%Vh+#tqqT4?LA-fpJCqA z*B3%wAG^Ns=e^uu@oAw!g+;kbm(RR&J1a%w@V~7pvt}DST|MJU&emQz)>*Ia?A7++%oL);(_Lqm}Dc?kUJtZ3>RLQ0`vpr@FFj`o<%!hq4!k)n8wF@ltGjL0#7A zSw+uPK1LpUv0ZglMbge4{b%~rKK*CdS0UfN-tX#`46W?ov#V!aIp%e7_ZQX9tLql? zHZ5$->FKEo_vc%2u%hbWm)Wwx0oQy4pEAwAXJ@ox|CL|$zdpX)CEsRtXr{ArgVB>B z|MgoF`@faEnZ5f>e{`#uxx{j-f~UQ2&+6*un!H|q_gSs-Z`pHsHmr{{`TT#SvH$%Y z_4D*&)#FnicRx8Frv9Hn&h*RkH|x`KYNQ`=cs-as;r>sa`qrA)AKk8|f6QBSX6N76 z{8z3YNiFU=xBBE-o&O9b6(0^=TY04PrBmGZz3cz(7Cxggy-;P=(d&ASj!g6X)n7*M zy4$nC?R}on;YE{=7H%@$(vzaHt@3Q$#O9Xt_lpldviiE=`r)%#zrJj|R%3qg+PA;! z(|W924kodrKYu;{K=StbtY761+nc8crren+@AVL z%&J#n9$#(vxAo+|tE=~Y_6xqt|8>37-jBNb7O!}DZQ=&icZ>eY$iIxM{2gxLeb%-= z#s1npd%GU7a!2QE{l9yD+%hdRHO|r5XfJMJ_pbQa+CT;!jSt(VO}bY(yXgIKzowZh zPjMTrozLdgSvK<+oAwL6tJdZA35Cmp#m`*5b^FS9{kDC~-YKd*Ibj7 zb$A)$wyfbv((Zn-IGss5*;lTUd*_fQANA>_w%?22XG(T%cx8O&g$?IoolVDuR-Cj{ zm-Sq~#76kTH_0tuCoYyXzO+aE;ng#RF^dglOlyrF`in>1ewj7T~8@*Bifc@;9%H{3G&V$rZI8BPQ)z`hPex^OwH=bltjE`*fY?>j^hz+?b$! zW$StAgKBdEEPn6X`Z7^e)N^NEO}t>pndSXG8TY4r_|G8wvhda&ivV`hXHuJ3%S2z= zSzev=EK|PVbzI`AbCNfn?YXJ)s(SgYpg9Yhyw*L}U!%z*>lqe2!JS3wm-+*@R{qW{ z*|si6x1SA?NR~I6w6@P*l3niV=WR=V&lY_zzbU?Bt;t^Ppv{>KbMnI=|x&Z+7N#F~N0Zzrve;oc8yw?i68+ z`~2v>l%s8@YvJW0(!GWK--q}RgZ94IG-qr)Jf|_T2db#?%^LxX|PY*4%eUo%6w%0s% z``*;FUK!3%H*dvPh7%|Exm7pDr&O>%{9`Vrt$fTS$lw{cnC}|3~&i1rcty19-waD!T3_mob!> zzS}Qk*BYqE7w=ul6(4afBOWpX`8kr zzk9y4V7|Z~OWtmaP-f9rxBPq7CS7XEk9oUZ=STng;}!3>wwu04N_GwU?mywAc3P?7 z+pBxmRh-++;cgQyzxtSDbk}Rs->sR_Y&&Ix930p2Xw@9Qmj1bW$z|*P4PhtO-8;L) z`{~bZ2jgt^pLyYVUaqUa$l~Xe+PePzKf;&X%UCsQ+U(3qsR^$pAKIjmBRGM>=2PYO z_0#Ip-}=RBKRP$vKLk6JSe{W%+;o{Ky{G_o`CDV7=-!bzWtG>=UciwWj&r_$$ol zG*?Gz%7Q6-Ci$OFnK^xV#L{z%*1eEU{OKtBH~Y>$i654wV!kIQ##ugmDH6NT{@(h< z`-HQ@u6fMv5M67sJW}&bpG?ZD#G;q}JbPc}l}Nom{6p8|(Z7fja#J708C({+Rvw`J zV!n9Au3OPeU9T_gtNOTY!DN5sCT*XZO#Oz354C>0>fPh`TxtROC{8k zYfkZ*uP^+D(2Oob%R>L|VVrr)tDa;4)f&%0HNU-h@z@oc-c<#qK7he?u; zBb9TPq(-F3$W=*g{>c5{du!dvg3B+=*<&J1n$dK>aGXxW=L=Vz_#KAt9V z!tx>$d6n+Y9aY$R+-{tuA-v*Hi9$DY@}*_~m_kA48XJo3>wIw5}e?{iKOod z@~x^rVAu8|{*l=gJLQb9Wlp!>waYvBe_6Nq+rfI>ocR~)*H%0~z?rA=C?dY?rGS4DUX-;d4uFUflfq>1WKp z$5yVMrMDodwBUy6xtNn`e>}MUW@+TN2r)!U+JxWv8$CRG%v{qn^#FT-L!^xmIj zvenn+)RAdxxL2?7;H$n^{cS1x_msvvVJ@4tJ>IYIOX}r9$GnQlb=lT8m-U@@yvn<~ zEo|MR(?{1$X#LFb_}ZSR%YlL?H|#jEwqmQ!`gIUt*zynSO4f- z&i-8e<2vtvz4tuTHZ8qkWcM{-=iWO7yuLQtd2cRD&b!=WndDt<_w87wi5T+{G5-DO z)2&YN8GpCSshhFp`;=0(`Ag&6ChuuHn7{kr%hz%3o3r?ipR6qsEi@>Vo9_Sa%C{#U zi+@_zTzmOC!s^(r%g>*^ejn4j<$BNxP3Z@ZCm9}m?>9?(lNJBDJ=49TJ?GcUl0+ z-@EC+fBf3E{Gqe)33gP%T%VF4e2}ea=Om(538=52{RNO+p}YZ`D(jYYd#7te;2&b?cWQT z&p|K6_eBQraje<>L%nm;e+Gj!AFC86)ZF#03Ou~>&_z4FZMnhRozGV&XBJlnUGZ7tnRDH~ws=lM z*4Cr{D%e)q-0t&SH_IX~HuBN4$XjbGj`qzx5R`p=kNG1@9g}QtWqkvOiF23tPj&b= z^>M%*H@yp+`6sj;|Fo{_+^5JN9mc;NZ?%cFH0jw_O0fsdm|Os9QRsW`)tWQ z`Kz~XPH9^w6rPeKuW)6X)T}n`JwkkZ{8evPwm$1?Kbx@ms?+9Bx#yb?KDsXO7L=+t zZtbmIe*Ro`TYu2cy01pL&dTq@<*zRLl76v1H=yfT?_`tp@6CmZBf^XGlh2Ea9(`Ec zkhNw~1E<>V6%T*51F@`FrOd+8gCBZtcAN ztgUVKQIqTwkHS(5yyrZTySuuGySsC8NyeFdTidke%z3}b)~8wA&7v;4*mK+O{|r&e zE3cU@n=^m*+M@5@BTt?+dziN^J*{@N+{b4;E*+<|twe;Y=TL%-zKr~L@>^KwsozkK}h22s2|}UmD_dBXD)rS%J{neo`_3F z9H-1bwo^7fH1o#Xt7qrBO#HrT>Cqntf3D_u_*8x6>(Fx=ghk&dfYYQkDv4B@O)#we1CoX(&G8tUuHZl+ds`_XT6@%>F@4E zb~}$hsP(P&|1kN`gt#f00^xRv9doPphcDlB=j#r4&BLiP_}|t)^kz4u&xm*mPbJ>aq2 zJNB>ZZU3%1kbT!e{+;~mc-Gk$Dr%m!#Hape*gmJ?&Nazxm91+T#vY1`VQ zzBOFe+m*|1->ATP3%GAx+f2B}XiJ>QA?rC-a}iCp$}9 z8RX{G_T?Uq$T=-45pqfM?rra-m!J7R?B`T+Tg}4bXArqF`SQv?RwZkH_w)MlRAzYm z(Y|XZ`orwjv#WA0>|NJB{%2@?^Hx_nN#nrE3azP%Z&S`HAK77}rkb$AQDw`GpW#85 z|Ll31J@s12m(m;_`M|h^k9MbYWirTWH(xpMbM<_FOQ$m1p8MSHqV3PJOA7bNe>iii zZ>8p>htot}1@s$szOZfI|Mb4}uJ%To@Eo~Zv$I>J10;`6bDyz_tsvxa;p^U=>auJO ziw|%A@G?$w>+T&ETlJK8Se#Q~>Kl3N zw*0KqoKq4FgnFhd4)pwe^7XpgccV|;Ui;PFZY$%8m!G?9{m#8QmKOWSx?`4^_9Wvr zhQ|t@-v-^h^-4UWKR?~3 zx>URBr@3{(M8OH{tE=Yc-H)5~>CmP-s|;9+C)s9S{U`QfV_d9@th-8>@Ud%iY^TJo ztJ+Z~b^62CduFSigc&cKR#2@EHix)n)HFt(2Yj)R1u{lTmr~J09 zcpW!+oz|M(uE$?nS)*1nM+HtYdbDO&Z!!|}E2no%oWIL1!K!BhTis&2y}wPPkFMMDtLBBzG`;+hw&xkf2gLlaIwq@LcJ$n>FPYwgnkP@4m6x6oc=Bc9i{J%IIU}>?$8Gm_ zdtY1f^1`3Dwc7Fhf6Ka8DgI~3y5#s*>*~Jtl_wT1?|-wx!QNh{$bR?j7lrYjf1EEb z+`glrp&q#v#gas^ zH>al^ynUz7>OVto)qjR&8HP|+5ZgZcf2%x?MHHTJcg#?4%v8+%GWoje}* z#`^^bm}kJGkqtb7aa3?F1xww?VkFFtF5EWZmhnvThr>p z^2(dP{xi({JhR1Uj-PJu;o{)E+iowvS*8Bs`p-Z7a#PoCS!BF4Zn6B&*W3z!yc4)K z&C-2zeBX;T@n6o!%s(r8Ef8I=g_%B^@!H=}+zd`XzRol1XNBTo+O_MK`g2i2`S~FhFS^J{hX&QHHLEJTiy`HabUwvO) zrT?RPzD@j(r0k4O9|eDe>#w}g@rmpDmHk3ntgSQTlU5v9Kd&ZGNM#+H)pa?g=7rkI zFFw`WvfRq9seI<^X_iT5%vv6=th!EqXm5=V+%^B)&eDk684(?Ks^3|%Gyi8;|MGnB z%E!DuKZ*-<|I{x#sOD6JF8xNUgW)NzcOuixc)!>$-jvADpJ_5uOtB_RD&cAF~(Vj@sQ4U>F;; zI%uk?=280tA2J>o?06Hi;$hY)t>5;Q`X}ehA77qz?kL;bq86TiAG!F?ZuDH0DbAU8 z@R?kC!T$1>uj7`kS6V$mdya=#_SHK^BF{g*jR`oDcHeYu@+-p_>GtLPspp50lAk($3fp$PtM{wj95*@lVdS5={~V8B+O@ycPOj_QBZXHS zkM@3xXNx$zB=5$~+b<(mnHH|SGTSOE&4N#|#~`92d+GhK-`oFIM*Nfxx_C>bX@=>U zS7ly~tl78glrlHm_E&IV@s^b#8^4?@+4#dhgGxpAJ5Too9zWs{a(><#cbg$s=F zi}tB~Xq~!kR%D>#?RdM2d#5b)Qn=WR!#j@b;*O|OleF`exmLEkBeU|T`45x*%+Fuf zng`Ahx?sb>$2mpRb{F5?fAhZjZqdH|HdXi0WX|v1^B*v;JYM{-;&oj6DhA0`|A*SF z)1K5U)+_S=w9ez1aaWPY_f;R##MVXx%(?A(clWKAC6}`&{fIuKEuyvI*eCPyx`@Ai z+6#7kxN_n6w3hxud(S_NZ_ZtpJMoFDO;y2vLvb(<4<);JveD*DP!dz;6y35=I^==$)_+WF!06!qkrXFqHy zjHpZ7?#{pHN7eg)YqJcsbu=6&`9C`NVnNl%FY-(CU(MtG=sL;t*!*<8rJ3_=8lpmF zk~J)C>)UNPEf%}&_BB6pt-NT52g|C>lQ@}-3XU^RZaja5>v#3T{|rrQRW66QyPmuC zZEn<8t<}-fZp+Wq5esiQa3$zjuV4Cm_4~PU)85UG%`5oNu;EGhgg;gveZ;?AzIDfa zW#Xe*MtwV*jEwk|oA@8cTi4{ay{hl{zA`soX9?rnE{~YqkJY#Pef^%_y5+@|lcuXP z9JrF)9$$Yhe`%lF$4|}cU-{HOfBO32hSIq*zlF8S|6F{QQkhdMbNfcM+telRQ_EB4 zFWYXD_Skc`*qXFro)!U-go!_{Yufnpv{|xA)NOrbwSYzHk&R;x*UV72r#AC`tlxVe zY0llHS8jJ3X;oCL4BY$pe)Qb!ho?uFoK}d8UY+XauH$F7=lZ31oubCH7b6kC?lfPf+4{iDI z<=w$y*S?%qE%3hUdi-MJzo{qcuIWF$^YZv8+K{J*Sw z{Ow4+p0)Xx!2b*j!;hzJO^vo%@bqT=+vg|JDx@OwN?Tji7Zue1wEUd6)IepArW^0j^Smuoy#0$cCZTh;z&=y)=p*LKvp z1r(o+yrO@mWzyB=+TtA(czwBacW&XX<4cgnbW(Ims z`I)m_cj-*OMXSDq{eJhK!TH9X`bSgu-fw3&eRNN8kC4X=lUaRxJ~My5ZdqHsW0G&> zr{`;}H@{i&H(u}XZ>yY$r}A0nvakM=e(jm|ao+>OIK^*!V$y9&)^)pGy~iV36E;=T zi`P>o!lqQlC*3XItv02mX8z545tDz^W}m7lT;F}XO#jz)HXC34>D%jHM_To*`<$-t zwYF+%xVAp?)CZe>?%HrCZ)1_{jb}S+y?l?0=6!o_`E28}$%QJ{eq`C~nip3-W7YPq z^o9S;DWBmF+L>TXbblwe-t-5fe(juJ5(sEdQo`yZeB_ZI`T@ zZ|7_{{$T4J`_3mBANPM$z2z5{p6Z`?cH^r(bNg4?r~PLTSvK**d%x{^jKSuwjc2{8 z$$f0Pr*VqsJlpK&@jO}2y)Ql3+|!^OSKuk#uktVD>h1f2o>~+4?Oc_#DqD2p+k{Ut zN(Jl9-$%w@JNjPa6;q`AJl{g|%S?Z(uU!BB%*iwB(B7SQ3V73(69O*4Oj*?Y%oGYV&;C%sBT@*0$3b zpMn&wER(RgZeM;P`E|Iyp7}Q8(6>|7_BW~fzPQBudQNKb`Ioc4tZ<%WZf9(Kq&920 z*6Zc>7k<~9|M{Be|cq+d{`D*oECfmDId)uo|f1@5)Z#?U}GV83RW!Cfe>psuRwr~nnEh~Fu7*eps zc8*-f(v^14j#fQ?vvAF_-j%N}88V*{yT5$)Khwv;o;xOGFaJ@!Le|WB=9LYZb2QI8 zi4?d$I<{BR^V0H?npCcUGlr{#Z{GXQQ26zHmrb$k(TR=*v`I^ZK;9Etm_|IPq~)0Ot1=91Q&QF z-~umespD^BuE-^Fn#<0w`6vHlpSHAX?1O}=i;w3^sy^XacBHVy#@~AJvd)L(6z2AM?BxE>FyZ)*>u2|iF8}l=d4*p6)5Y>vt{-}kA8xhoe)PYL z&qhmm_yw=@ly%Me&u}uSC~C@L_F2!i#^tKnzmb0$RX+KBl5xbZBL{V!yqqTOaDHv= zH?i5>9=Gj|9$TZX_Qms`&+$v^rOrJrt8;s}e`#r1)v8TB7Jpv%Y-?RUGuffiX1?R= z*k$bxrF#R#w2eO6OB9&bCGV}>7Ju-@nNO`gt}K(<%k$E2mh9dA@^bO#H`_b4Qgegv z>3^_Q|5my8^FHGrX|^}dUao(!ZGGzBZStot=ia{<{-42F^znX%8vaLT*&nC3t}m5# z$yV8+=J|MnXi#z~Lv!0Xj~9k#tKPpowCyC+xYKa3Z0dYFFs&%!xknG+h{6?m?+-w?;~J=RC|Kf|v1C3WiS z^Sv(5YcUCmSDyUp=RCDfQ#DoZd7b`v|4C1WDaWMW()&_nYO|MKp7-jlvrF%W{|tf; z>c76WKD1BJd#%SEKl1~vydGKh?>urLk zrL}eKAAWDu(Z80g5j`_vN=p9EwB^fe&wt;q*S0r4*Zs!MGe6j;rP<#KJpAyM=dyQq zxBc5yxp!i$sY3YskfK-0@>RRF*EdQ1neg+M*`l5$J+5U-%hp+1Uy+&f?UsdY#q$X} zKZy6P`Oon9wM)f`uRA;bGpH|@2*{r4{r>W2rES`#Eq{Afn*C?k{a$~c`Cl%fnCX`4 zUF!>rRt(t|KW}Is$Ew_o7kl9+nZU>dAvSK zIj*T}U(3}~n==pnJ9nvCefR!p+kQ^S5HE^#6S`(zySMOWd&4u&f2GZ=SMUBv7U#2l>*%x9KD$2l%H*jQFKYKiPIYE?GugOx zebB9?i{j?`E9~67ldCRg{?f#IoR5>A_3%f1xf}0mFpagqwWwZI2j6-E_FkUbnQrsP^@K(XPdAvtHf&kuLDjHD}W9Ws{1x*Ps9L`k zNg3OwOMP*AdNZl`v&Q4fH^%dfFZaKm_08Z$hoA15Uu!0JevIsmNPIGB&MeP2>+Z+D z{$iqI$~JeJ#inz|8Mtn?o%+(*^57{Z&RKYX11+Ue%65vt_Lh6{xjJ3uPskL zD6X0NOrk^L%X+h=>E^#zyr_44@ae|G1=FmyKKZ39{&?l%a;wyHe5vx^&nCx3$2fSF z-m!J9+O~Cx>CV)YgK}3-W|f_8V+mf|J!$Ha)|nsvN=@0jRMURXgUP`j>%7=rUfcTi ztE-m5Re{S}zFuGZY)`+TIKz{M1>bb%EvTQdJhz-A1^hu)j>ktPp0n7PtW`H^3%RuuP;2jA1LwrYEbs2 zKg`j)o*$~0&15qAHtqVt%{y+NV>^?)euntE>hz_lM<4Q*hL=8a&TKmvKEXKoO74lj z?q0b8%ho;V==HfRspoNF`rYOCtLxN?&oG?Jvb7IvO-~Cu`Fn46*kh+I?(#^L%(-ox z%FG{RSNk8hC(s+?Z;}>y<7xSdzcV{kz2B_;^42aZCg~5ht368<-0!XBXReSt z9db#y>ZH!(PpLs6i;E2QJI~w6^7&=A)%t_`Wh0M1&pgSuk~4w9UC^^9Wh0+c1HX)+ zt;Or!{Wo7-nUeH2@A>qa$BZpY!`4(zxm5Rhciief>vokGs9j;R`x-Rq!OoMWRnHH~ z8E&!Ib@3+0*Bu@I8Pt|JKHTfTaDC0R$Gez!{`&H`Z|&@C`)pQx z^(Lddcb8O7o3UnPeDBp-Vs?wI2a3|uV>*C&hG7fP<)nSmy>l<2%B~qUX)!Tw@#jF#iazU3s6cYMxR|Qbt~Ya^XB?(LAdncCT55 z3qy<5^J94nr*4kfS9ffwUB1Qd(|@j?l@z|8_dsgJ<#M%k_N_IZJdNs?|EvL3m95_` zR4)H#*bv8Zx746q{t&3DoP7K8$F-I(oLyBvS=Oze`6ypAXj1HxHTz}%d7S9_C%TvG zh|r#%FK0`3l}tDHkW$HQ|IrT`W4yF^kM2W}omYB~9IoNGzq_Mke(N(tS@n7BVSc2j z`Lp*~{U@R8=jtUM&hwX!H;K5tr+NPO-rDHjHktWLe&ok(n^-nkqo)3V;a}}%=Q}?9 zoTqsurvGQ&;jimEPG?!9n?AYj{&Vrs!wC<&9(i3!)V2L>?{Val<;}$^77D+w+poG? zyC`5qQTMM|Z@<3gc-A>}djF{%+ONyD%~{Bv|6%gI{hkNTiJHEus0nR9^3cBgn|yHe zVX=dEtodR$@NcaR{lI>Bn>m~L%#bgy<8>;k0%Z!eFSI|m_wmE&y=+rDI}Q7*{&gQn zRQXXfRYtG(sQIg}_1*R+bN1KV>0f2aEA6*&?`4(kAws%WB98xlv}gIZ^9(nmng1UA z&#*A$p2)|C*K6_@W!_7BZ}hU_{BrwCtNz`3zu9+tzKi@XiS^HGesjjNKjI6NdLMnM z{%277dM~dCuW6tEO#CGJ{JzC{ryu3ZR~^ll*5Iit`&m#_TQ}F9>vMJcNwvM^hqkX~ zy<}+mE566#rq^69!5`7Ne_BU~7rCehk zZLw2+S!Qs{eA?(89iAN8j-NmEN^um75PfiptR z+OE!@_I%clT^5%z4Z9wc3P^VKJr}+FV{)Ldb>ilj)++~2S-y`;RjrJb&+l6;5g791 z-2I1NTZ&`dmhdn!tY2Nj{P3?$rq{XEbGLp9Z!%TgHrLbQ;QEpaHs#;41?6Y<*=Db2 z4H9{F=luLfIda;P?M;VmZF=Lo!o&(zcO1HYzD_kXQd(~7OF5H|k^6XO8qcr#Z>vR@J%d$vz)4iU)wSigRqwn@*?vvXs7^|GVw{n&Kgx^t9 zAAHpK)&AgJYr2ZYrB(B+uV+5qtMA|LpWC%p`?wAFqmPMPjcOKO*ZPZ8Jh*#%%4g%_ zYpbSg6j|&(edUK8Zx+i(8-Lqgv)$(Xv5m*33*|D)T%VJblDc}$N4phj@d^3`MG!`Z3Xn~wjBGLUarziuDfi*1?9RE~-lm#?2tV_l?N zaobknKZDgT?T7h&i!Q$nla$H*burp&<;ht2V=;kop_^BI&B}hif2XznLFE^=Mdz;S zoMZa3e#SrDqj}RebA0TXH}z$l@{fr**L*g5einQk$N4z7`t5bTqn{_g4(ynd9kNGs z;-jQhZhPZ0+)g|y13WT;Cq7HiH}yB` zP1`%`q;K7eIWg(pt=&p8g}^k0Pbn_MD0JxH^AV?S8(8S`P~L@2i?&uC>W;m7Al@^`(FG zFE84$yZa17Q}*eo!fzALR*5&1wr(l0-r(vSv(Eg+tL66DT&w0EIltx$FSl>M8_TNn z+)DGK+R+j7{B?Arw|xBR%_uQ_``Q9Ik29_PutQ zXK-PQeU_U_P0yMY?tVp*)gQOt+jnU9#gZFaYFd5Xu5bD$5Z7z{D6hYIPNlEDeMC%s z)UUSR$Deu2>z{r5I&S&a<(~U;Z+@^3IQBT1Kjpqo?Ed&GPxh%CWGNS7VP0FwwzW|? zX?MN&>!zo7yPumrk6L=}Tk@=rOW$AFW$(RUo;b_Gz*qK;jVXJc)IR&G{ZhZVN_NR1 zv#H@9*U$VSJyGVx%@_Bt?LB@%MYzr1=>be+fg%6EV9mr^xW ziMLkH-TJw_Z&9aS%I%(%>kEE#A9s6pW%#VkDWeWGV8olx3 zwG2;JT=lp(Tyy2L$Y~xoCti6M7Tm<~!g1|ix0*@CF>fE|7iB(pbaB35Sg)_(xB53< zbC+k|6TG~&_^Gi!hf!|O0uQ@z2Dt(WgFn{S{Xa_kY;3!@jrC=m<_G4Z^KblPxcs*H zapvs(Yu44TEveJ{xNvW0`^y#I?Zl!?{wBVV`y%x|_c<0elIh89em&~M1kKaAVvsis^WyqpC>-zT}5AD&=DoW4&@b8%Ay2U{jER6AC zf9yYen`g2mJ>=Z2pV|kdCf)X1vdwaR>4*OeegDoTDGMd{N4-86(rUS{`1z07oSnxK zAIcbCKJj%g+db*%xoH**x1SuV`1^MAG{|GIws;jMY)9fhC&T>NBX$eFmKDPZNUp3DCk4kQ&?Ei=gO zzW#updxyM{O#kw#S6@Me__-)#8hv-RoINpSN?vmAq4my19IxZIeb_IuN<_JR#hb^=PcQs2H%q+See1t-x0Y;=m$uOt zwp6%l{;#|0Tm0>ww-*!b->m=FBl`LKn}d4q`|U(x{xh7u{GZ{)^7VCpclFuWOa5m_ zwf~Z^{?s3bGmkqT|Jk%B{?N*Q!Yj_*(a~+4_4O}*-_yyaS6)O-dy$-U-#{XNZQ;_F z*LF2-o6az4`TDK3^Cdo|MU-mVSLyrDd;RsN+Pq+op;ZQ_puSFe$mFyKhK)6 zE9y$`^x|^wD_#Q5NxQuB1-v@@4X#f)yn0PJtK-l5z3-zwWUV^=ebws+s?|51ownFC zxnFtO@xtmgCpDg)O}rPEt}^Rbt%uz*I&*_*@ugC=N%eXfcb6m|T5(dLR(tym?};~lPMsAL zu|lgq`rh5Q{~1`mnttTDZMf%J?YC8*p6ky#yZLhdl7JLNcNsqa%YU9No$Wb+FZT8E zr%UFptDCgy@v7iwA-BF>SX^CseOA+<@5w!LihcKAUgi`TF~M5u(4L)UH`7l|efv7D zRm)(dw9Ah-hYgP;y!!2R>YA;%-?b;54&nB5BX?Y1I?*8JU+HtRs9l@-=dF|V5d6Mc zG9hK&@#W54EB$6=xjRkLz>d?#(WH8eN}iQ)gOsKGa%Z+fzQH-EBrj?w?ueL_;_D zWzUpv|EL!(nXDc*ZRM*!v+w<9us`#q^6SqfK9c;;BfjryteJH6TzzJf-B(B5pLvYy zG7@H0%bWA;UA}Q)b?J@?yy?CQTz*+%^LLuMy$*Gm9HI2__=K1 zrdPjZ|1-3kvTfYhB~oP8GjZONC;yghTXOwr%JCW5=M?u%W9ePi=izc3%sw9NeyU{>7f%9T^Wld{`(e669%jQoBxm=H<9ox@w+TNB8bN=U_TpZ{hBS ztlj?eJlAR_R+d|Cy!oGD+a;ZO;SVOqrZ;~Tzg)7Q;|$Nb)CB)^496d^76ipUr`_zPIF;?cT3%G&O={@{E>zRldUi`PzDMzbk*=3Z6gw<9udMURTkiu**xo zTVr9K@7+1GHkDMC@t*s6+;o2Rk`p42+|KW<{IYlIcf0*EAOG}zs#B}J zD{o<7!yFwIwk-Kz*t)nswhPqaMC!$}7N)OZov_YB^0DpFDu3>`i52t3dHyrJlIV+C zcXr-d`HnQseuJyhZzG?cd#<+Q#a37C?<*z;vDChL5}{t(zi_(n<$_CYTi-q_KAUn@ z?~~`M^+hpHX00zR+vpZE>&?>krx)c-`_G9+pYnGpi4)qH9qSgoG--$LT&pL|*FVV5 zE#rM8>6Ki$-t@!UBj494ZENj3anIqQ=R5xg^;&Oqw^UE_Iq`N5|1PU=IkP#*!S~ZI z6`a%CTB8(^v2E-1rT15wep`0w$+WXcad)5FTw8l?lGDV`{70_I{+ny!vT0-fS~vNd z<~uLX{#zxGd)zTcpUaN({j8T??q+#}=j7M1Q$eXu z`Prv;>TPn17iwnpd(DrZdYScXa@;G{Pu}5{f0uFmzRI%w=?=D?51Yzu*SHHEJnk01 zch?;cw$00GG%Z&|)jhe&-Rr5mBUCbB`6Pa?_eZj^15!TeYk4z%UdyG ztKOKc^H8@?dGc?`)!X2r?d!=G)2?6Nuw-G)jyb6jkZ9j_tY1Mg=}DE;Cv7*u+0Uxx zFM7JQFm%I(Zvi#i!uHLISY2Hct+F-gZp^ege&?v`w*rszoc^+|?iXjSqwWb=-;#$@ zEpyKETdnL~y4K@nxp~Q6mxU~5+Do>5WLeQrIrXW)tJAUv1M1@6mz~XVT(w&N-db%? z(f0Jz4@l8=D}Gb$(zxgseZddzA3S}Zt0wxx z`wreey}7LC1y1sx{jBI0BVe_ys=E4m@$Z5Ic_kT%yjwP{w>a<4{wsXbtGCO!&zkCf z%l{o>0qW%Te>;Et#@o%{PHy<;ccp%9>itGLs_i09g+;4|mva--*B3vQ z->}5SQ19OIUr>d^7XH0>kdAu*|0N=Ng~HYXv*E`CDY#hz8|u_Zp|-yzE2%#m6KO@gtwZO%{#ky z`h)u?W%sw(h}-_sjOaXH6LxRwgUXx*Iu|D%Us}z6C_9^FqqBm~qqTp$ss%G1+3wZ; z=gOtxplx4Hee^rw= zEePC`o>H5adODhCsp)Dr^QJGal^>;bF8a^lIiv3B#t9ax8((<5e^XoeRq=z@qkIJwl3!UZb_-#bb`P;reDfaYDX>|3EKsoQsNh#qhE42#sa!U!NSG{3o>9b`!_9>*wv%Qa?+}Z9U(8^xAU0kpB$KHy^%}JzZE*yVWcI z;>p{;e$FedToUcf*rl;u$iVaI>_5N4T_4D^A7!2_RXO?O_c`C>@5W zGS@fMsBUWVo>6na@My8uRhNpRrtM0p(s*dRZIAV%j%~u8Pap5i?mTd4ie8`2g$#te0HNpG$OF4;H0(6op8NdC4ci@oo`rYC-S4&f9B-ieH%NOJ|x^%RKLukFI#!m zZJzAr%hTtaH;_5;Z%>IVyYlPzalb!mJ}?)mtaz1uymVQ-;l{W$WzneMr~Br)-+F4v z7wgTnTC47RrP+T5TYKiND_d5)*H3ijnDDb<>fPZiCsiE$=m4zbFm5~dDWPUvneY{*^UHU)KcUyCnb-&(SlEu!Z zd#?D4V#Vuw`@Ve)Z_m;Faws(1I{Uf5Y_zNBnMQ|WzNJa4lQgu8@ww;nJIRdmLHHPc5H+x9!E-c_P35 zGsMk1zV2#)WNXo^c~54h^v+aqyR&9Fi{ORk*O7^@LsphNUHz)6a+&}1r+eld>Zwe+ z{B&F2`E}oa-jCN_e9OlE!!Lb-$iMU6ozzoIyg1#$LRsM}`{WbPHr0gwwp+XK^Ov_l zuP$heJE=kk}O#Hkj-~h2q*ig2h8V~+2q@U zWA%@8=CCeixqWGuM&MK~Kd&&GGnWk)&V2mXZz-$l(z$EizFPC2L99l%@WbcO&AX;q z&;FgrHF@L3$eBAIYZb7|J(v5NwY#E(7 z^SAc(O&i?@v%60;>$uB%J*{ESm%i(^_CiAVHG7^nTb^7F*x~bbxgWn|=+4bHX<9Ot z(~ntHWWBpLH|{^f^@$Iv-Z!Uh?3mWme`tqp(g~M{++*6W{JWG+CKk%woBFxGtBW&U zZfl!f(_(9vuRH2ZSI&5NXVv0!UuTC*G7AfElu)=bpQj{SGk=}#!=AruWG0>A)STCS zpW(56yRD(#vcqgEe;9|fyL>!0b=4h_=!(1$zjI5Qj@;MYCO*k&qq6LQ2Vd6h(hAkI zD!=pd&9RVz$X1(pr9AVyxpk}0*3U1#tp0cY+ppE>yDvZAaalcqgJbujb48xc&6j)F z7z&TC=YJ&M9H)Nq-4c)YUw*#5E}b&DCa>bTmT1Fs+w))6@A;y7IqBl`mUFj0$#+eP znyK>X+x1k>D+@hMwST>;xyR4nbhhwP&x)eg-=g~;Z23LOE+n6I>jwFped*SAshx&x z-;(F_?QIReV$!iJFq6fDxq$tv+V1lLn|}6o9oWpczNl{MGiS-DxG(dL-$}A4*IzPK zD&)=5#joDJdjCt7y#mQMUylD#L4({It02Y(zBdDg5|5@LLwdGL6R z)Yo{f3U0rTYV%pr4r%7jbw0Y4E0?$Jr^msVk8_gtJP$j_5`Mvce{qVcV1eZd)WGE!JckJF&g7~{BUgDv3k8?>@wlbt2XFdUHxE3;JU?O$3+i* zUA1TJ{jl2X6Gq?TO#aS#(zos2+uZ8+pZ_y7l+EM+5c2)S(j;};kI_;08=r1$*zD#m zH}#D?=Yz|SH#$8u?%McK&s#7H)L2+#AyF+?_SL3qPiR+V|J8@muJW3%%jCQblqbgY zt!CP^L20k_(Kqu-S_`l3`OgrP_&I#O+sC;Rzuug#n`2ZQwI%t7zTYN0wTxNzUuL?$ ziZ$68(+6l9Y7w70x0Pxzx=Z*|#p*LO!gdaVeU zYN+*T$sE~Jch5`Mez42>vHjual|Sx%`*3&0L>0qL9G^UR{9`^|zqIe+MJch}*Loyw zKRJH+`t$YuHFXZxzv{64-%w6|O<=Xb0 zPrvU9T_g5ZrtrBk>+DH&TMxe~Yr9q?BHO<3%eVC&S8gO+S6q8UW!sdG6F)Qed;MOs zZ_oPow&&jIpITv2_e#^^ZIUckyp~2kXi}#BK%G&osff;u<9jRW=9*ndR$q8xZFlzZ z{>4)NCOlkop113?=Eaq(JoR@we_VB;aCXM8^$+j&sb2f1oMFbRnW%cpT(39D=VL5i>xxE}>^UOR{tx4W zA0->+^xLye{6B;7OMC8$vu|~;2F2amGEenm_uV50 zm;TK@s%u*ADpCCN%H&t?9#6NQTjz2&x@i6eHwpIO+qZ+0G$pWWONQ<-!kkIzwU-;5vik0rOa!d9tP8>+_({Zx{8?&RhFvy~x%Z zNtf!jKAUy+`>Z#`k>9Nr?|6DPH7@S!vmJ}QN>wZ6{exxO4_$h)bdipG0qgmwFa1of z7oAzi-=uxq?owFn&qv$7-1S+&Vw)S*vN)~ZTK{ZjXwmZEv|9cD44iM~Cw=;J`7$WW z9G$25JJ{Ixx!u~=uX=$-`VTxA7s=ot=@aT zZ|S7Vr$77qNBx|AIQZ`@Pdy`Z`%}wh8mvCQtDjmDf7?j(*yo>Dl2ikISG*}n`C>5n z(6P{I+w(tOc=N}9-QR^X-k-GldML}>y3=w+-d3icr^8&I-h0QmCNp5l+?y|xH%Eo6 z{N$WmfB3qhnw$EM{cEfDAKovrZoX9Ff%UVt+&-`KR(;{R&ED5l8XfowLoLot^~;!< znEmkMkND(}U*SjQS&N&svdrC^eat3$HRqGEyC>Ih{&Ce_W`0ff-=Y+iX=l@eO114P zULQ;>n3)p4N%_k1lj^2t?``{Tn)mCqCBwCp^#@IFw=X@_Kl5DSt1YwKchqoy%)K`A zq3Y(zg2!1t>8LQ7D_VDc|2eZ=Zt9gE{l|=AU7WpdU)!VYa7FICUzfo12LEM7p2uH@ zr(d0WTrYdxmQ|J}+id6T>f;j0JeT#!Gv@a7ulAO=d1L0jJ#f$Rz3=XQ=ZdaQEG$UL z+Y`L7y?T?e&porJo%bsI1I4a$c^)@?^H28U?pwFCboL})+n0Gc|J%gR30*I8OIHdO z$owl6YV``*Y(Z(D7Yp(|Gdw0L`tMB%{r_qKIQ@(s%XMQwJ#oV>qbI$MUbKKXQ5SB~)^J?$4 zCFkdCt=#l&^Tqj@t_cNauPocDo3(vj^2W1ik#`yk{HnVaS60sX9Fn|KQ}0pLbypkX zr#5raiskcWrEmSAexyE`!}&pf)w^|nN_D2~wz+)y+P<>OUyT+d{%44~WOb&s@R|I% z4O^q?UfG)K@ENY!DthzgkNGjboelLTWj9}0S1wc>7@NiVdD@!p(|bPfT7{^pm$_M+ zF7=wPVy3ira`mh)_BVe=TbaJw@anfu6aVEi{~4q{OR7AWlwE$fyf-y{i?Oz~c!Iy* z{S#d8R#yal_n&t9u8o_e)qcLUf3N-ZU-)&sv}a*n$m!eH_MAUbwSV5*&*`RTJ=b`g zZhE$P-TKq%x^dOLUj6s%4$ZAmFzI1NU#_)XS7yEg@Wmj07;cMTI`aN>*l%(RX?TNY`UJ}@DKi8@@@=npS z4S8#K`bQZau>75!mGk=6^f_6EmER)gU2OZ(CS)aELwGt8gScX)4ELAH_B1Is_J zYkZcAO!3!OS=_!}Ytp)PTf9HlFZ||y&^B;ut$f_Bv^&nL>K`uwtt-uc6!R~>Ypcll zKiiUjUEf=GqFn9ufqP05`#g3Z|K}X_^Z28`$EQAy{(3$fd~nuB%aWMSt6sie|E!;% zGj5)E$E#CPuEnbV85)i}HI@84an`}B{J&K0zmtC&_H4#(A>ZWJ(-{*!HU6CcGyH`_ zmanIZ&S!bapgB)(&gk-*;2s$Dt8~xjRU27DzI-(e_Sp8@_rjf>u21@dZ|z-@LQ8?yifq`TC~LwR7cqm2#!Ov)0JT_udnqI^{vk zcJ+Td_g446J+%8vM#%Tj{|pz7MtyKU-2cP9CUH?#n(Z>}rO)N|>wjJGpCLE&{_^Pc ztN8zNgg@I;9M9SNQC{QMuJ86G`#&vp-psR9M%Mf1KaU^BD$Jg&4e6?Uv^%6za%M;D zf|QN63~Rfm92Sh_ZzyrJJ+Z&^v{{g1LxJ`7>nr~J&HmCa@L@{P9hp_jQ*MR5yYGMf zNqND#=y^^rR=+v!*oD&#w zo)z&A=dSNG`OmO9OU&@jfy3{1J!fe$;tweBSDqL-Pv`I48vA6G=?4C*q82g>95qp{(3G)bMj{_63uNny}Rf{(qp-))6@lZTz+b-R;iLS z^LN)+@KJKAU%Gn9HqXlM^-VYBq}4h^Eqe-VwbcVJDJ%Th?eVft`@T*5gZFQqmSicyyKJgtui&{12;Rvobm(b7p%>9b)OX; zxBmmb?P24&;ZBo#{Xguk6WY38`1GyE>MB>Wf6r9fX0#^9@qtWX?3I6lmvvOszkg>} z=(qfpe1mcRaZ{)FetoY(wsNqfH!(cWP36fI*A;88Q*SGlxRkYI(&U@!wKexTp8wGl zTe$Lx+wSC^hD&lSzxadu>JKaJu8!y5cIHIvIriYLH#Uq9P3J0Z-`1d#Ww46fF>Xbj z^qw%gY}ebi+LN|M?U-p99Oiy8^#%{0x0A@m&CgeSfBPx^`RY4A-@Wz-SR%swVGXal zm*LYzD%Dco^hGk}CrzBN-s{0u52tAo>#9Ou1y7y%Ci&AEHNEyN%lggt@1Auo^{(Kt z0>5mp%OM9CH!W!>aI;WW_!pWS)?_+YwPIRmIP1iA9>y2hSO3_5xbOdQYl~fyhs{;@ zzGnhr0ejsz*_${Y^!?lV>fBzl1#`+@^*0=PTCu9=h~M0lojOs<8sga-u73X-Kv>0IYfWGjK_pSy(;V6 zM0lRhoA-0wB70u$Ah~ys&lND4!zQN}sEc`9Lu(1=g0}%) zLJseWXMN>ouF#5g4e2<^ers26@d4h{teE3H{9d2aUSErO87ZIMzI2oH@g;WYZFT^yS1@zfBffT+JUC(t!IoEAJuxS@hY^f@^QYNe>!|qX{cwuwf8@R*AL4jKNg*{G>tV>*KS(Jt=wRI?5V=z$;S%g zmb_khCGg3m+w<95PrXX~5WH@q_gv3)VOzGZy7sqhyYsWQD+guFvcz}mU-=k!^|AfU zSEoI<%ip|pZlOrm&9t2%Q@tL1Y~^g8Q#}9B4)1=(s0gL*?$h0!A%C7QblmxJT&3{+ z&!Cmj{NA;Hxeul8JeK%j$@RL_{Lg>*43}G2JLd3AV9T=QeE(JYxVHy4WAE8Htg@E& z7mBa#I=x#Wslzc}Xwesja$C!-MPXvg2YyDGg?rwF)~JlLo|Q!}eyxO0<*R?t-bGI!IZG57Z_zQbLa z(x%)#F=T?pIsXfMwH9AR^K2s{E2_TQH~sRlx;rcCpp?$EvrkWS_gS|ckE`_$lG?g}T@5qU^7In(-v0Hcym2sNIBUyd zEsLd^o@!UNTtE4G+r3YB<@M|q#4lWN=J86?SO1iM*e=NwGSdCF;>N!(6aO=O6g_+T z;ag+>g2e52UNGEO7E|f_VZ(epLEG}t3&&4O-oGeI{84Rs=Tqz1;q*MevT-S`j^?#Xn|W_-lW@=30wYNci>F&)qh;Emw_5F?^$a z(@y?}2bT|3i%p0DRAX| zS5~Eo+*FLQfOFvAeUM7w<>=HK=D!UQ+RSA3jLinNW7&fmPe{Y}cGXPjTX zLllxEo&|L`_HnPwtNP?0b!n=HpUmgpKApqtorfOPt#4hoY|q_UU+>z7<~u*14$4rz zLYwEVSlVaYU>w)D;*ZUxlA9+#uTKv>e^RBp`9DL=3j4KbcO#>3J3cumbgX%UZ0-4# z-`CtT>;0Lq{)cSg!#T$%-+H97XwQ7(`bqAr>E-2S%QhV3Hr{z_1^d~5wb>U<*7Kja z*laB+(N}mt-v9HD(DkepRbsn8PZNB8y5a17+4k-G|1(5{@BLx_@bcYTI?HT6zKncS z$S-W?#dT8lr&*x8+TlHJsll^?%DorGKl}G|)4P)TO`*#{`xPa&wVu89j{UE({KI&w zKam@~*Gt6j=5uLD|7ia>KCVXN;{FY5Oi$bHF5dc|!NC2?`e}8FF49M4P5#et`7qay z9_Fb!&-Q)~|8wzC>XaABKc=nM`mVC<`afpj<6pfib46!{&UH_`w$r;aD$}R;$``q* zFRQkI+5`_ucgL$0EB(D@VRvl5$LZHASKFQ!?=jl>aOqk0ck9}ww@!5EnExoruU`LU zd_)cN-VIwkdUjWruAlfNvt~!K!WZ?Q*OyfIADwhVt98OU+t{|sJl>~oLZTyo(4oAv+Nw12+tGCDrBqJ7Gx{I%-;8K$cLb6@RL z^TVtE`X~1j(|fol$1Qx2@u({!>D7vbZndjVE}v}qY%lxaUmaa86C(s16uN%z7vCtf z?!zm6mnZ+~-oGq<|3_=8Rp~~)=&hoku7BP5P5sbWr(?H{nom8a<=<&_bk4SO0_(j# z)G{A^pU)6FU8dx$+RjJUcl5MPx9_d<{`zEPQN-{1uTeqA|E8XHRzG@qv9}^iQFhbb zgiDRDvcn^<^qlc~^=#cbhpB$m*JU*?SXNLuJMtM!|$`orT>zwNmB@q24+^n`2NUg^0tu@7s*-)w5$-Sy?J@v%v+If7}A<+kn<+kf@RyMAq(Q}YVlWG3DCvcIcp z?wUgmt=Z4d3wtedJ1Co7f5cARTyeYS{9`+0!+xJF@?4XBrSy66#Zw<9p8Bw7Qq|0; z**#LTAI2@a<$q+Z*aK~w;#l1+9V)jZQ>=|@9aPM$r^;Gg3tMRSrsql&ORspR$;k;q z$-BG!*a}1ss()GU)KZ!7u4Y9-{NeP$q}a?82d_U3)@F>@Rd#L9 z$>RYUSJr*sXt_#E+%a9?i4ayN(@xE$Dv9p55-W%*HLVt4r4xTr1VJEooX6 zY@PjNK1aobTUw8N1mDM&KJQ&R?RMhq?Q2UPZp@l$7uL^g`S8}vHr?=^Ey9mX<s= z2hs_FaO2H2ceA_2JHP!>epykiQW;b<+u&#TJ@90TqgpT9OC zOI+c}v$a3!exICV&c0#IT(gz)S`0T#GY+dQ|IijKp&M{=yT!WZM{I`gf(pOT!VU_9&h{Ri(mbl2_SUmAaR zjb>qKD$k`=JQ`^Z9+E1L)vxVi-I4QT*7ttqAG^HmxihD|He)F(R5O0j5WeR1Do(Q+ zUYoVgHm~&4yKR5$_~x3xtGQ|J9AWz^Kf0Vs$&vfI^AW#@>8ZJwo_}1&9k$cU$7dNPJ#nv>kid2CdB;s(?dLkfUCeD~b-hn|f}XqSjUWC|zqR$xb`^Iw zcZL zj?e7Q@9XBcnTE7$xpz+~IJ2Q*d0df!jic7gXwl=Z)^V7wUU@G+$#Y%RuiUpi*DRv) zzT4`2mlkIiDZjs2Z#Cb{k8aZ0&E`|<^FC^={AqLaa9iTMQ|lO?Jl%V?cJYeW)3}%9 zvKDXK$M~bP=v$rX#=U+lOm4~Z8W!t+PK>*2->XtxyR6Reb?oP(tMsSuvh(IX{Q1m- zRrftku0J{bpYpxKrbk*iUdP$5Il| z4Oy2_QJlHk=X=(#$ZU`AYm?R8)*IXW z`l3AZfo)Ih%&+`CUr&o&o(WEzdrC`XrVANO?3pz`zBbN1atCHmF=zyK){IdBTeizEl(UB>&x$~bvRBHW{-^$-2 zt|k3vXw6)*_eOIWKuqbVumy?Q8Sf)_<+EUVQr8r}b~U44zCoe%VfL zch{%qQPYIXIwn^9XK4J-&|6dgk@e7z<{~lWfBIwIf|>srrmd+Dj#qA(zV+Njq4)J?YX4^6 z)1DtMA3EjF_VPc&m*DHW{@ppA*DeTMwK~r}b?5g#H6LdEx@-ThtLm5Vx3?A_zNG)1 z@}J>i(|+y8H8+zhp6eZPy+1YhkE&UD;>u4Cm+h^0e%xMrY}*!Jmo?ea=9|OS-gA>Mw4)DfzUxCG>s#!b1Jud7S4KmHEB=68rUS?zx_B*>J}0prxy;BJ+ON zyx;g@+O3&f2LBn>di`pd#Js&Y`O>lv&s*=GblY*}(&K0UUf3P}Q)?aWtk!gKS(NdQ zu0L&Sy#l8$UinwB@!;cCmx9(@k$!pQQNG??M;!_N!pLC1*v+%v=6|^w)3o*Ut6ybz z&&spy+HiH{Y3D=dKHZ5Gd0xG6n^fE7rW>Z4L1*sQU)vF@cRp<2)i@3Trp0;@6S}O6 z-~X#BEDxx4_LzU-itdw+Nluo*n|zX|+WzWaR(Z5E^pI2VQ{VWF4<1-F3w!gwT@^fO z+3c9J*0GiU8DiJh@~x|Nol$gkc6s%j&k^#sT#vI&xbu9{m4!`D@2qhb`kk7w>C2>P zDwBg=3ayI!`Q+0a{VV?&zV4r!z9+mtFSSoeq-V7~!+(Zg-w%CrSG)>8vokTTw=@3! z@73>r@t=@g%CV{_FU;d}#-r7zrQPOQlO3x?)GM_UdKpcCY)-aJ{r{)3ZO@impyBEsL4Jn`-*mzD{#d&4ksHjyzyIskWs} ze8Q8X>F)&>rOr%c5c18-m_9#sOT^U%+i2O7{~0X)XivCy^bN-962tmgC? zNKAei^6uUJOdSdSAnmpNhu=)(znj4Ccr;+&r9;e9{%RlV%~0R?OEqS@s8#;`aEsNm zCo3MX2~4kiYImt_>f+UztBOvUZC|m@>6@<0E5qo6lI3ZKSpO-%e|fa(i?ZLAoVoqy zK1c1?vuV|oMNe*T+O~b?-CM7ERvCOXnYDPs)AP?`mcCuLe#y~icW>?7F8}GC&6ecl z!GCNfSRShmO_ zAA{)8m)okQEnf3ekXg$8-^LTCR{i=txsUxnL)>0zmk$SB!W5s@@Xu_ov*Nq|eAaQ9 zmzOt9-u6a?zyEJMaRB9tIEB-`p>%bll3YMkBe)y%|3l-ay((zwmWl+vDBv- zzq*cHF}cdH(lJKl_2r)))rvgFw*mQ_v*9%4zumwE=T*Ym7Ume;-sY9Vueo@%Vb^WFI*GGzUsyo z^`qVqUa!1MzGPoD&U^RShB-uK@=CQ8vnO8JD*iEEb>YM$ty+o1eLL251O#rfsqss< zIu-1>JA2u(Yt01;m1-w=?rS`rQ~&ip!_qun-x~}PbFSMySj+bBm&H51$VozuF2~O* z{d&IP<=1Zyt}nd#qhN`Gj*G^(_14l>g)6ST`K>2)_;L1w$7Xxy#I5?h`*n5w{OQiq zcI=wcJhlGBHP@>*iyTbv#=W$Qu=KyQ^KP)O8~f9PqI0>vyie;pb6e}^iek5N1I1mR zVu}y0-EHgBDv|a0>kWOSsY;!(%^LzYq;|fsSnG1p#yvMUKU} z%{}^8SB0@2eN}Sh(Tc0Ri_Us?PgZ<=G<4#3fdxJDquOqt+gUq7+0JT$Mf}RQmsZ@1 ze&xH;l||#+n}V*n=RudO%V-RZj79+I%f{&kGq#N<_3QYV`X0`zQ-D{FPXephS%x8lN; zg;%%K)Mwm0EtB#vjoEPHbBVl}7V7Nmva8pv6PvUA)U5r<&p-Y7E$Yqp`rMqUCbyn# z-Zp>wdGD9i^V92&2hZ+jtmr+7I6d}c;nRvoKaH<;{%1JeTYdhGcHy`AZFQ=XF9$0B zXHZyL^YY`hK=~uy2mEvXGdzA9FFrN!KSS#u7kQWe3??#yq<&k7j!Xl#P?5m&n z@$D%VYX=5C2HDl?epD{j7TuAm=J_}L-3r@%d+W8H1Q?DUkzneHMr&L4gEp55JAP_h1)vR~7}XSGvf^3sD% zw(Z$&SM||!)?wupvf3S2E(lz`^J5eAT>Yvk&Cj0g+2wuz!tXtY>ffC7uNL{Esz343 z>FBiBi*Y^^HZZFf%V_>NZ+G+C`Za%KKis<>aA{`V+Qri}1J-oBl8p2?$Rf9(@9M|7 z@6Vjce$U@lXTEjkhranWCpMT~T~jRaJ?}=ObM85|!a3jie7qAsm<+}i_u9T9-e}(gYJHZ@9kOjpW$$n+4QMf zFFy=gzr(oc4gY2{kC*YTHC`V@%o7i7uw2jfQT5c8-m?XdwNB5UW>ogoZgtxRkudpN z*A|QF{aN*&Vd9DV2cPZesTVw2ZqL8RZhFvBkwR9V2MpR>_jqrtkNgo`$-C#H^~7V^ z;;Vb&jxXm9?v46#eSa>0+=YKKE+q%G-R#~~g)=^W&*z@-PSoLOb#8xmuJR=&wwSl; z6@E-!>sqQZ+hg6EP%Fcw@8)Yxcx^@yj1)4X?>QU*a3hydOELu4&nOc6IB7d7feCF3+hJyz^(LZT9Wb{|t@u z#IAn%&#)zHmg=6(LbA&olBagW@az&elDyI4K^4~r|C_TT+dY0veHs&EQ+W5*E|r?M zl_INo8jm@38u+i2{rT&6(8tn+m%g#b?~Yrm6|(YF(9QYG{l}9FOI8MMHwo)|^}FhR zbj|r`HSr%dADR`iWs$4o;fQRI z^~@&)s|Pb8)skn{bx6G+u?_z{;3kDZm(GK@3&-BX;Vy=*1N`S z^3#>~udQxBtk2HtI$3jKoc+V+fh8^f8LIa6{qSCMJ5niMJKR@m>ZExmo*g|`;j=6F zuzpqa>|M_fzsNQD^e^I^t@cry_+`3l-Yp2fI8X0m?wVbduB9(u$J_k4AKxL^PocCti zW!wEobIFwjZ&lvy4g4y9Xgyo>>!{kjZxlRvKCYR#?UK=w6dCy}o5~N`2MhbRnlE{)kvI zE}Pgcw_qFpMG^dY!Mp6_#?dj(d#3V!V}!pc4)t3oGjb9UNdCQ^VK=O zU(K-5ljfUhRoI;!t+HPw>xZ_Rr&@rr^qr>XGV}dU?d$rWe)!6+O_6anA793)e)yO1 zc(+^L8SPi{EEV%E-S!F5S@3q<9GS$R#ijh>9jhN1R9FNbT&=Hs{!itDA6tIh=3uj3 zee{oG&PHpV64Uqhh5op*UfSU%`XEkiXV}CI)z>Ue91Qu+@89-1Nxd~+ps;F9!pcWm z?1bLz{OI&zvXJXB-+e^|hgGL9FPwZ`UVr79w_c9TXTv_EzPP-naMAs(=Wj0V4rpCE zz3#xq_l%#aHDj7@vpn0C;pjKJr=Q>Cs5f^{Z#oiS_s0x~J2l zV7kDXE@_r@7P(5B-`6Mq`2OHOL-Uv0GnaO|3vS++BvcvdsBWW?!}x}QXYA?bp^`-f{f#?W321!e34PbMayMF1Pv1Ww(_T z9Nt=%7b4y9-PYglYp3q4*jODuqqz}PT`x^vUR{zSb!21Vw@v;l*6YoAp053>_L(t% zdr_;X$l{wS)9& zRmY2MS_Hd3#U>?OGF)$$Ssh>Un@894uWNPgx!?#N*;ihh<}~qfn7)r^HnFZ3%`E%A zu|;?8WR2q|6<%?iJig+*g~Ips>{q1=k5=cusb9BkuHDW|o5gQVsu&$>;gfA{vwVHR z<zLwMd;lIE;Pw)MfT)S7L{TY+0Q_8qc z9`iV7)SKd5yqiROiyz7#Fy59?Z|7rg@Z+=CwPxaGdSC_!n00RcuR{hp5 zN2Yx~b9;K7Rf*)k{SSSvJY}76?Rc}Q%Wj{?TMO=a&D}je^rTnCR_z*Vxu+klALy)Q zvOdP=zBKp8<%0$hw>EOHu`kW2G5M&vcJ3r?qdv|10((O9i}N1Fl&tqMd7&kjekANz zTB)&j_UYp1=Y?;sG1~QbX~C^oJO=BYAD!N+M;xW9O!>%utJfGYu0ML8FmKwWQfRIanJX5{eDIId_SVkjTNOp68#(Zfktxx#kLMk>UHe;!N`?Kh&R^E*Cv6 zBlWNOVVu%Z9T5%xiq)ns|1&WBaoa0?wxpK%gY%KgS@GgE=2@S__)99zFEac$^~HaN zZNGCbKFI$DK49*_{LRKE?#tTfPAL4g{Pll^n0b32e|vWRn@q&(t)NZJCv05S&F`2Q z@=!W5=;hyE?RA3nn|!POdHnd6X*}y)iLQ74bS)txM$zZ%j@$Hv_4Tj#so->kM}GRf zeXILlo;F%4wYtLmyZsMMdGCXgyG|Px^~{}e>G$F~-t$g9ySH-1%!o->&)vV1t{~O)?6>W! z?z20d%zC-F?djEda_Mumw)aGMdDpDsHhjQ%W!AS|_9M;ym)^cfocU*mQpDuK=Ufbu ze^wt^`@APkF-=~Px94Bzh1>Ca=D6?dGj1>r?Ov`nwWo+DmgCgoS-!jVcmLyj5p}#% zs-Ui@_KUYuPzw4Y|=63n4+jHArMttAowYF1att%Jj-g9#f~9F}=fb@gnkPUZKZ-rXOYKZjc#KII>LZRMPRrTj%FHrE$lpLJ~RCr^{f zG2)i$U29EN?@%n*-DkPptyeDiu`$o_+h(_IgCF*7*=66pxXa+8%_fsgMRiGjjL-j0 z*t&OB#nNR?JT3oBpO%?FO!io$&cGUA`789Y?&WnZ`RCV*K8M~z!n0r8$wX1Y?VYCf zlB`#|I%jt3#(aHxfse2HV%c>Cp`<)*rO1elcPG^H<~lXm+_`Nw?^?#25?PHWh=G_#<)4ZJd&+mA!taE}7p6_yg^j#nqw6giowbF0%?d^)+$GC2Nv$;?}_sephyc7Q!LhjG4%$vM-$@#r) ziF|QY0Y8^S?B8?8Q*HCwypIKUu6jS;5x-ZO@pXt4_`0OGOF`EqrOVFoGM!u%@s*$N z_1i3w{A0GSmrOr;?!w#8o{z8X$vPYyw4hynZU(Q%+P0omGjeX( z=CvkI{#-pBe>Yv-)T{b~`@JX*#7xX5X0g`k!c4{!-IF z4-Z7n6lVB5_2hqso2> z`s4neZJT}{?bnGgntXh1k=4Fc=}F#UQm4yaPn7;ud^CKwxI^us`(B?zwf9DTD>eKx z<@R#6=?kWRkF8u?rTd>@+N%c-u3HzY%sw$e^w*WZcn%eYZN`^pz5BJ@M5ljRbjm~+i(Apat^(0tTW_`=&`_a4Qt=zSP z={mX(J(`mxZ!JidZ>?A(d<=4P(y@B27rFUMrnL6!)UMiCFxgXCrdia@c+S$ayOZK( z{Y$@Tzd3F}sXli_(}Qhq{KV})@PJmfE`BuSUwrphmh*qMCjXlC{rrt5Cu*1<8EZ|r zpZoqlLk#GSn^URr((zNA!V90&@5z2tw4*pZ^wDqovvQ&~{+k|YT}|3Q+y8f&x^k`E zBL~yo)gEH!V&<)Ke;%eXo#pxZs>9dvj;wvM@C5s_U%$d%RAkwG@_2ggv&u@ZpsKxs z^QBDs1VuK>HH3#Q$O!h`qBXtv%72E|)E`Axyfr4at8QE8?jQ9l`9XTq+pl81PaTT; z7VR&3$g`MtT7v!7k6E9lAKImQ@9zBvYjbb@OjBAsXYU-p@(1i~@3#DB=)NblXPR25 z_vA_Ls|@~aeYJnvqj#4Q;vu!#OXY*tqRdt5q1 z^ml)bNV}(;D!ORRde8c&p8pwU-fv&_@}ZV~{7HG~7#F^ZRkz9}7O#BOnakWNapzop zqkC}QU-zHSw&Wd?>3UZuo9Ut4F@gJRr^N3v`RT8G>lQw0KK!7dE3^7jS^v6s|2*s3 z*B`W0KDU|GtNw7;v+2uIU;Ss`{weX@j`<^l%VZb#{b4y0GpEY3Sv{G+Z~5iz^;yqM znOA0BUb}C3YH6~u+DF+VzS5#9;A<6Zeuv-L&-F((w>Ya`N%Qfgt$XSpc3XS9X>=KA zfAlh5wX*n%=Rcm`XHN4rPP4smC}gU=erL_Pcl*BeH>{1TUapxhvU!Je*RiD?a(imC zT}@U$>pnB5lFQ9${@$Nue=5JN&-fU-%hjZTZ|cD;?@12tFYS~|)bu)KX4ht;=+!Hq z8MJzKt#0bi?LX#(wLjdw*Ezh@=){EeY5_ZSitOUo8K1X!+?RdbM4!ui!fM`qB4x~f zp7k?kdYXJZ-p6?S$Mq|6Odot_zwB0C^gMs5=BagdWjB?*L<(fo+nzstw$e7b>d*8^ zf2!^~KU@8t|76~N8<#rKv#-JwjkvB~x-ay{K0Bj-V@T2-=_7?&){L)XOjmlfye)oZ z^ybjC?Dpb9o6B*Rx4S(v)41`V@2dYHJCQwC#5|YHT^M$vJ55^m@8h>`58B=RWgEc6 zn^hxLGX1z<#--IJ<+ryb&t11F+O~q#@r|F;_2qth(;biT2S5BcGb~=_l4zk}p4Do# zOMAEM-T$EEO_9|8wm;#Ek6pU+GWdMXikLgMH7A*dGHgs@3*q^iU?r0-+M<8@Yt~=M z3ws1pb~zMv&)qlm>3yLu+12h7lp4EU&W#LOe%4~yzsE-oCuk&Z%FHY>)QV;)_n3?rSOt z?D=PUoadPDXVsMcrAG>KHG;ndt$3=LSv%>c{?#cqybr|;j@n+RR4u*x)Zk~ZZHKb; z{_{E4mqh;vt5+|dRQP4x_J{uMN&9wmST$L!ubO?Z%;2T;HodZ6VP3s4*`+GyPCf%) zeG#I#ZhCF>yZ;R9ouAZtdl)FUgRdtB zzSfYC`o;b&#e&IJbjMJ6JLk2 zK6@9r`b+SUd;FWWUiM~*dHZGk{5`p;GU7(8%qv$PNvdu7zVOGKpKe~8Be!}BUHaVn zpFypE{@X8i-4eVVJ}6kI1%&)#UjJp4?xMJRuMMMB_G>;l*}sE5xc}*o@I_f&%myp> zs3&c@v;OqyZT?@@MWh9H6>WTX?ZFw@uz%d+BBBqJ8%}&0GJdY;;-8llOf0 zex17Iq8DN+vLcdCJGnoMd-!4X!EM*WUVKupl$*Nq@qMnFx1tPP0vjW2WW6SQ+myas zPUYZ(joi#moT>{yEnB+$XXUBu+G}noYYQ0Ex>il^)}5regn=iVb!Fq{a67r8mN(Uw z+r;{``OjQ?@o-B%e_Z_QT#2dEL=;Y{e@yriU|aEv|I+ra_G~}qos@cX=v=JZb(>0t zEvqb;;TK(a?DDlfa&0=6i!QPses9uMy*$m`^_;EttW_fSr9andBWSD_Od530?ihcx1Tm=%-J0_8<72H6G4?D^+*>wch=Q*Z(tkZGTXy z@+}t;BRXd8@-IcE_JTyb%(Y}pQ??k4ZefQ_DbzNK8^oNl=%%`^> z>TA$rH4nIOkHOi^{b77)Mg2iBXAiy;J8!>?OaG|vx_wI}lZM0^?SyoW;%!wo%S9f3 zjA(Cf5%P9^e%9-xn`6|YJ>JVbpBgrH&0A7meQU3ITyN+(?f$D%L`^=JKIK%hSgy0U zW1-5m7iT_PZ#L!rtE=Ai;;2pcUgeTgeLGm1=hX$zyYnGSw%FyPUCX*()20?pd%6d?s+oHRsRC)@( z?3yMcM!v@x3SX3M-7lMd`F_OKNILTg2RqxI>5&1O4Aw>MZ0^|^!e7sL$Z)m$?JMhU zy_vdS?EaI=X&V>c-Lvs1W9AceMuuaxulIfMZ;6vG5vu$5aA*3l!Z-WwpZ~(S=vHU` z_T))r{Yz^(KlC5k5H}@LM5=2>*N*PMXxRvz*^HBS&7A96nKSvSzJ2(QlC3wNsUNz0 zobNFwv)t6qm6`Lx9AlF9?f7WllCyTprBmH=w|;)!yJm6IBZmdarl&g(d9`h~eKWa3 zGwpi6Ui-wXZ5pSF7VUU`;oW=F6>k^M(6T&{W?#U!L-zd7@9SNzI`ACY>Fcs5-0-~M zZIv8JKjS7#(VLCyO=kK0+^2bJ!&Y_4E4`O8x6EC)e$~JIyk{l%Ft3-`^H${VhWhiI z5;}9+c@NEdKBwe;%(i;rsZb?)qfZtIHQsJ)o|W% zR!gV9b{hYz)_c!qxV7iIU(h|x^a69yUT*>0inS77R$uErvm=;m;)Lbzs|#;`eBL+p ztsLym8(U9D6|N_hElc%6rR81a1eQ8=tqy|M-*&wZcfWNGSFqOIwf($)@xK$_|FXY~ z+qgUYzXMCAy^6>~e!{a~MujCniXr29Xb>hY1?U$x34VSl$J1Oqe z#@zDZ-sS1DmVC{9ov-@z=hqkM|IU2lUtSR$-*`FGxb65KX8B9|3V%#zn0~aXTX6n; zgTL8t`ng_S%$$@R_Mt)KNbm7KJoR2b#gD(@?=V#Y-C*-*!^D!!vp&B4m+`?!>f`Z` zx?X29Rn7l1Ogi$Zx8Co*^v|5YjR$2{x6M;;bCzjlf!>5A--p{dCQQCD|9QMejl#zotB}m;%%Y$9rkW{nUs$^IKo@ zS+%>X6#g?@Sbf5dA$xOtP1=XEyLT$Co4tQYPWH9>Jh9u0o$7CbHVr?B$!=Ua?ML^N zLz6Fm_y5nJ6=LgSGUvlo{pUZGpI9$HEgZM-A@`K7x14rUpKSJwZEIaAEE1F_sb$AYq->6flSeozr z@ZkBq73(|lStgnBsx4iA(m=WXbM9sGL&C5>hnzNXFR{OzE z9W}WN{i@to-roOIYu55|yKl-Svn=gzhxJLUpQ?3wPP(*T{W5#0FPZK)4{m;Jcy*e# zpv3pgI*s46&L1yyU&it0;P=|>(|c+kiS8}8UVU!yN0)hFcb|V=v(`Vl^7FKHT03S< zO+Iyg`GJ%jHoW0cI{neR_?3$z#e^D5{CBMSe!cSK-NN@7#GFN`hTk~1SJKVOme9q^{LqaRHH*Xj0TH3ns z&4Vwlx}M+7v~Sp_^45N-K3im|Uazu+Z{jrT(Eb?`jTeNNo_s&>WxdEO-y@S_-4E|| z{!QQ>k$=o6Yhgf$_sSr&U^FntTBhvd=)SA^kT#H zoA(L*xO4jlx0|>*zs__2hLb8ik#qNKJ*o1^)AseFmqu>{*&_QG&Ie^**^)0HEo;SX zF?Y|7&dTJVZhdqqLxSrgyZ3)qBAU-iJka=p+;*$0!{ z4xTr;>wSdZK)JR!{QK^cs;kepJ7zzN}pT@XC{?LCN*{tcNYCLFMUJlMF)& zrr6Gr>$v{m&#UPg$A4e_!hYCa*me1_`39n&#pYIS{Pl^q%*wq(rICUE__ZyQrb^8@ z@p!3~3 z4xL-Ra$ju2p{Id){6YIbH+fw*t+_qt>g(5Qp3gcp^Vg*8^}OCw$>w55G#ML%=AHue(&0QEBoiD+#;ozGy(Z8l6b z*Fp2CWf7ktr8M0k0;#laWF5f>NT z-uW`Ea;jB9V6^h3JisM~=#2@<@oq1aBgT>eN6TZ}X96303V{GpH&L^TmW!>|8N76Qao!Jz5^0JOuUv2jL4O{L+ zx$XR>XPRhfyXHTGT7siu@8=s|*Jd-?-dUubaWC9m0{{_$223;(9S?cR%ZP9o4 z&gKUbR$0yee5dQ%ebx#ql~$!K+m17c9Y6E$P4!pPuObzj_W8=Edls8-di%G`&b{r2 z)v~I)S(BbD7Ejk(f3j}vi#<2$&hAouy8T!@&)qwlR(MY;@RJull&1@YkWLP^~uDkAv@y=UmyRvuKn9Kf1_-cul}#&rx)_o z_aFbLCN14DeZO3EWYo3i*&p8*-#oLUUhhy^MGc?WyE#8Y*1fx3wE6nwt^Hm4Uw-fQ zOZ7c{clrd)S#^uQr3-E@@N?fn>wZXFY{R>Xj>nhw*)5Iq+|Kc$Zf?uz z7Z+PHAFYn7&E5K^UvAH)U0fas{+BlDxlGvj*-_@}dhe@iY!*4jgln$8rM#MH>o#f8 z@=WD(=RWC0RC@)b>*lUnQm&@^r|U+0FiXKz??ZLc+jn2TW!d+&hrLh9BCmSB<8j%~ zU(aXjA3U4(HLRZh?xHq(6Z6Phi|09Os9#9vkIUY-`LNe=)vp^rMb_Fpo5%ZTXK=r9 zm~Xt_wzB>A>$X|WG!^XM8?t<_UIA}L%pa?dUl*Lc*Q`<>J;VP~)e;;1^{c1u*y>%t zR_>`ap>|))#gk6+KE+q)xTW{Ry_LNENB^JnN6kG4cqaQ?E|myNPfdtkmhJZ5rBAv% zyliU6L6w9$rmZ#X4>=BVcP=vWd#)wx{_a@C@%_&8pPmc(D5C7SeSN;shMR8L;j(^n zgu0?m?%({q^xvN2H;-2vH9y_N|E-PxY0&B9(*FIw!dJblvzjz!C3xv6v4R#bWW zwD(JVTdx+HrC&Ym#9zKXc251fR_lVk+Ds4Fy31$&9{Z>hJ9Y@HOt&ukb$!9BvW1*1 z;o^^cP1QO+wy`Vp9ozk(qT}pRf7x`i?z7hvr;E>BzQk&dY6GK;tD51YBbK)q zYzmHif?Sz#cE#@KozL!D97xQ(vYIbdW&WzZ3l1~#k(_jCZ^Q3Hh-^}Fg zeRH$8yS3-Y&;PPMZu-G;gWK;jIv!uznValwAjVqYTIsjd!+J~YlcG0jYBF11nf>+G z-_uty+o=CYDD#S?dtNQwnRjn0=*EnYChh)OHf_j_8D2N?!@kLGsw)1^aLsO;*jB5F zHNWKNr_W3?<_y#3UY)BOyS?_Tb*_)7MAqD`0`B+L&8X3y9R|5EE#r2D?A7u-%QuGeb3S^_$q0+NSoZb8W$Ad6 z)63sv9iDy8?$aOBc$0Mh+T9IVi+$&Lu1x;$y`y*6nUa-@!_Es$?cHJVG@{8~Fl_$@ z^gE_5p6a!=oOn_ya++@Ot|0H~Etme})=x50+Si&tHL~sL6TX}4ru$8L^^zHW$<(i~ z^432p+oNXgoUhNd|J`Hd_wvE7*k9jYZg>3Qd$zMC97@{{H83z%Fzwv9_2p-cpz!p~ zhb`lbZ+Z*%PFl`(cY65qm$%n1e4d|P60W+T@MYxnYty|f6n;JL`g%6{(B~+{`(pN7 zkH2~=N-B#UlyP~eUnw6MuW|TMra9=IDXW>YjGUYJ_o}w7ncdZC+}w5JdXDlmv#_|W z?2UU=(^s4{+>vap{Z_C|E1+sl@_M^Fb#X_u0;Y;v^lckLPdt>ERe<(l7o%?M+|Hgej{9h^~RQ9&>6fEEQJdfdB z_Pkvm_;4BFUvgc!SUV=2yUQNrpY<|#!QQFNq8j|`qjrDz z&v5Y2J;P6(c`3(dJShD4;@iLa337AuAIx6AxpJN-v)t6@kFt-I%5MyhJ-^|^r(HX8 zbmWqQr}@@sFJJxs-u-HuN!8Mztgt5gb@hysdPa*c?TwDS7SeTL;)^s(S*0H2bLxuIc zy6o#6m+WLBUwspFPf2a_oxgjY@$Pb#ro)Sw{3?zoaEQJNUD+PcZ~E@fHals?rn5^s z)~qc0bWrzc_WkXDWc8PxD|uxpU$xr5ejel6x7iQ*`%9kj=4bOQW;RZII7L~jueJFx z%ku@gJ#tm)Y>yBA)84A$ztl+Z`uC6X|ITXl>M4EZRPpBA=7Nya(wpW#V@2*29ap*P z-F;$GNT2ifer3~bHkO6_=H(m(l^&mp?3PRXS=Cb~Zq>JDwe*aK5}!SuJl-JpT>kmq z%WIv(o-VT7SXq{HC7CPk%dD{c_#blR)l#!!zKbVRa-7+DFz@ikKiT1L!gF@&Hh)=n z`%oNT`nE3V?AnbB4mDVXeOvh8cXvcNXgc8WmDQSN4`ul;ZkSmsCD3aVntgulw*3^x}>2N(3J^AWe$BP3i)^515dbg)sS^0!dhi?T< zw#=>#Ro-cs|D=9S*b%E4S_W6W5ABoQw(I&WOV83C_C6sa>3PpD6dtenE%WWVJp0z} z51W5fJ+f##kfGX-aCjyqhpvHtM;NSU3& zrflow`#y&mE7=7cSs=4gdDZ+=`-*>@T>Q$a{RsEVwbM*niEzgYS?my&T^_Q7lt2p<_`A&^wg9|-btJU}aG~WLse0l43 zbDf*!dIrV^LRIQ2&x1DjN?&-Z#&K!YKhsa=8`Qgajn1D+3SsiAEh_%?Z0~;t$TbNn z#~;VpdUd}pn(}-8l7|MxHP&8j;_jzrZ!cT-pFynp+s0*)QN9TuR<(-vyC>U~^>{hv8McZVt$hqX873VBZnVpmsx9Z}WuQ{~y#J=#?pVipU> zJ3YF>e|=$;&{6Yi$FJV!+#)Tu$!%h|#ryDoDw)>|ZrL5!t9{N!`mz7Us8yYY$JZJk zy=P*+(dg&Q$Jh3Xb}U&@^wmzQ($21O{?^=2cRu%vt7MzZIA$Efw#@x(tbNBZ)eWue`iR}1Rgz~t zGu13lN!#&ZL%ChQ{Snv88DH+-OkA+*qwl-U0*SVsSl3UztD8hWRXusApm zZPmPMbIpEkPe1tAS-Q8^9(F5;ol5jU*&~e%ud+{=&f%06y;HG2M%>6+{3Q5VkZ15~ zK^E5NaXKx&63cZrWiO9|YM(vVFYgEU+A|G$mxivNRU$nRbS=o$cXEs$BR2FJ{P>ey zrC9Nyb^kdZ7kbj3zg3? zPocMh*tkZSnz-Mr-@HUjPU%D4{575&y~~_bf_5-o?J~2p$qVkQO4_x*<5p~sSpUZG zr4`HH{AYM{{!KkY=C|7)x19cU>iMtho{!#3N#B@RbLL6ab)VHit>!HKd~K04k_;yt z@$y{;xfaA%?M~93{|tc)lh}*9UfFoA=uF8mD~_ps^7yRGe+JRYkj0g;^7VbIB?1B_ zTgNj*95=m^<<8Kc{px)CKDo=sruDpVIcg2iTvp4&HzWmkRu|$^H z&sV}Q-## zy|U`=y2^L^L_7*(zV6BTeqjE?mr+({Z%lHtTr*qqz)p4Bqm@@4{fzt;aqC0rg89XF z_X)fd`z|h6*^u0~^^54W&Sggzr)Z_;)|~wC{fKtz#^!{sFT3x{Pv7_nWas_nwO(`0 zmhSvi<2mhdVa1MflfV19Kl0rpc*jFnHv9P3HK2t2V}Fde-kWI4^%ht4%8g~Nv;6%v z-ThjCKX+5Wim#S`6PS2w*?+63?%TZBH@{p(-?aB&hu)hVJq@QKgy*DekYy8>?X7vg z!gJ@wxP`w>vghBJ)wb>7wx3P+zkIeowl|{a80YDQA0p;wM+<8Nlok2b?O*tHe|Jf* zovguI(A_VGj~BX3H)3I4x$Zy15j$&hv!yoY?rnV{2TS79Wurt*I^TU*7u|XAUg*se zSv&4rEkAf|rRtf4#*-%>ZQLsP$=`J4!|bbVPbKDQPd&OSeLvTQX}bHi*{%8Ez2L^y zSteaOk7m`lUCvS5oUfzr_1T}T;`|%4Rf~KIUwebn@rlTqGap~absY%`v8=jg>oM&}?{;QOlt5+(Z*O8?ywy=D*=T_jexfj3PY)$p&Td2Ot=&k;I z@9Vl-H7=hq`^2U>!F>HkJr9c$C(c=%t^NGry8|pe&kt8G^R12ju>IKmoBvoY=DN)I z^yP=}`XyP~H-cKtmKuMqnqnBSXsQJirjIW_*18`FQyszvXY= znrK^h>FZbiLvy2lryY;kt-D(~*xtea>-wp7%IBZ{m>=l#pW$?w{n{Ea*_F>L+U4!f zN*3%A{SDUG`tJKJ34F>WA;g^@j!Doy&{<&)~YZI{xjBXSQ1GvQz877{)Ws3@kWr z@Ub@cKg0H!&u`8tv|K9nv7TT5q4s>;dw26rur0f+zfJV#PSKXj-_=%}U8Q5r7_7p- z$35%!jfa+xPfffTY#&jzYRi+VseQY3JQybYD|x-PC^DS&Y~|l|Yt}4&E}FPiv43w& z(1DY-{Y#e~HCfKRQu_MzqnoF#iQe7&Tyj;>z3DHq*k*+L>X<7&dc1jk{-P@3iO)_= zWODn)tdK7E^~JP%3R8vUQY(G8EuZ~hqPAg@Xj#uYl`l-YZT0>3?dVLIAaOY1?eVky z^wP(|^ zq=FNsrpc77lk%JT-EO`?pKb7d%~{u7eB^DoZeQAJEXTD^d+HVQTWm%j7Viz*aLu7; z?NrIf>MPd!MfhiPANesW#_=nUyJ~pa`LO;Y#w^EYWc7Yq^XYl<^N;JSbOXKqzEZj3 z_~Pn`4Sv7no%Ph0JzUb8ef!*=Yc7}GsmxmQUG<#js_W&QLPBT1$Zfst&3CQi=bXBN zRdGR8vg$2)a@PZiGeA-_#!T%HFwvn#nGp5h>$?n{-H?{4SdJ><+gNMbh>aE`B zZs~68k(BIwRe1SjOvJ6iUjN$pzK1P#ZT--hxaii^`%CXV*?w!b_oQgk&g$|xpQElz z`7xfbpSi}?*>9TuOo{E+7W2QEedp!be|tI19*K#knIE+Mq`mxd=}N`Gttb9upMC$n zcQqsYwh_nA$v3X2<_OPv=J9jQ?#_qpD_(d-Exxq;`qPqw#Sz!BTyZn^e74|`4TTqH ziEoeYWVn`dDbe$+3n(qcWO>RSYW&Plmt-Bj(5v~T@{^4}x5)1e3fuY8PWr06-(`iZ z?ulEA94!y3tAABncQ<>}sU3RRlP)~iyT8L@#l>TVZ3%S=ZjQ`5UY^a<>(_|cS@w7q z?81?SPp57S{cxcq;b+d;S`)2%_r*@?MqCevU8S_RPjdQ;Y^GoLvh(+T<`2+b&a-mw z%tz_Q$AYgdDKYy3xo>3Y){iVFCFByt*wO`(Ea0+VyL~@q4Q_#m?l9)3&NGL%mB$<5Gv!*4-(M!kwJ# z%kH_q?m9aQa+lJgi(A>}eLm4l)wUx*6-fmr9TM}Q} zAKHH;nB(I!sl~Oc_w2m$2|*7KJa>Xb&+ zoD%zLte#no*d9GgC^7QJQAMX@GLl>QVI@wa?y7PnE zhnF8zS^a6x8BR-^6)*pse;(ue_t%jf^2TxpuAOh6_dc-SY~$RnvS~I9g_r*`Tz#co z<0}4U-52-ilb;n-Huc!PT=Hhx?)N|H(reB3YcJ!Tb!_hy?kCe$DqUQ5i+i)-`(vz* zk%W6J*&)HR}Uw^)SQPm46(JsH+dNU0+W!nGzmM(x5Z;lNJV|fce}*T9|4cu(A6@xp zz2yCMRXgohu3z|{A%#0^%Lnz2#YsnIpS|;+;kxO62Cko%AN`#iQ*rK}Ym&i}b7gv_2!F`x>jO+I~A6 zixVkdm-p-Gy3{*vBDELe7bj+XHo10u`n+d)Q&j!prS*O!yVs@%3go4L1sy*~fD`QtQ~I)<4N_?G8p zCT;rZ<|=P@_r~G$W$sI>&30Ui%k4V2z5dq1WA?8XU7u2S)rI@5#r${jujA$CTRPhw z-hFq;{%@Zj7kqh06gUk1Fa zliGI0w6M^mdaCrh2Vb`IL{%`&>tjjFi zaw~5m&*L)|eXo?|t~_78?(G>1`4Z-nkC)a)f0)J1@h0Geu*K?lp`{ze)+yhw*3G}S{pYe8qyG&2TeIU0;_pYhg-h2=%`|>J=k4+QD9@5? zZ;MmMT5tb;S9JG3gZ`nt{?POBcW{4_{Pt^3`24TCuBvC+@^6f>ot|j$DrDvFvw64k zKi+=Qb&u!68MQz6BpPQqf0ElB@?EawKZE|Uy_*lqG0uB;GsdN`-|NXfS!dz9$KoaK zXupsAwnBey&F4pH{)QW0$Lv^TxYXL^yOGYZb=F)@BW2jOW=(QCb&5lI zLe}}iyzKtF=RLZbMZq@4TG6frUl-;kh@HH$3?An6W{o@b$qT?GK)JZmHfWWc}B!LR?y9a!p>vb1i1Z zbJg=-##d*?-`tpSpl0UnIOC6g(P`8C^>a(F&h-+R9JGJk^2Ub44?f3~EVi=Q^>^Ci zAG-D|H9P+CMtg29uDQJ6pJ;!Y|IU+-|2$iDKU3gL&?Swlp?wze>-U!1DWrau7Hv;q zj(gId^;xld&EJ={{X33)_!jSXB{SI5yY}|>*w~vFey|@3{An0<%c<!Dr5Gel;^TBH_b? zEuqsoekvcSlH6Pt7B}_qs|l<+hH)1^s(DB~@|^)X18LXK-mV8zDzzfzBi(i%O_=gZ z*H8F}n82x1moyd3{4O{5{V;u1C-{MF_9I@sTa1Y^+m!0(Y@qD)<7k-{|=k%+?-1is#XXwk4)jwQzt8I;*T7S{vf*BHJ-@nNe z-v6?$Jv1S5wg15hi(}oSc8KY1>aMx9`L&$m^iz8>f193^&E0$J*7y6*|1&VWt&xAQ z^Ziw?BYxG7wwvx}_D*F?>*?Y5`g*?QLWFxto5Rkdu|Fp3c5DIN?{ZOw$F|?PYMyVN z=F$3$zj17T&uq4C zI29bVCGm&5*T(5bLWt-cyQJFLef-zqy0=o!{;YXrbZ|TF`(ZAC@6?QbLb$*+; zGt!Zred59Qac2}QuLeKMcK+=3V~v?KqmA}L$?CIj*X_;Ud+oY^@}vI@LVtKZn)Ms} zwp*TD%Hgy5%zAFNlaDia410>_AHF{KKSPVuuN!IqeyJwhS)&!L{qN&3{G7*n^(F*xRirNwFI+mEbFUR})cF3JC6{^4rd&PCiBYh5PHzk9BS&-+2j zBOc^X#+BcB{O#r724`+Y}vruE+1N2YMxvseS716G}gt?PeEUdo6o+ z+t+&qXH{|!t+)BJ=1EWb)APyk>Gx#KY~`8L%C4_MqPAC@3+;oULL#u(9$TX+5p{yp*Q%y{0^Zl2Yrc=x~e-1vm459<9bpJ7pO~*RvIVHm%kFkaq8+ zORh%zvE{QWI#(4{DW`k$Pky*6IpcENrP$nyIs4atva~+memVM9Wv}4Nmoe-eCX;jC zv{r>*mou2|A8Xi@^Ly*(@cuaEVnv^1wQ1(uT=twXhVvd3i~U`7;nQ3{#?MUJ)6C4+ zqqkSTXm;JhJc+5PO6+{-*Z&M(o3FoGV{WEB<*Gy4(Kx=KTi+~qOzYK4H5b)3d2{tz z->-SwlRqrGd~|~Pt;CtCfvxkzZoM*|Q_lX8UDD!cQpNIbwbx5_+{!hNXe)ds<6bJ* zpHuT#Z})bC2elXY)%&J?aeuSBTx{uw@80{al$joM@0~pTUs=BM zo9lc}Z^T$lwW|AGcDufBeq->#c~YHQ+4p{Goa86mzr%X|%75{}aW^0KGy0e3$$)G0 zf3k-~rguPUbVfC3jUFqNFCKVmv1PGMN<}%VRD?zT>g{3Q)ASF@%5L$Mj@_Jk%Uk`zveF7I;WNWv@QSgtyONz z4zum}TPCQwrG+p2nSA?yhNyl28FW`YUVOvivi|Z=%cIq&o_l}z_x$9gT+0{H{~4T2 z-~QwM7`eH(%(MU4zMK#979~4pJ%2a%h63FZauThTHvf&xi8Zm9~|Xcu)M#@Z`H2M%IA8H=$mSJmLT_LAWqjzLakY2B zYJG{X%YIBh#$PVXHvQ{*(Jfc+iZDF?y!`xX>%N$4yjQntzIL-om(CBdG3a* zr(%A|Y6tziDk9(Wr%cu*7_bq43oa3G`ul1p9K-8J#WtQt>F8(Q05o=@t z-4K$0c`NUdnj5A&*)}SzW1fF*;i09P)ysWt!i42LwN8DrjXr9pnZ4omlJk$_a@X9i zTzA}bZs989zL;63cJDo5bH#1SbL|uN*4ed*O;^7ox=pq#e0tyE zKf{!+tT~s(lRQ_JM4DxJ+j$5!H}MxA|D?88z6b{#otzBv2c-uq8#-TC{T ziq%C-c`Uc}XvOj)ZcjF*pR0X+UN~}cp3UK(SEJ{8&R-oqTR+=Y^4pZU#cg>@O;=`z z?*1&h<)7Ewq08SbzEXVPvDE6o*tyd?x1Qf( zJol&Cj##(nh3clf*A~R9Y)y%aeRqOw)l^Q;yE7kujw*Ti$vH{;ruokGE`R5j9$p-u z&9i>X35EABpVjwPwrnc!G~NGj_qL6jZ>@8-7EgTPXTL!7cG!pI@7~qyi+lOVaOKq> zp|^jp=?7gGauRx7$mt_h`ytnboCIAL^8E9f+p9m_JRLsoanR!L{Tr4?b2c@9(>nZ> zyP>E!Do%R8fM4%C?a8}#-7Da=JM{f@!ji|L7j=xE*knas3DbJ}qE`H2y`<^VU8_zX zv(5OZ-V^suNhsGVUx8CQ<4u`9* z@H41f^zOIi=`h!`$7kHFSeub}_uYAWv$KmHpB8g1xXCi>SMbB{J!zL~hcvu4Mq zr2O3A?)7Q=4!eY!FKc7XgKjbMMqfR=WwQJ9>Ce7AwREaBekolqdum&fq2|liG5KA4 z-154`CR=`AZ`mI?In8|jxz#bRe14t|6Z*FK;=HAzjfc&HW?k97>Rx5vanrL|LhmeA z>Vxk&@+|UH+x6j#WvLC%eUs4jBIo)amfpVc$MLd$fcZP0o+JFbcye~y&6!{?^-J#c z@uI!Ur$3uFZ|i6Iwr8L8=DjXt&pY}nMfgwq>sbA7XIcyQ{43dLykdFAtdt!!Dj)uQ zoq9X>&lc}b*8ak;_h+Q3e)8X2P&M`3Bfl)^wGR7=u1>5hpU1eaDnwN?cHTN`lciqM zRm{vvvNy`Cy7?mex{dUs&FNBaC(HL%$gaKE`N2Op`kU2i1?l*&t5>@POgHh%VM}%v zcE54W_H*RNJ=?{e`t04Ceb&Z(_0MJsY3Kcz|vFw6V4X1#`zuJ`G@ zZk|9M#Y zRnUD$eQQ>o^40BMeBi>tprxFi)hD%oeKp(q)*qDkw95-@E}pMSz5C7abeQYWgJmad zwN@nF57xPC(YsdoLXGk&?#L!;@nJ^%D4bj7mzr<>)k z?S1~ud8c_C+eeX}BG+g3pQNszix+=qvtH`{y28(s|1zs=IyaT|?%6#P9nF7jx8?tlzT$k~r3D|%Chc0b zPAcQ@K?a^zZqCBr9iP9dwK(`X-n~NnU~+`Nnul1#lh}1@cJlBCxEDqxe=O_`^>ll` z^7NrO_F?PTmRT*$PnTW1^xd_$KT9sh-uJd+|CW74tiJc3c#m0mtogt0s_*)@Yqw`otjd$(K*7rS2F<*xW?iBZj*mFF1l6o_X$e;H<(uH04EZ*9d~JMdO08;61?8$-zWDoA{f3DP*Bicmn!|HV_|f#RuQ@+2{r2e4l#7sWEuJ;E`{1;G6~3#l>J&E$Sg*4R zmt5t-p)9iDM(44x)aQ|Qa%<(PvhKCdyA^xSccqSi)0=l?YZ8j*fBqRZ;mVUXXWm0L zM(fN~xJc)qk@8?7y5Nm;cz^i<-{!_Ep`ysW!i~770G( zk=qk~;g|a1pkEbJ7rmV~_4tp=hn4-)qzk(~zY1C}dS0!zjaznV==`fMT{9}u7B4y8 z6k0a%vgoPTb){2M-s*53ux-D#*FLgAd7gIvb=^xIH@%uT*3A)9{j91R`0%5hCx5DD z!1t8mTRF4lf2+UkyXJfzC!1?bAG^A2fkEZVFyXMUIJv#?4~|Wj+n+J*V&k)0kJNoW zvDpRpJZCBY%6@6DdGz0Td(2m4!Y;H}a~}0VixXEv)m1H`&M*92`oZ|%!;I7Xok2xi zyQaC`T68$IemY=*!zU|i#zd8RWDx8e|YCQHM?s|7A?N_{g05%e}>Q*Z%Tf^|SSkOI>SM=+BkflT{Sj<}7#k*Y(YR>^>B~ za%JdO_#IaIan8q(m&fnDD}5Scwc+Zj={sG-*v6tVx-+^n+(d+XnS8cDd z$>K{2{1JXBYWv}ZnaO)V*IAtW6S$N+GS=|Yo?jc*y595o&BLdxdnUM5WARB-TZ7{} z7d`lTv}pVE@WA^zf=7;iXAt3;uD(F@Wz-x8G0`)Vd8cj8uU2tA;!`BPjzi(`=k?y~ zox5sI{gM|xGE=G7;xki}$?^~?Q` zJntKu(4{KnWgG5A`OKa&afg6A&yo@g8-wTbc!NK-zj^!cv`4s0f?dVk5GvD~nBzN}A@=CL18xAAiW-%Xhn}x9?f*OAYc^W6cg|O3P3ikHTXXT`#Cys{E6-|LFTJS$xxVOT zxsC1@hi1D7_8Vco|0auFGGqKA`bE5_M#AL9?I*`9-8XAgm%d!`P-RDgC$Dwh+nxjld#{DHN!usu@EENrxbOFMj^UL# zTcTud^ogHQcKz+S)O=IatKWOY?-cJ7X#39)k`}_M&OU1+)GsNVKAENSQ7ZJV0jJ-g?zVD{hWdF_9UucWVd z8TIRo<{oReNx2EPV~duvFO-}5=05}X9%KHlk{#(0Vi9@*YdTI(sA>zIc;cM<-m1?> zeoycc-}n6ajGD=R7wuWzS@6{JXw-j(`qIn3rTe|*_)J5U+n3pXtZVQ3m48%z^YXT+ zv&*}#J@=nF|4jPU89iT5z0Ex(KCgi%A(^@B)86WbX_J?oI5B7@PD$CbH2-YO=XiS+#z~$BnD++k*|p32Nt4Cwx(7^;RXg8kUr4>Q zCWm?L+Fi%|if+Q{dh5l((+h9bABsS(>a+Ln{;ZuL zCHv*$>buR7=YMT*{Bz>*r$4W&f3pS}B(cja+FO6Xj-}R3HDAA{D(rpdA2uD`?#hY- zU)I|dt`DvDo%r=e)lEO9Y|f9~tE;xvJg;5iBGRwJe`x1fzk?507oTL_TD80*hlTHT z-_)b8CNgmx)iF~loI11ent%IR_j$9nFMPgjd->)pZx(~y))Q9CS^l~<Hx}-N&%`ph{kQ>#F?fCD*;B<2O7#u=7Xmqe#Yc zrcCyqgu>6&%PhV5k?UjearOTU@>##xABZ=;*~7S~qThW(=AW7G?5>D~-`!mF_SSOA zTTDFZ>Q`p{tbbJ3o>>3ruh*wn<`a*!8JJICV3~L0`Ln;QHGWJ>G}C`{+HU=G@zK*8 zI$`!EB@3=wKg+%EEA%?wuYIDY@r=8R-D;avbQAoweKjYZ^L+V6`% zk^krapMl}$;gAVp$x;8fZ+_cyx6d$U+rr{GbFRK+5BQYo&bDvnr7ZSWCLcFU(_HpT zKB-3M%9`9Y0fsS;mi(BwHu7}NL#{9DSufPYef!X`>2ZIQ>3%WOBPk|3|75RzeQoK< z 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 To__XO$<%PwSRFvdYWaQ-KK!z}~va+(XvGZ|o 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 z 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 diff --git a/examples/hyper/local.10Oct18.000000.jpg b/examples/hyper/local.10Oct18.000000.jpg deleted file mode 100644 index ef0ec0cd59adaf184019cafa7fa00746be5828fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 493761 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

1v+p2}4f`GNZ`=GNU@e$(z|neUe8Jx}D=V?H?^ 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�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

t*Yt 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[kMWAh>A8BG>)%OhTFNZH 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�z$AhMGKN=rLxo2W6cfN4M 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

pZ7ca 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

yle^9*m2{HNALlQIOg>A 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