Removed several files that should not have been included

This commit is contained in:
Dan S. Bolintineanu
2019-03-06 13:54:32 -07:00
parent 87a243203b
commit 9a6dc2ff11
11 changed files with 0 additions and 6337 deletions

View File

@ -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 <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}

View File

@ -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.
*/

View File

@ -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 <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}

View File

@ -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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}

View File

@ -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.
*/

View File

@ -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 <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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;
}

View File

@ -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.
*/

File diff suppressed because it is too large Load Diff

View File

@ -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.
*/

File diff suppressed because it is too large Load Diff

View File

@ -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.
*/