git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7209 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2011-10-26 17:08:27 +00:00
parent 9e2f81e4ed
commit c6ab9c0ce6
14 changed files with 5547 additions and 1 deletions

35
src/FLD/Install.sh Normal file
View File

@ -0,0 +1,35 @@
# Install/unInstall package files in LAMMPS
if (test $1 == 1) then
cp pair_brownian.cpp ..
cp pair_brownian_poly.cpp ..
cp pair_lubricate.cpp ..
cp pair_lubricate_poly.cpp ..
cp pair_lubricateU.cpp ..
cp pair_lubricateU_poly.cpp ..
cp pair_brownian.h ..
cp pair_brownian_poly.h ..
cp pair_lubricate.h ..
cp pair_lubricate_poly.h ..
cp pair_lubricateU.h ..
cp pair_lubricateU_poly.h ..
elif (test $1 == 0) then
rm ../pair_brownian.cpp
rm ../pair_brownian_poly.cpp
rm ../pair_lubricate.cpp
rm ../pair_lubricate_poly.cpp
rm ../pair_lubricateU.cpp
rm ../pair_lubricateU_poly.cpp
rm ../pair_brownian.h
rm ../pair_brownian_poly.h
rm ../pair_lubricate.h
rm ../pair_lubricate_poly.h
rm ../pair_lubricateU.h
rm ../pair_lubricateU_poly.h
fi

611
src/FLD/pair_brownian.cpp Executable file
View File

