Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F66480580
fix_wall.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Mon, Jun 10, 19:48
Size
9 KB
Mime Type
text/x-c
Expires
Wed, Jun 12, 19:48 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
18228912
Attached To
rLAMMPS lammps
fix_wall.cpp
View Options
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "fix_wall.h"
#include "atom.h"
#include "input.h"
#include "variable.h"
#include "domain.h"
#include "lattice.h"
#include "update.h"
#include "modify.h"
#include "respa.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum{XLO,XHI,YLO,YHI,ZLO,ZHI};
enum{EDGE,CONSTANT,VARIABLE};
/* ---------------------------------------------------------------------- */
FixWall::FixWall(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
scalar_flag = 1;
vector_flag = 1;
global_freq = 1;
extscalar = 1;
extvector = 1;
// parse args
nwall = 0;
int scaleflag = 1;
fldflag = 0;
int iarg = 3;
while (iarg < narg) {
if ((strcmp(arg[iarg],"xlo") == 0) || (strcmp(arg[iarg],"xhi") == 0) ||
(strcmp(arg[iarg],"ylo") == 0) || (strcmp(arg[iarg],"yhi") == 0) ||
(strcmp(arg[iarg],"zlo") == 0) || (strcmp(arg[iarg],"zhi") == 0)) {
if (iarg+5 > narg) error->all(FLERR,"Illegal fix wall command");
int newwall;
if (strcmp(arg[iarg],"xlo") == 0) newwall = XLO;
else if (strcmp(arg[iarg],"xhi") == 0) newwall = XHI;
else if (strcmp(arg[iarg],"ylo") == 0) newwall = YLO;
else if (strcmp(arg[iarg],"yhi") == 0) newwall = YHI;
else if (strcmp(arg[iarg],"zlo") == 0) newwall = ZLO;
else if (strcmp(arg[iarg],"zhi") == 0) newwall = ZHI;
for (int m = 0; m < nwall; m++)
if (newwall == wallwhich[m])
error->all(FLERR,"Wall defined twice in fix wall command");
wallwhich[nwall] = newwall;
if (strcmp(arg[iarg+1],"EDGE") == 0) {
wallstyle[nwall] = EDGE;
int dim = wallwhich[nwall] / 2;
int side = wallwhich[nwall] % 2;
if (side == 0) coord0[nwall] = domain->boxlo[dim];
else coord0[nwall] = domain->boxhi[dim];
} else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
wallstyle[nwall] = VARIABLE;
int n = strlen(&arg[iarg+1][2]) + 1;
varstr[nwall] = new char[n];
strcpy(varstr[nwall],&arg[iarg+1][2]);
} else {
wallstyle[nwall] = CONSTANT;
coord0[nwall] = atof(arg[iarg+1]);
}
epsilon[nwall] = atof(arg[iarg+2]);
sigma[nwall] = atof(arg[iarg+3]);
cutoff[nwall] = atof(arg[iarg+4]);
nwall++;
iarg += 5;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal fix wall command");
iarg += 2;
} else if (strcmp(arg[iarg],"fld") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix wall command");
if (strcmp(arg[iarg+1],"no") == 0) fldflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) fldflag = 1;
else error->all(FLERR,"Illegal fix wall command");
iarg += 2;
} else error->all(FLERR,"Illegal fix wall command");
}
size_vector = nwall;
// error check
if (nwall == 0) error->all(FLERR,"Illegal fix wall command");
for (int m = 0; m < nwall; m++)
if (cutoff[m] <= 0.0)
error->all(FLERR,"Fix wall cutoff <= 0.0");
for (int m = 0; m < nwall; m++) {
if ((wallwhich[m] == XLO || wallwhich[m] == XHI) && domain->xperiodic)
error->all(FLERR,"Cannot use fix wall in periodic dimension");
if ((wallwhich[m] == YLO || wallwhich[m] == YHI) && domain->yperiodic)
error->all(FLERR,"Cannot use fix wall in periodic dimension");
if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->zperiodic)
error->all(FLERR,"Cannot use fix wall in periodic dimension");
}
for (int m = 0; m < nwall; m++)
if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->dimension == 2)
error->all(FLERR,"Cannot use fix wall zlo/zhi for a 2d simulation");
// scale factors for CONSTANT and VARIABLE walls
int flag = 0;
for (int m = 0; m < nwall; m++)
if (wallstyle[m] != EDGE) flag = 1;
if (flag) {
if (scaleflag && domain->lattice == NULL)
error->all(FLERR,"Use of fix wall with undefined lattice");
if (scaleflag) {
xscale = domain->lattice->xlattice;
yscale = domain->lattice->ylattice;
zscale = domain->lattice->zlattice;
}
else xscale = yscale = zscale = 1.0;
for (int m = 0; m < nwall; m++) {
if (wallstyle[m] != CONSTANT) continue;
if (wallwhich[m] < YLO) coord0[m] *= xscale;
else if (wallwhich[m] < ZLO) coord0[m] *= yscale;
else coord0[m] *= zscale;
}
}
// set time_depend and varflag if any wall positions are variable
varflag = 0;
for (int m = 0; m < nwall; m++)
if (wallstyle[m] == VARIABLE) time_depend = varflag = 1;
eflag = 0;
for (int m = 0; m <= nwall; m++) ewall[m] = 0.0;
}
/* ---------------------------------------------------------------------- */
FixWall::~FixWall()
{
for (int m = 0; m < nwall; m++)
if (wallstyle[m] == VARIABLE) delete [] varstr[m];
}
/* ---------------------------------------------------------------------- */
int FixWall::setmask()
{
int mask = 0;
// FLD implicit needs to invoke wall forces before pair style
if (fldflag) mask != PRE_FORCE;
else mask |= POST_FORCE;
mask |= THERMO_ENERGY;
mask |= POST_FORCE_RESPA;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixWall::init()
{
dt = update->dt;
for (int m = 0; m < nwall; m++) {
if (wallstyle[m] != VARIABLE) continue;
varindex[m] = input->variable->find(varstr[m]);
if (varindex[m] < 0)
error->all(FLERR,"Variable name for fix wall does not exist");
if (!input->variable->equalstyle(varindex[m]))
error->all(FLERR,"Variable for fix wall is invalid style");
}
// setup coefficients
for (int m = 0; m < nwall; m++) precompute(m);
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixWall::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
if (!fldflag) post_force(vflag);
else {
((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
post_force_respa(vflag,nlevels_respa-1,0);
((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
}
}
/* ---------------------------------------------------------------------- */
void FixWall::min_setup(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
only called if fldflag set, in place of post_force
------------------------------------------------------------------------- */
void FixWall::pre_force(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixWall::post_force(int vflag)
{
eflag = 0;
for (int m = 0; m <= nwall; m++) ewall[m] = 0.0;
// coord = current position of wall
// evaluate variable if necessary, wrap with clear/add
if (varflag) modify->clearstep_compute();
double coord;
for (int m = 0; m < nwall; m++) {
if (wallstyle[m] == VARIABLE) {
coord = input->variable->compute_equal(varindex[m]);
if (wallwhich[m] < YLO) coord *= xscale;
else if (wallwhich[m] < ZLO) coord *= yscale;
else coord *= zscale;
} else coord = coord0[m];
wall_particle(m,wallwhich[m],coord);
}
if (varflag) modify->addstep_compute(update->ntimestep + 1);
}
/* ---------------------------------------------------------------------- */
void FixWall::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixWall::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
energy of wall interaction
------------------------------------------------------------------------- */
double FixWall::compute_scalar()
{
// only sum across procs one time
if (eflag == 0) {
MPI_Allreduce(ewall,ewall_all,nwall+1,MPI_DOUBLE,MPI_SUM,world);
eflag = 1;
}
return ewall_all[0];
}
/* ----------------------------------------------------------------------
components of force on wall
------------------------------------------------------------------------- */
double FixWall::compute_vector(int n)
{
// only sum across procs one time
if (eflag == 0) {
MPI_Allreduce(ewall,ewall_all,nwall+1,MPI_DOUBLE,MPI_SUM,world);
eflag = 1;
}
return ewall_all[n+1];
}
Event Timeline
Log In to Comment