@ -0,0 +1,611 @@
/* ----------------------------------------------------------------------
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: Amit Kumar and Michael Bybee (UIUC)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_brownian.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "domain.h"
#include "update.h"
#include "memory.h"
#include "random_mars.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
PairBrownian::PairBrownian(LAMMPS *lmp) : Pair(lmp)
{
single_enable = 0;
random = NULL;
}
/* ---------------------------------------------------------------------- */
PairBrownian::~PairBrownian()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cut);
memory->destroy(cut_inner);
}
delete random;
}
/* ---------------------------------------------------------------------- */
void PairBrownian::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,tx,ty,tz;
double rsq,r,h_sep,radi;
int *ilist,*jlist,*numneigh,**firstneigh;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **torque = atom->torque;
double *radius = atom->radius;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
double vxmu2f = force->vxmu2f;
double randr;
double prethermostat;
double xl[3],a_sq,a_sh,a_pu,Fbmag;
double p1[3],p2[3],p3[3];
int overlaps = 0;
// scale factor for Brownian moments
prethermostat = sqrt(24.0*force->boltz*t_target/update->dt);
prethermostat *= sqrt(force->vxmu2f/force->ftm2v/force->mvv2e);
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
radi = radius[i];
jlist = firstneigh[i];
jnum = numneigh[i];
// FLD contribution to force and torque due to isotropic terms
if (flagfld) {
f[i][0] += prethermostat*sqrt(R0)*(random->uniform()-0.5);
f[i][1] += prethermostat*sqrt(R0)*(random->uniform()-0.5);
f[i][2] += prethermostat*sqrt(R0)*(random->uniform()-0.5);
if (flaglog) {
torque[i][0] += prethermostat*sqrt(RT0)*(random->uniform()-0.5);
torque[i][1] += prethermostat*sqrt(RT0)*(random->uniform()-0.5);
torque[i][2] += prethermostat*sqrt(RT0)*(random->uniform()-0.5);
}
}
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
// scalar resistances a_sq and a_sh
h_sep = r - 2.0*radi;
// check for overlaps
if (h_sep < 0.0) overlaps++;
// if less than minimum gap, use minimum gap instead
if (r < cut_inner[itype][jtype])
h_sep = cut_inner[itype][jtype] - 2.0*radi;
// scale h_sep by radi
h_sep = h_sep/radi;
// scalar resistances
if (flaglog) {
a_sq = 6.0*MY_PI*mu*radi*(1.0/4.0/h_sep + 9.0/40.0*log(1.0/h_sep));
a_sh = 6.0*MY_PI*mu*radi*(1.0/6.0*log(1.0/h_sep));
a_pu = 8.0*MY_PI*mu*pow(radi,3)*(3.0/160.0*log(1.0/h_sep));
} else
a_sq = 6.0*MY_PI*mu*radi*(1.0/4.0/h_sep);
// generate the Pairwise Brownian Force: a_sq
Fbmag = prethermostat*sqrt(a_sq);
// generate a random number
randr = random->uniform()-0.5;
// contribution due to Brownian motion
fx = Fbmag*randr*delx/r;
fy = Fbmag*randr*dely/r;
fz = Fbmag*randr*delz/r;
// add terms due to a_sh
if (flaglog) {
// generate two orthogonal vectors to the line of centers
p1[0] = delx/r; p1[1] = dely/r; p1[2] = delz/r;
set_3_orthogonal_vectors(p1,p2,p3);
// magnitude
Fbmag = prethermostat*sqrt(a_sh);
// force in each of the two directions
randr = random->uniform()-0.5;
fx += Fbmag*randr*p2[0];
fy += Fbmag*randr*p2[1];
fz += Fbmag*randr*p2[2];
randr = random->uniform()-0.5;
fx += Fbmag*randr*p3[0];
fy += Fbmag*randr*p3[1];
fz += Fbmag*randr*p3[2];
}
// scale forces to appropriate units
fx = vxmu2f*fx;
fy = vxmu2f*fy;
fz = vxmu2f*fz;
// sum to total force
f[i][0] -= fx;
f[i][1] -= fy;
f[i][2] -= fz;
if (newton_pair || j < nlocal) {
//randr = random->uniform()-0.5;
//fx = Fbmag*randr*delx/r;
//fy = Fbmag*randr*dely/r;
//fz = Fbmag*randr*delz/r;
f[j][0] += fx;
f[j][1] += fy;
f[j][2] += fz;
}
// torque due to the Brownian Force
if (flaglog) {
// location of the point of closest approach on I from its center
xl[0] = -delx/r*radi;
xl[1] = -dely/r*radi;
xl[2] = -delz/r*radi;
// torque = xl_cross_F
tx = xl[1]*fz - xl[2]*fy;
ty = xl[2]*fx - xl[0]*fz;
tz = xl[0]*fy - xl[1]*fx;
// torque is same on both particles
torque[i][0] -= tx;
torque[i][1] -= ty;
torque[i][2] -= tz;
if (newton_pair || j < nlocal) {
torque[j][0] -= tx;
torque[j][1] -= ty;
torque[j][2] -= tz;
}
// torque due to a_pu
Fbmag = prethermostat*sqrt(a_pu);
// force in each direction
randr = random->uniform()-0.5;
tx = Fbmag*randr*p2[0];
ty = Fbmag*randr*p2[1];
tz = Fbmag*randr*p2[2];
randr = random->uniform()-0.5;
tx += Fbmag*randr*p3[0];
ty += Fbmag*randr*p3[1];
tz += Fbmag*randr*p3[2];
// torque has opposite sign on two particles
torque[i][0] -= tx;
torque[i][1] -= ty;
torque[i][2] -= tz;
if (newton_pair || j < nlocal) {
torque[j][0] += tx;
torque[j][1] += ty;
torque[j][2] += tz;
}
}
if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
0.0,0.0,-fx,-fy,-fz,delx,dely,delz);
}
}
}
int print_overlaps = 0;
if (print_overlaps && overlaps)
printf("Number of overlaps=%d\n",overlaps);
if (vflag_fdotr) virial_fdotr_compute();
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairBrownian::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(cut,n+1,n+1,"pair:cut");
memory->create(cut_inner,n+1,n+1,"pair:cut_inner");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairBrownian::settings(int narg, char **arg)
{
if (narg != 7) error->all(FLERR,"Illegal pair_style command");
mu = atof(arg[0]);
flaglog = atoi(arg[1]);
flagfld = atoi(arg[2]);
cut_inner_global = atof(arg[3]);
cut_global = atof(arg[4]);
t_target = atof(arg[5]);
seed = atoi(arg[6]);
// initialize Marsaglia RNG with processor-unique seed
delete random;
random = new RanMars(lmp,seed + comm->me);
// reset cutoffs that have been explicitly set
if (allocated) {
for (int i = 1; i <= atom->ntypes; i++)
for (int j = i+1; j <= atom->ntypes; j++)
if (setflag[i][j]) {
cut_inner[i][j] = cut_inner_global;
cut[i][j] = cut_global;
}
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairBrownian::coeff(int narg, char **arg)
{
if (narg != 2 && narg != 4)
error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
double cut_inner_one = cut_inner_global;
double cut_one = cut_global;
if (narg == 4) {
cut_inner_one = atof(arg[2]);
cut_one = atof(arg[3]);
}
int count = 0;
for (int i = ilo; i <= ihi; i++)
for (int j = MAX(jlo,i); j <= jhi; j++) {
cut_inner[i][j] = cut_inner_one;
cut[i][j] = cut_one;
setflag[i][j] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairBrownian::init_style()
{
if (!atom->sphere_flag)
error->all(FLERR,"Pair brownian requires atom style sphere");
// if newton off, forces between atoms ij will be double computed
// using different random numbers
if (force->newton_pair == 0 && comm->me == 0)
error->warning(FLERR,
"Pair brownian needs newton pair on for "
"momentum conservation");
int irequest = neighbor->request(this);
// insure all particles are finite-size
// for pair hybrid, should limit test to types using the pair style
double *radius = atom->radius;
int *type = atom->type;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (radius[i] == 0.0)
error->one(FLERR,"Pair brownian requires extended particles");
// require monodisperse system with same radii for all types
double rad,radtype;
for (int i = 1; i <= atom->ntypes; i++) {
if (!atom->radius_consistency(i,radtype))
error->all(FLERR,"Pair brownian requires monodisperse particles");
if (i > 1 && radtype != rad)
error->all(FLERR,"Pair brownian requires monodisperse particles");
rad = radtype;
}
// set the isotropic constants that depend on the volume fraction
// vol_T = total volume
double vol_T = domain->xprd*domain->yprd*domain->zprd;
// vol_P = volume of particles, assuming mono-dispersity
// vol_f = volume fraction
double vol_P = atom->natoms*(4.0/3.0)*MY_PI*pow(rad,3);
double vol_f = vol_P/vol_T;
// set isotropic constants
if (flaglog == 0) {
R0 = 6*MY_PI*mu*rad*(1.0 + 2.16*vol_f);
RT0 = 8*MY_PI*mu*pow(rad,3); // not actually needed
} else {
R0 = 6*MY_PI*mu*rad*(1.0 + 2.725*vol_f - 6.583*vol_f*vol_f);
RT0 = 8*MY_PI*mu*pow(rad,3)*(1.0 + 0.749*vol_f - 2.469*vol_f*vol_f);
}
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairBrownian::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
cut_inner[i][j] = mix_distance(cut_inner[i][i],cut_inner[j][j]);
cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
}
cut_inner[j][i] = cut_inner[i][j];
return cut[i][j];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairBrownian::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j],sizeof(int),1,fp);
if (setflag[i][j]) {
fwrite(&cut_inner[i][j],sizeof(double),1,fp);
fwrite(&cut[i][j],sizeof(double),1,fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairBrownian::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
if (setflag[i][j]) {
if (me == 0) {
fread(&cut_inner[i][j],sizeof(double),1,fp);
fread(&cut[i][j],sizeof(double),1,fp);
}
MPI_Bcast(&cut_inner[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairBrownian::write_restart_settings(FILE *fp)
{
fwrite(&mu,sizeof(double),1,fp);
fwrite(&flaglog,sizeof(int),1,fp);
fwrite(&flagfld,sizeof(int),1,fp);
fwrite(&cut_inner_global,sizeof(double),1,fp);
fwrite(&cut_global,sizeof(double),1,fp);
fwrite(&t_target,sizeof(double),1,fp);
fwrite(&seed,sizeof(int),1,fp);
fwrite(&offset_flag,sizeof(int),1,fp);
fwrite(&mix_flag,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairBrownian::read_restart_settings(FILE *fp)
{
int me = comm->me;
if (me == 0) {
fread(&mu,sizeof(double),1,fp);
fread(&flaglog,sizeof(int),1,fp);
fread(&flagfld,sizeof(int),1,fp);
fread(&cut_inner_global,sizeof(double),1,fp);
fread(&cut_global,sizeof(double),1,fp);
fread(&t_target, sizeof(double),1,fp);
fread(&seed, sizeof(int),1,fp);
fread(&offset_flag,sizeof(int),1,fp);
fread(&mix_flag,sizeof(int),1,fp);
}
MPI_Bcast(&mu,1,MPI_DOUBLE,0,world);
MPI_Bcast(&flaglog,1,MPI_INT,0,world);
MPI_Bcast(&flagfld,1,MPI_INT,0,world);
MPI_Bcast(&cut_inner_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&t_target,1,MPI_DOUBLE,0,world);
MPI_Bcast(&seed,1,MPI_INT,0,world);
MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
// additional setup based on restart parameters
delete random;
random = new RanMars(lmp,seed + comm->me);
}
/* ----------------------------------------------------------------------*/
void PairBrownian::set_3_orthogonal_vectors(double p1[3],
double p2[3], double p3[3])
{
double norm;
int ix,iy,iz;
// find the index of maximum magnitude and store it in iz
if (fabs(p1[0]) > fabs(p1[1])) {
iz=0;
ix=1;
iy=2;
} else {
iz=1;
ix=2;
iy=0;
}
if (iz==0) {
if (fabs(p1[0]) < fabs(p1[2])) {
iz = 2;
ix = 0;
iy = 1;
}
} else {
if (fabs(p1[1]) < fabs(p1[2])) {
iz = 2;
ix = 0;
iy = 1;
}
}
// set p2 arbitrarily such that it's orthogonal to p1
p2[ix]=1.0;
p2[iy]=1.0;
p2[iz] = -(p1[ix]*p2[ix] + p1[iy]*p2[iy])/p1[iz];
// normalize p2
norm = sqrt(pow(p2[0],2) + pow(p2[1],2) + pow(p2[2],2));
p2[0] = p2[0]/norm;
p2[1] = p2[1]/norm;
p2[2] = p2[2]/norm;
// Set p3 by taking the cross product p3=p2xp1
p3[0] = p1[1]*p2[2] - p1[2]*p2[1];
p3[1] = p1[2]*p2[0] - p1[0]*p2[2];
p3[2] = p1[0]*p2[1] - p1[1]*p2[0];
}

58
src/FLD/pair_brownian.h Normal file
View File

@ -0,0 +1,58 @@
/* ----------------------------------------------------------------------
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(brownian,PairBrownian)
#else
#ifndef LMP_PAIR_BROWNIAN_H
#define LMP_PAIR_BROWNIAN_H
#include "pair.h"
namespace LAMMPS_NS {
class PairBrownian : public Pair {
public:
PairBrownian(class LAMMPS *);
virtual ~PairBrownian();
virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
virtual double init_one(int, int);
virtual void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
protected:
double cut_inner_global,cut_global;
double t_target,mu;
int flaglog,flagfld;
int seed;
double **cut_inner,**cut;
double R0,RT0;
class RanMars *random;
void set_3_orthogonal_vectors(double*,double*,double*);
void allocate();
};
}
#endif
#endif

View File

@ -0,0 +1,338 @@
/* ----------------------------------------------------------------------
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: Amit Kumar and Michael Bybee (UIUC)
Dave Heine (Corning), polydispersity
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_brownian_poly.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "domain.h"
#include "update.h"
#include "memory.h"
#include "random_mars.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
PairBrownianPoly::PairBrownianPoly(LAMMPS *lmp) : PairBrownian(lmp)
{
no_virial_fdotr_compute = 1;
}
/* ---------------------------------------------------------------------- */
void PairBrownianPoly::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz,tx,ty,tz;
double rsq,r,h_sep,beta0,beta1,radi,radj;
int *ilist,*jlist,*numneigh,**firstneigh;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **torque = atom->torque;
double *radius = atom->radius;
int *type = atom->type;
int nlocal = atom->nlocal;
double vxmu2f = force->vxmu2f;
int overlaps = 0;
double randr;
double prethermostat;
double xl[3],a_sq,a_sh,a_pu,Fbmag;
double p1[3],p2[3],p3[3];
// scale factor for Brownian moments
prethermostat = sqrt(24.0*force->boltz*t_target/update->dt);
prethermostat *= sqrt(force->vxmu2f/force->ftm2v/force->mvv2e);
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
radi = radius[i];
jlist = firstneigh[i];
jnum = numneigh[i];
// FLD contribution to force and torque due to isotropic terms
if (flagfld) {
f[i][0] += prethermostat*sqrt(R0*radi)*(random->uniform()-0.5);
f[i][1] += prethermostat*sqrt(R0*radi)*(random->uniform()-0.5);
f[i][2] += prethermostat*sqrt(R0*radi)*(random->uniform()-0.5);
if (flaglog) {
torque[i][0] += prethermostat*sqrt(RT0*pow(radi,3)) *
(random->uniform()-0.5);
torque[i][1] += prethermostat*sqrt(RT0*pow(radi,3)) *
(random->uniform()-0.5);
torque[i][2] += prethermostat*sqrt(RT0*pow(radi,3)) *
(random->uniform()-0.5);
}
}
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];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
// scalar resistances a_sq and a_sh
h_sep = r - radi-radj;
// check for overlaps
if (h_sep < 0.0) overlaps++;
// if less than minimum gap, use minimum gap instead
if (r < cut_inner[itype][jtype])
h_sep = cut_inner[itype][jtype] - radi-radj;
// scale h_sep by radi
h_sep = h_sep/radi;
beta0 = radj/radi;
beta1 = 1.0 + beta0;
// scalar resistances
if (flaglog) {
a_sq = beta0*beta0/beta1/beta1/h_sep +
(1.0+7.0*beta0+beta0*beta0)/5.0/pow(beta1,3)*log(1.0/h_sep);
a_sq += (1.0+18.0*beta0-29.0*beta0*beta0+18.0*pow(beta0,3) +
pow(beta0,4))/21.0/pow(beta1,4)*h_sep*log(1.0/h_sep);
a_sq *= 6.0*MY_PI*mu*radi;
a_sh = 4.0*beta0*(2.0+beta0+2.0*beta0*beta0)/15.0/pow(beta1,3) *
log(1.0/h_sep);
a_sh += 4.0*(16.0-45.0*beta0+58.0*beta0*beta0-45.0*pow(beta0,3) +
16.0*pow(beta0,4))/375.0/pow(beta1,4) *
h_sep*log(1.0/h_sep);
a_sh *= 6.0*MY_PI*mu*radi;
a_pu = beta0*(4.0+beta0)/10.0/beta1/beta1*log(1.0/h_sep);
a_pu += (32.0-33.0*beta0+83.0*beta0*beta0+43.0 *
pow(beta0,3))/250.0/pow(beta1,3)*h_sep*log(1.0/h_sep);
a_pu *= 8.0*MY_PI*mu*pow(radi,3);
} else a_sq = 6.0*MY_PI*mu*radi*(beta0*beta0/beta1/beta1/h_sep);
// generate the Pairwise Brownian Force: a_sq
Fbmag = prethermostat*sqrt(a_sq);
// generate a random number
randr = random->uniform()-0.5;
// contribution due to Brownian motion
fx = Fbmag*randr*delx/r;
fy = Fbmag*randr*dely/r;
fz = Fbmag*randr*delz/r;
// add terms due to a_sh
if (flaglog) {
// generate two orthogonal vectors to the line of centers
p1[0] = delx/r; p1[1] = dely/r; p1[2] = delz/r;
set_3_orthogonal_vectors(p1,p2,p3);
// magnitude
Fbmag = prethermostat*sqrt(a_sh);
// force in each of the two directions
randr = random->uniform()-0.5;
fx += Fbmag*randr*p2[0];
fy += Fbmag*randr*p2[1];
fz += Fbmag*randr*p2[2];
randr = random->uniform()-0.5;
fx += Fbmag*randr*p3[0];
fy += Fbmag*randr*p3[1];
fz += Fbmag*randr*p3[2];
}
// scale forces to appropriate units
fx = vxmu2f*fx;
fy = vxmu2f*fy;
fz = vxmu2f*fz;
// sum to total Force
f[i][0] -= fx;
f[i][1] -= fy;
f[i][2] -= fz;
// torque due to the Brownian Force
if (flaglog) {
// location of the point of closest approach on I from its center
xl[0] = -delx/r*radi;
xl[1] = -dely/r*radi;
xl[2] = -delz/r*radi;
// torque = xl_cross_F
tx = xl[1]*fz - xl[2]*fy;
ty = xl[2]*fx - xl[0]*fz;
tz = xl[0]*fy - xl[1]*fx;
// torque is same on both particles
torque[i][0] -= tx;
torque[i][1] -= ty;
torque[i][2] -= tz;
// torque due to a_pu
Fbmag = prethermostat*sqrt(a_pu);
// force in each direction
randr = random->uniform()-0.5;
tx = Fbmag*randr*p2[0];
ty = Fbmag*randr*p2[1];
tz = Fbmag*randr*p2[2];
randr = random->uniform()-0.5;
tx += Fbmag*randr*p3[0];
ty += Fbmag*randr*p3[1];
tz += Fbmag*randr*p3[2];
// torque has opposite sign on two particles
torque[i][0] -= tx;
torque[i][1] -= ty;
torque[i][2] -= tz;
}
// set j = nlocal so that only I gets tallied
if (evflag) ev_tally_xyz(i,nlocal,nlocal,0,
0.0,0.0,-fx,-fy,-fz,delx,dely,delz);
}
}
}
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairBrownianPoly::init_style()
{
if (force->newton_pair == 1)
error->all(FLERR,"Pair brownian/poly requires newton pair off");
if (!atom->sphere_flag)
error->all(FLERR,"Pair brownian/poly requires atom style sphere");
// insure all particles are finite-size
// for pair hybrid, should limit test to types using the pair style
double *radius = atom->radius;
int *type = atom->type;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (radius[i] == 0.0)
error->one(FLERR,"Pair brownian/poly requires extended particles");
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
// set the isotropic constants that depend on the volume fraction
// vol_T = total volume
double vol_T = domain->xprd*domain->yprd*domain->zprd;
// vol_P = volume of particles, assuming mono-dispersity
// vol_f = volume fraction
double volP = 0.0;
for (int i = 0; i < nlocal; i++)
volP += (4.0/3.0)*MY_PI*pow(atom->radius[i],3);
double vol_P;
MPI_Allreduce(&volP,&vol_P,1,MPI_DOUBLE,MPI_SUM,world);
double vol_f = vol_P/vol_T;
// set isotropic constants
if (flaglog == 0) {
R0 = 6*MY_PI*mu*(1.0 + 2.16*vol_f);
RT0 = 8*MY_PI*mu;
} else {
R0 = 6*MY_PI*mu*(1.0 + 2.725*vol_f - 6.583*vol_f*vol_f);
RT0 = 8*MY_PI*mu*(1.0 + 0.749*vol_f - 2.469*vol_f*vol_f);
}
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairBrownianPoly::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
cut_inner[i][j] = mix_distance(cut_inner[i][i],cut_inner[j][j]);
cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
}
cut_inner[j][i] = cut_inner[i][j];
return cut[i][j];
}

View File

@ -0,0 +1,39 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(brownian/poly,PairBrownianPoly)
#else
#ifndef LMP_PAIR_BROWNIAN_POLY_H
#define LMP_PAIR_BROWNIAN_POLY_H
#include "pair_brownian.h"
namespace LAMMPS_NS {
class PairBrownianPoly : public PairBrownian {
public:
PairBrownianPoly(class LAMMPS *);
~PairBrownianPoly() {}
void compute(int, int);
double init_one(int, int);
void init_style();
};
}
#endif
#endif

723
src/FLD/pair_lubricate.cpp Executable file
View File

@ -0,0 +1,723 @@
/* ----------------------------------------------------------------------
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: Randy Schunk (SNL)
Amit Kumar and Michael Bybee (UIUC)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_lubricate.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "domain.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "memory.h"
#include "random_mars.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
// same as fix_deform.cpp
enum{NO_REMAP,X_REMAP,V_REMAP};
/* ---------------------------------------------------------------------- */
PairLubricate::PairLubricate(LAMMPS *lmp) : Pair(lmp)
{
single_enable = 0;
// set comm size needed by this Pair
comm_forward = 6;
}
/* ---------------------------------------------------------------------- */
PairLubricate::~PairLubricate()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cut);
memory->destroy(cut_inner);
}
}
/* ---------------------------------------------------------------------- */
void PairLubricate::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz,tx,ty,tz;
double rsq,r,h_sep,radi,tfmag;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3;
double vt1,vt2,vt3,wt1,wt2,wt3,wdotn;
double inertia,inv_inertia,vRS0;
double vi[3],vj[3],wi[3],wj[3],xl[3];
double a_sq,a_sh,a_pu,Fbmag,del,delmin,eta;
int *ilist,*jlist,*numneigh,**firstneigh;
double lamda[3],vstream[3];
double vxmu2f = force->vxmu2f;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *radius = atom->radius;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
int overlaps = 0;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// subtract streaming component of velocity, omega, angmom
// assume fluid streaming velocity = box deformation rate
// vstream = (ux,uy,uz)
// ux = h_rate[0]*x + h_rate[5]*y + h_rate[4]*z
// uy = h_rate[1]*y + h_rate[3]*z
// uz = h_rate[2]*z
// omega_new = omega - curl(vstream)/2
// angmom_new = angmom - I*curl(vstream)/2
// Ef = (grad(vstream) + (grad(vstream))^T) / 2
if (shearing) {
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
radi = radius[i];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
v[i][0] -= vstream[0];
v[i][1] -= vstream[1];
v[i][2] -= vstream[2];
omega[i][0] += 0.5*h_rate[3];
omega[i][1] -= 0.5*h_rate[4];
omega[i][2] += 0.5*h_rate[5];
}
// set Ef from h_rate in strain units
Ef[0][0] = h_rate[0]/domain->xprd;
Ef[1][1] = h_rate[1]/domain->yprd;
Ef[2][2] = h_rate[2]/domain->zprd;
Ef[0][1] = Ef[1][0] = 0.5 * h_rate[5]/domain->yprd;
Ef[0][2] = Ef[2][0] = 0.5 * h_rate[4]/domain->zprd;
Ef[1][2] = Ef[2][1] = 0.5 * h_rate[3]/domain->zprd;
// copy updated velocity/omega/angmom to the ghost particles
// no need to do this if not shearing since comm->ghost_velocity is set
comm->forward_comm_pair(this);
}
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
radi = radius[i];
jlist = firstneigh[i];
jnum = numneigh[i];
// angular velocity
wi[0] = omega[i][0];
wi[1] = omega[i][1];
wi[2] = omega[i][2];
// FLD contribution to force and torque due to isotropic terms
// FLD contribution to stress from isotropic RS0
if (flagfld) {
f[i][0] -= vxmu2f*R0*v[i][0];
f[i][1] -= vxmu2f*R0*v[i][1];
f[i][2] -= vxmu2f*R0*v[i][2];
torque[i][0] -= vxmu2f*RT0*wi[0];
torque[i][1] -= vxmu2f*RT0*wi[1];
torque[i][2] -= vxmu2f*RT0*wi[2];
if (shearing && vflag_either) {
vRS0 = -vxmu2f * RS0;
v_tally_tensor(i,i,nlocal,newton_pair,
vRS0*Ef[0][0],vRS0*Ef[1][1],vRS0*Ef[2][2],
vRS0*Ef[0][1],vRS0*Ef[0][2],vRS0*Ef[1][2]);
}
}
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
j &= NEIGHMASK;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
// angular momentum = I*omega = 2/5 * M*R^2 * omega
wj[0] = omega[j][0];
wj[1] = omega[j][1];
wj[2] = omega[j][2];
// xl = point of closest approach on particle i from its center
xl[0] = -delx/r*radi;
xl[1] = -dely/r*radi;
xl[2] = -delz/r*radi;
// velocity at the point of closest approach on both particles
// v = v + omega_cross_xl - Ef.xl
// particle i
vi[0] = v[i][0] + (wi[1]*xl[2] - wi[2]*xl[1])
- (Ef[0][0]*xl[0] + Ef[0][1]*xl[1] + Ef[0][2]*xl[2]);
vi[1] = v[i][1] + (wi[2]*xl[0] - wi[0]*xl[2])
- (Ef[1][0]*xl[0] + Ef[1][1]*xl[1] + Ef[1][2]*xl[2]);
vi[2] = v[i][2] + (wi[0]*xl[1] - wi[1]*xl[0])
- (Ef[2][0]*xl[0] + Ef[2][1]*xl[1] + Ef[2][2]*xl[2]);
// particle j
vj[0] = v[j][0] - (wj[1]*xl[2] - wj[2]*xl[1])
+ (Ef[0][0]*xl[0] + Ef[0][1]*xl[1] + Ef[0][2]*xl[2]);
vj[1] = v[j][1] - (wj[2]*xl[0] - wj[0]*xl[2])
+ (Ef[1][0]*xl[0] + Ef[1][1]*xl[1] + Ef[1][2]*xl[2]);
vj[2] = v[j][2] - (wj[0]*xl[1] - wj[1]*xl[0])
+ (Ef[2][0]*xl[0] + Ef[2][1]*xl[1] + Ef[2][2]*xl[2]);
// scalar resistances XA and YA
h_sep = r - 2.0*radi;
// check for overlaps
if (h_sep < 0.0) overlaps++;
// if less than the minimum gap use the minimum gap instead
if (r < cut_inner[itype][jtype])
h_sep = cut_inner[itype][jtype] - 2.0*radi;
// scale h_sep by radi
h_sep = h_sep/radi;
// scalar resistances
if (flaglog) {
a_sq = 6.0*MY_PI*mu*radi*(1.0/4.0/h_sep + 9.0/40.0*log(1.0/h_sep));
a_sh = 6.0*MY_PI*mu*radi*(1.0/6.0*log(1.0/h_sep));
a_pu = 8.0*MY_PI*mu*pow(radi,3)*(3.0/160.0*log(1.0/h_sep));
} else
a_sq = 6.0*MY_PI*mu*radi*(1.0/4.0/h_sep);
// relative velocity at the point of closest approach
// includes fluid velocity
vr1 = vi[0] - vj[0];
vr2 = vi[1] - vj[1];
vr3 = vi[2] - vj[2];
// normal component (vr.n)n
vnnr = (vr1*delx + vr2*dely + vr3*delz)/r;
vn1 = vnnr*delx/r;
vn2 = vnnr*dely/r;
vn3 = vnnr*delz/r;
// tangential component vr - (vr.n)n
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// force due to squeeze type motion
fx = a_sq*vn1;
fy = a_sq*vn2;
fz = a_sq*vn3;
// force due to all shear kind of motions
if (flaglog) {
fx = fx + a_sh*vt1;
fy = fy + a_sh*vt2;
fz = fz + a_sh*vt3;
}
// scale forces for appropriate units
fx *= vxmu2f;
fy *= vxmu2f;
fz *= vxmu2f;
// add to total force
f[i][0] -= fx;
f[i][1] -= fy;
f[i][2] -= fz;
if (newton_pair || j < nlocal) {
f[j][0] += fx;
f[j][1] += fy;
f[j][2] += fz;
}
// torque due to this force
if (flaglog) {
tx = xl[1]*fz - xl[2]*fy;
ty = xl[2]*fx - xl[0]*fz;
tz = xl[0]*fy - xl[1]*fx;
torque[i][0] -= vxmu2f*tx;
torque[i][1] -= vxmu2f*ty;
torque[i][2] -= vxmu2f*tz;
if (newton_pair || j < nlocal) {
torque[j][0] -= vxmu2f*tx;
torque[j][1] -= vxmu2f*ty;
torque[j][2] -= vxmu2f*tz;
}
// torque due to a_pu
wdotn = ((wi[0]-wj[0])*delx + (wi[1]-wj[1])*dely +
(wi[2]-wj[2])*delz)/r;
wt1 = (wi[0]-wj[0]) - wdotn*delx/r;
wt2 = (wi[1]-wj[1]) - wdotn*dely/r;
wt3 = (wi[2]-wj[2]) - wdotn*delz/r;
tx = a_pu*wt1;
ty = a_pu*wt2;
tz = a_pu*wt3;
torque[i][0] -= vxmu2f*tx;
torque[i][1] -= vxmu2f*ty;
torque[i][2] -= vxmu2f*tz;
if (newton_pair || j < nlocal) {
torque[j][0] += vxmu2f*tx;
torque[j][1] += vxmu2f*ty;
torque[j][2] += vxmu2f*tz;
}
}
if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
0.0,0.0,-fx,-fy,-fz,delx,dely,delz);
}
}
}
// restore streaming component of velocity, omega, angmom
if (shearing) {
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
radi = radius[i];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
v[i][0] += vstream[0];
v[i][1] += vstream[1];
v[i][2] += vstream[2];
omega[i][0] -= 0.5*h_rate[3];
omega[i][1] += 0.5*h_rate[4];
omega[i][2] -= 0.5*h_rate[5];
}
}
// to DEBUG: set print_overlaps to 1
int print_overlaps = 0;
if (print_overlaps) {
int overlaps_all;
MPI_Allreduce(&overlaps,&overlaps_all,1,MPI_INT,MPI_SUM,world);
if (overlaps_all && comm->me == 0)
printf("Number of overlaps = %d\n",overlaps);
}
if (vflag_fdotr) virial_fdotr_compute();
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairLubricate::allocate()
{
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(cut,n+1,n+1,"pair:cut");
memory->create(cut_inner,n+1,n+1,"pair:cut_inner");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairLubricate::settings(int narg, char **arg)
{
if (narg != 5) error->all(FLERR,"Illegal pair_style command");
mu = atof(arg[0]);
flaglog = atoi(arg[1]);
flagfld = atoi(arg[2]);
cut_inner_global = atof(arg[3]);
cut_global = atof(arg[4]);
// reset cutoffs that have been explicitly set
if (allocated) {
for (int i = 1; i <= atom->ntypes; i++)
for (int j = i+1; j <= atom->ntypes; j++)
if (setflag[i][j]) {
cut_inner[i][j] = cut_inner_global;
cut[i][j] = cut_global;
}
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairLubricate::coeff(int narg, char **arg)
{
if (narg != 2 && narg != 4)
error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(arg[0],atom->ntypes,ilo,ihi);
force->bounds(arg[1],atom->ntypes,jlo,jhi);
double cut_inner_one = cut_inner_global;
double cut_one = cut_global;
if (narg == 4) {
cut_inner_one = atof(arg[2]);
cut_one = atof(arg[3]);
}
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
cut_inner[i][j] = cut_inner_one;
cut[i][j] = cut_one;
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairLubricate::init_style()
{
if (!atom->sphere_flag)
error->all(FLERR,"Pair lubricate requires atom style sphere");
if (comm->ghost_velocity == 0)
error->all(FLERR,"Pair lubricate requires ghost atoms store velocity");
int irequest = neighbor->request(this);
// require that atom radii are identical within each type
// require monodisperse system with same radii for all types
double rad,radtype;
for (int i = 1; i <= atom->ntypes; i++) {
if (!atom->radius_consistency(i,radtype))
error->all(FLERR,"Pair lubricate requires monodisperse particles");
if (i > 1 && radtype != rad)
error->all(FLERR,"Pair lubricate requires monodisperse particles");
rad = radtype;
}
// set the isotropic constants that depend on the volume fraction
// vol_T = total volume
double vol_T = domain->xprd*domain->yprd*domain->zprd;
// vol_P = volume of particles, assuming monodispersity
// vol_f = volume fraction
double vol_P = atom->natoms*(4.0/3.0)*MY_PI*pow(rad,3);
double vol_f = vol_P/vol_T;
// set isotropic constants for FLD
if (flaglog == 0) {
R0 = 6*MY_PI*mu*rad*(1.0 + 2.16*vol_f);
RT0 = 8*MY_PI*mu*pow(rad,3);
RS0 = 20.0/3.0*MY_PI*mu*pow(rad,3)*(1.0 + 3.33*vol_f + 2.80*vol_f*vol_f);
} else {
R0 = 6*MY_PI*mu*rad*(1.0 + 2.725*vol_f - 6.583*vol_f*vol_f);
RT0 = 8*MY_PI*mu*pow(rad,3)*(1.0 + 0.749*vol_f - 2.469*vol_f*vol_f);
RS0 = 20.0/3.0*MY_PI*mu*pow(rad,3)*(1.0 + 3.64*vol_f - 6.95*vol_f*vol_f);
}
// check for fix deform, if exists it must use "remap v"
shearing = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
shearing = 1;
if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP)
error->all(FLERR,"Using pair lubricate with inconsistent "
"fix deform remap option");
}
// set Ef = 0 since used whether shearing or not
Ef[0][0] = Ef[0][1] = Ef[0][2] = 0.0;
Ef[1][0] = Ef[1][1] = Ef[1][2] = 0.0;
Ef[2][0] = Ef[2][1] = Ef[2][2] = 0.0;
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairLubricate::init_one(int i, int j)
{
if (setflag[i][j] == 0) {
cut_inner[i][j] = mix_distance(cut_inner[i][i],cut_inner[j][j]);
cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
}
cut_inner[j][i] = cut_inner[i][j];
return cut[i][j];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairLubricate::write_restart(FILE *fp)
{
write_restart_settings(fp);
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j],sizeof(int),1,fp);
if (setflag[i][j]) {
fwrite(&cut_inner[i][j],sizeof(double),1,fp);
fwrite(&cut[i][j],sizeof(double),1,fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairLubricate::read_restart(FILE *fp)
{
read_restart_settings(fp);
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
if (setflag[i][j]) {
if (me == 0) {
fread(&cut_inner[i][j],sizeof(double),1,fp);
fread(&cut[i][j],sizeof(double),1,fp);
}
MPI_Bcast(&cut_inner[i][j],1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairLubricate::write_restart_settings(FILE *fp)
{
fwrite(&mu,sizeof(double),1,fp);
fwrite(&flaglog,sizeof(int),1,fp);
fwrite(&flagfld,sizeof(int),1,fp);
fwrite(&cut_inner_global,sizeof(double),1,fp);
fwrite(&cut_global,sizeof(double),1,fp);
fwrite(&offset_flag,sizeof(int),1,fp);
fwrite(&mix_flag,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairLubricate::read_restart_settings(FILE *fp)
{
int me = comm->me;
if (me == 0) {
fread(&mu,sizeof(double),1,fp);
fread(&flaglog,sizeof(int),1,fp);
fread(&flagfld,sizeof(int),1,fp);
fread(&cut_inner_global,sizeof(double),1,fp);
fread(&cut_global,sizeof(double),1,fp);
fread(&offset_flag,sizeof(int),1,fp);
fread(&mix_flag,sizeof(int),1,fp);
}
MPI_Bcast(&mu,1,MPI_DOUBLE,0,world);
MPI_Bcast(&flaglog,1,MPI_INT,0,world);
MPI_Bcast(&flagfld,1,MPI_INT,0,world);
MPI_Bcast(&cut_inner_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
}
/* ---------------------------------------------------------------------- */
int PairLubricate::pack_comm(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double **v = atom->v;
double **omega = atom->omega;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
buf[m++] = omega[j][0];
buf[m++] = omega[j][1];
buf[m++] = omega[j][2];
}
return 6;
}
/* ---------------------------------------------------------------------- */
void PairLubricate::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
double **v = atom->v;
double **omega = atom->omega;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
v[i][0] = buf[m++];
v[i][1] = buf[m++];
v[i][2] = buf[m++];
omega[i][0] = buf[m++];
omega[i][1] = buf[m++];
omega[i][2] = buf[m++];
}
}
/* ----------------------------------------------------------------------
check if name is recognized, return integer index for that name
if name not recognized, return -1
if type pair setting, return -2 if no type pairs are set
------------------------------------------------------------------------- */
int PairLubricate::pre_adapt(char *name, int ilo, int ihi, int jlo, int jhi)
{
if (strcmp(name,"mu") == 0) return 0;
return -1;
}
/* ----------------------------------------------------------------------
adapt parameter indexed by which
change all pair variables affected by the reset parameter
if type pair setting, set I-J and J-I coeffs
------------------------------------------------------------------------- */
void PairLubricate::adapt(int which, int ilo, int ihi, int jlo, int jhi,
double value)
{
mu = value;
}

59
src/FLD/pair_lubricate.h Normal file
View File

@ -0,0 +1,59 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lubricate,PairLubricate)
#else
#ifndef LMP_PAIR_LUBRICATE_H
#define LMP_PAIR_LUBRICATE_H
#include "pair.h"
namespace LAMMPS_NS {
class PairLubricate : public Pair {
public:
PairLubricate(class LAMMPS *);
virtual ~PairLubricate();
virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
double init_one(int, int);
virtual void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
int pre_adapt(char *, int, int, int, int);
void adapt(int, int, int, int, int, double);
int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
protected:
double mu,cut_inner_global,cut_global;
int flaglog,flagfld,shearing;
double Ef[3][3];
double R0,RT0,RS0;
double **cut_inner,**cut;
void allocate();
};
}
#endif
#endif

1933
src/FLD/pair_lubricateU.cpp Normal file

File diff suppressed because it is too large Load Diff

74
src/FLD/pair_lubricateU.h Normal file
View File

@ -0,0 +1,74 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lubricateU,PairLubricateU)
#else
#ifndef LMP_PAIR_LUBRICATEU_H
#define LMP_PAIR_LUBRICATEU_H
#include "pair.h"
namespace LAMMPS_NS {
class PairLubricateU : public Pair {
public:
PairLubricateU(class LAMMPS *);
virtual ~PairLubricateU();
virtual void compute(int, int);
virtual void settings(int, char **);
void coeff(int, char **);
double init_one(int, int);
virtual void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
protected:
double cut_inner_global,cut_global;
double mu;
int flaglog;
double gdot,Ef[3][3];
double **cut_inner,**cut;
void allocate();
double R0,RT0,RS0;
int nmax;
double **fl,**Tl,**xl;
int cgmax;
double *bcg,*xcg,*rcg,*rcg1,*pcg,*RU;
void compute_RE();
virtual void compute_RE(double **);
void compute_RU();
virtual void compute_RU(double **);
virtual void compute_Fh(double **);
void stage_one();
void intermediates(int, double **);
void stage_two(double **);
void copy_vec_uo(int, double *, double **, double **);
void copy_uo_vec(int, double **, double **, double *);
double dot_vec_vec(int , double *, double *);
};
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
/* ----------------------------------------------------------------------
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(lubricateU/poly,PairLubricateUPoly)
#else
#ifndef LMP_PAIR_LUBRICATEU_POLY_H
#define LMP_PAIR_LUBRICATEU_POLY_H
#include "pair_lubricateU.h"
namespace LAMMPS_NS {
class PairLubricateUPoly : public PairLubricateU {
public:
PairLubricateUPoly(class LAMMPS *);
~PairLubricateUPoly() {}
void compute(int, int);
void settings(int, char **);
void init_style();
private:
void iterate(double **, int);
void compute_RE(double **);
void compute_RU(double **);
void compute_Fh(double **);
};
}
#endif
#endif

View File

@ -0,0 +1,459 @@
/* ----------------------------------------------------------------------
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: Randy Schunk (SNL)
Amit Kumar and Michael Bybee (UIUC)
Dave Heine (Corning), polydispersity
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_lubricate_poly.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "domain.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "memory.h"
#include "random_mars.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
// same as fix_deform.cpp
enum{NO_REMAP,X_REMAP,V_REMAP};
/* ---------------------------------------------------------------------- */
PairLubricatePoly::PairLubricatePoly(LAMMPS *lmp) : PairLubricate(lmp)
{
no_virial_fdotr_compute = 1;
}
/* ---------------------------------------------------------------------- */
void PairLubricatePoly::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz,tx,ty,tz;
double rsq,r,h_sep,h_sepj,beta0,beta1,betaj,betaj1,radi,radj,tfmag;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3;
double vt1,vt2,vt3,wt1,wt2,wt3,wdotn;
double inertia,inv_inertia,vRS0;
double vi[3],vj[3],wi[3],wj[3],xl[3],jl[3];
double a_sq,a_sh,a_pu,Fbmag,del,delmin,eta;
int *ilist,*jlist,*numneigh,**firstneigh;
double lamda[3],vstream[3];
double vxmu2f = force->vxmu2f;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *radius = atom->radius;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
int overlaps = 0;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// subtract streaming component of velocity, omega, angmom
// assume fluid streaming velocity = box deformation rate
// vstream = (ux,uy,uz)
// ux = h_rate[0]*x + h_rate[5]*y + h_rate[4]*z
// uy = h_rate[1]*y + h_rate[3]*z
// uz = h_rate[2]*z
// omega_new = omega - curl(vstream)/2
// angmom_new = angmom - I*curl(vstream)/2
// Ef = (grad(vstream) + (grad(vstream))^T) / 2
if (shearing) {
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
radi = radius[i];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
v[i][0] -= vstream[0];
v[i][1] -= vstream[1];
v[i][2] -= vstream[2];
omega[i][0] += 0.5*h_rate[3];
omega[i][1] -= 0.5*h_rate[4];
omega[i][2] += 0.5*h_rate[5];
}
// set Ef from h_rate in strain units
Ef[0][0] = h_rate[0]/domain->xprd;
Ef[1][1] = h_rate[1]/domain->yprd;
Ef[2][2] = h_rate[2]/domain->zprd;
Ef[0][1] = Ef[1][0] = 0.5 * h_rate[5]/domain->yprd;
Ef[0][2] = Ef[2][0] = 0.5 * h_rate[4]/domain->zprd;
Ef[1][2] = Ef[2][1] = 0.5 * h_rate[3]/domain->zprd;
// copy updated omega to the ghost particles
// no need to do this if not shearing since comm->ghost_velocity is set
comm->forward_comm_pair(this);
}
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
jlist = firstneigh[i];
jnum = numneigh[i];
radi = radius[i];
// angular velocity
wi[0] = omega[i][0];
wi[1] = omega[i][1];
wi[2] = omega[i][2];
// FLD contribution to force and torque due to isotropic terms
// FLD contribution to stress from isotropic RS0
if (flagfld) {
f[i][0] -= vxmu2f*R0*radi*v[i][0];
f[i][1] -= vxmu2f*R0*radi*v[i][1];
f[i][2] -= vxmu2f*R0*radi*v[i][2];
torque[i][0] -= vxmu2f*RT0*pow(radi,3)*wi[0];
torque[i][1] -= vxmu2f*RT0*pow(radi,3)*wi[1];
torque[i][2] -= vxmu2f*RT0*pow(radi,3)*wi[2];
if (shearing && vflag_either) {
vRS0 = -vxmu2f * RS0*pow(radi,3);
v_tally_tensor(i,i,nlocal,newton_pair,
vRS0*Ef[0][0],vRS0*Ef[1][1],vRS0*Ef[2][2],
vRS0*Ef[0][1],vRS0*Ef[0][2],vRS0*Ef[1][2]);
}
}
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
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 = atom->radius[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
// angular momentum = I*omega = 2/5 * M*R^2 * omega
wj[0] = omega[j][0];
wj[1] = omega[j][1];
wj[2] = omega[j][2];
// xl = point of closest approach on particle i from its center
xl[0] = -delx/r*radi;
xl[1] = -dely/r*radi;
xl[2] = -delz/r*radi;
jl[0] = -delx/r*radj;
jl[1] = -dely/r*radj;
jl[2] = -delz/r*radj;
// velocity at the point of closest approach on both particles
// v = v + omega_cross_xl - Ef.xl
// particle i
vi[0] = v[i][0] + (wi[1]*xl[2] - wi[2]*xl[1])
- (Ef[0][0]*xl[0] + Ef[0][1]*xl[1] + Ef[0][2]*xl[2]);
vi[1] = v[i][1] + (wi[2]*xl[0] - wi[0]*xl[2])
- (Ef[1][0]*xl[0] + Ef[1][1]*xl[1] + Ef[1][2]*xl[2]);
vi[2] = v[i][2] + (wi[0]*xl[1] - wi[1]*xl[0])
- (Ef[2][0]*xl[0] + Ef[2][1]*xl[1] + Ef[2][2]*xl[2]);
// particle j
vj[0] = v[j][0] - (wj[1]*jl[2] - wj[2]*jl[1])
+ (Ef[0][0]*jl[0] + Ef[0][1]*jl[1] + Ef[0][2]*jl[2]);
vj[1] = v[j][1] - (wj[2]*jl[0] - wj[0]*jl[2])
+ (Ef[1][0]*jl[0] + Ef[1][1]*jl[1] + Ef[1][2]*jl[2]);
vj[2] = v[j][2] - (wj[0]*jl[1] - wj[1]*jl[0])
+ (Ef[2][0]*jl[0] + Ef[2][1]*jl[1] + Ef[2][2]*jl[2]);
// scalar resistances XA and YA
h_sep = r - radi-radj;
// check for overlaps
if (h_sep < 0.0) overlaps++;
// if less than the minimum gap use the minimum gap instead
if (r < cut_inner[itype][jtype])
h_sep = cut_inner[itype][jtype] - radi-radj;
// scale h_sep by radi
h_sep = h_sep/radi;
beta0 = radj/radi;
beta1 = 1.0 + beta0;
// scalar resistances
if (flaglog) {
a_sq = beta0*beta0/beta1/beta1/h_sep +
(1.0+7.0*beta0+beta0*beta0)/5.0/pow(beta1,3)*log(1.0/h_sep);
a_sq += (1.0+18.0*beta0-29.0*beta0*beta0+18.0 *
pow(beta0,3)+pow(beta0,4))/21.0/pow(beta1,4) *
h_sep*log(1.0/h_sep);
a_sq *= 6.0*MY_PI*mu*radi;
a_sh = 4.0*beta0*(2.0+beta0+2.0*beta0*beta0)/15.0/pow(beta1,3) *
log(1.0/h_sep);
a_sh += 4.0*(16.0-45.0*beta0+58.0*beta0*beta0-45.0*pow(beta0,3) +
16.0*pow(beta0,4))/375.0/pow(beta1,4) *
h_sep*log(1.0/h_sep);
a_sh *= 6.0*MY_PI*mu*radi;
a_pu = beta0*(4.0+beta0)/10.0/beta1/beta1*log(1.0/h_sep);
a_pu += (32.0-33.0*beta0+83.0*beta0*beta0+43.0 *
pow(beta0,3))/250.0/pow(beta1,3)*h_sep*log(1.0/h_sep);
a_pu *= 8.0*MY_PI*mu*pow(radi,3);
} else a_sq = 6.0*MY_PI*mu*radi*(beta0*beta0/beta1/beta1/h_sep);
// relative velocity at the point of closest approach
// includes fluid velocity
vr1 = vi[0] - vj[0];
vr2 = vi[1] - vj[1];
vr3 = vi[2] - vj[2];
// normal component (vr.n)n
vnnr = (vr1*delx + vr2*dely + vr3*delz)/r;
vn1 = vnnr*delx/r;
vn2 = vnnr*dely/r;
vn3 = vnnr*delz/r;
// tangential component vr - (vr.n)n
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// force due to squeeze type motion
fx = a_sq*vn1;
fy = a_sq*vn2;
fz = a_sq*vn3;
// force due to all shear kind of motions
if (flaglog) {
fx = fx + a_sh*vt1;
fy = fy + a_sh*vt2;
fz = fz + a_sh*vt3;
}
// scale forces for appropriate units
fx *= vxmu2f;
fy *= vxmu2f;
fz *= vxmu2f;
// add to total force
f[i][0] -= fx;
f[i][1] -= fy;
f[i][2] -= fz;
// torque due to this force
if (flaglog) {
tx = xl[1]*fz - xl[2]*fy;
ty = xl[2]*fx - xl[0]*fz;
tz = xl[0]*fy - xl[1]*fx;
torque[i][0] -= vxmu2f*tx;
torque[i][1] -= vxmu2f*ty;
torque[i][2] -= vxmu2f*tz;
// torque due to a_pu
wdotn = ((wi[0]-wj[0])*delx + (wi[1]-wj[1])*dely +
(wi[2]-wj[2])*delz)/r;
wt1 = (wi[0]-wj[0]) - wdotn*delx/r;
wt2 = (wi[1]-wj[1]) - wdotn*dely/r;
wt3 = (wi[2]-wj[2]) - wdotn*delz/r;
tx = a_pu*wt1;
ty = a_pu*wt2;
tz = a_pu*wt3;
torque[i][0] -= vxmu2f*tx;
torque[i][1] -= vxmu2f*ty;
torque[i][2] -= vxmu2f*tz;
}
// set j = nlocal so that only I gets tallied
if (evflag) ev_tally_xyz(i,nlocal,nlocal,0,
0.0,0.0,-fx,-fy,-fz,delx,dely,delz);
}
}
}
// restore streaming component of velocity, omega, angmom
if (shearing) {
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
radi = atom->radius[i];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
v[i][0] += vstream[0];
v[i][1] += vstream[1];
v[i][2] += vstream[2];
omega[i][0] -= 0.5*h_rate[3];
omega[i][1] += 0.5*h_rate[4];
omega[i][2] -= 0.5*h_rate[5];
}
}
// to DEBUG: set print_overlaps to 1
int print_overlaps = 0;
if (print_overlaps) {
int overlaps_all;
MPI_Allreduce(&overlaps,&overlaps_all,1,MPI_INT,MPI_SUM,world);
if (overlaps_all && comm->me == 0)
printf("Number of overlaps = %d\n",overlaps);
}
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairLubricatePoly::init_style()
{
if (force->newton_pair == 1)
error->all(FLERR,"Pair lubricate/poly requires newton pair off");
if (comm->ghost_velocity == 0)
error->all(FLERR,
"Pair lubricate/poly requires ghost atoms store velocity");
if (!atom->sphere_flag)
error->all(FLERR,"Pair lubricate/poly requires atom style sphere");
// insure all particles are finite-size
// for pair hybrid, should limit test to types using the pair style
double *radius = atom->radius;
int *type = atom->type;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (radius[i] == 0.0)
error->one(FLERR,"Pair lubricate/poly requires extended particles");
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
// set the isotropic constants that depend on the volume fraction
// vol_T = total volume
double vol_T = domain->xprd*domain->yprd*domain->zprd;
double volP = 0.0;
for (int i = 0; i < nlocal; i++)
volP += (4.0/3.0)*MY_PI*pow(atom->radius[i],3);
double vol_P;
MPI_Allreduce(&volP,&vol_P,1,MPI_DOUBLE,MPI_SUM,world);
double vol_f = vol_P/vol_T;
// set isotropic constants
if (flaglog == 0) {
R0 = 6*MY_PI*mu*(1.0 + 2.16*vol_f);
RT0 = 8*MY_PI*mu;
RS0 = 20.0/3.0*MY_PI*mu*(1.0 + 3.33*vol_f + 2.80*vol_f*vol_f);
} else {
R0 = 6*MY_PI*mu*(1.0 + 2.725*vol_f - 6.583*vol_f*vol_f);
RT0 = 8*MY_PI*mu*(1.0 + 0.749*vol_f - 2.469*vol_f*vol_f);
RS0 = 20.0/3.0*MY_PI*mu*(1.0 + 3.64*vol_f - 6.95*vol_f*vol_f);
}
// check for fix deform, if exists it must use "remap v"
shearing = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
shearing = 1;
if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP)
error->all(FLERR,"Using pair lubricate/poly with inconsistent "
"fix deform remap option");
}
// set Ef = 0 since used whether shearing or not
Ef[0][0] = Ef[0][1] = Ef[0][2] = 0.0;
Ef[1][0] = Ef[1][1] = Ef[1][2] = 0.0;
Ef[2][0] = Ef[2][1] = Ef[2][2] = 0.0;
}

View File

@ -0,0 +1,38 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(lubricate/poly,PairLubricatePoly)
#else
#ifndef LMP_PAIR_LUBRICATE_POLY_H
#define LMP_PAIR_LUBRICATE_POLY_H
#include "pair_lubricate.h"
namespace LAMMPS_NS {
class PairLubricatePoly : public PairLubricate {
public:
PairLubricatePoly(class LAMMPS *);
~PairLubricatePoly() {}
void compute(int, int);
void init_style();
};
}
#endif
#endif

View File

@ -13,7 +13,7 @@ OBJ = $(SRC:.cpp=.o)
# Package variables
PACKAGE = asphere class2 colloid dipole gpu granular \
PACKAGE = asphere class2 colloid dipole fld gpu granular \
kspace manybody mc meam molecule opt peri poems reax replica \
shock srd xtc