git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7686 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
123
src/domain.cpp
123
src/domain.cpp
@ -31,10 +31,12 @@
|
||||
#include "region.h"
|
||||
#include "lattice.h"
|
||||
#include "comm.h"
|
||||
#include "math_const.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
|
||||
#define BIG 1.0e20
|
||||
#define SMALL 1.0e-4
|
||||
@ -132,16 +134,11 @@ void Domain::set_initial_box()
|
||||
if (boxlo[0] >= boxhi[0] || boxlo[1] >= boxhi[1] || boxlo[2] >= boxhi[2])
|
||||
error->one(FLERR,"Box bounds are invalid");
|
||||
|
||||
// error check on triclinic tilt factors
|
||||
|
||||
if (triclinic) {
|
||||
if (domain->dimension == 2 && (xz != 0.0 || yz != 0.0))
|
||||
error->all(FLERR,"Cannot skew triclinic box in z for 2d simulation");
|
||||
if (xy != 0.0 && (!xperiodic || !yperiodic))
|
||||
error->all(FLERR,"Triclinic box must be periodic in skewed dimensions");
|
||||
if (xz != 0.0 && (!xperiodic || !zperiodic))
|
||||
error->all(FLERR,"Triclinic box must be periodic in skewed dimensions");
|
||||
if (yz != 0.0 && (!yperiodic || !zperiodic))
|
||||
error->all(FLERR,"Triclinic box must be periodic in skewed dimensions");
|
||||
|
||||
if (fabs(xy/(boxhi[0]-boxlo[0])) > 0.5)
|
||||
error->all(FLERR,"Triclinic box skew is too large");
|
||||
if (fabs(xz/(boxhi[0]-boxlo[0])) > 0.5)
|
||||
@ -150,21 +147,28 @@ void Domain::set_initial_box()
|
||||
error->all(FLERR,"Triclinic box skew is too large");
|
||||
}
|
||||
|
||||
// set small based on box size and SMALL
|
||||
// this works for any unit system
|
||||
|
||||
small[0] = SMALL * (boxhi[0] - boxlo[0]);
|
||||
small[1] = SMALL * (boxhi[1] - boxlo[1]);
|
||||
small[2] = SMALL * (boxhi[2] - boxlo[2]);
|
||||
|
||||
// adjust box lo/hi for shrink-wrapped dims
|
||||
|
||||
if (boundary[0][0] == 2) boxlo[0] -= SMALL;
|
||||
if (boundary[0][0] == 2) boxlo[0] -= small[0];
|
||||
else if (boundary[0][0] == 3) minxlo = boxlo[0];
|
||||
if (boundary[0][1] == 2) boxhi[0] += SMALL;
|
||||
if (boundary[0][1] == 2) boxhi[0] += small[0];
|
||||
else if (boundary[0][1] == 3) minxhi = boxhi[0];
|
||||
|
||||
if (boundary[1][0] == 2) boxlo[1] -= SMALL;
|
||||
if (boundary[1][0] == 2) boxlo[1] -= small[1];
|
||||
else if (boundary[1][0] == 3) minylo = boxlo[1];
|
||||
if (boundary[1][1] == 2) boxhi[1] += SMALL;
|
||||
if (boundary[1][1] == 2) boxhi[1] += small[1];
|
||||
else if (boundary[1][1] == 3) minyhi = boxhi[1];
|
||||
|
||||
if (boundary[2][0] == 2) boxlo[2] -= SMALL;
|
||||
if (boundary[2][0] == 2) boxlo[2] -= small[2];
|
||||
else if (boundary[2][0] == 3) minzlo = boxlo[2];
|
||||
if (boundary[2][1] == 2) boxhi[2] += SMALL;
|
||||
if (boundary[2][1] == 2) boxhi[2] += small[2];
|
||||
else if (boundary[2][1] == 3) minzhi = boxhi[2];
|
||||
}
|
||||
|
||||
@ -270,19 +274,16 @@ void Domain::set_local_box()
|
||||
/* ----------------------------------------------------------------------
|
||||
reset global & local boxes due to global box boundary changes
|
||||
if shrink-wrapped, determine atom extent and reset boxlo/hi
|
||||
if shrink-wrapped and triclinic, perform shrink-wrap in box coords
|
||||
if triclinic, perform any shrink-wrap in lamda space
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Domain::reset_box()
|
||||
{
|
||||
if (nonperiodic == 2) {
|
||||
|
||||
// convert back to box coords for shrink-wrap operation
|
||||
|
||||
if (triclinic) lamda2x(atom->nlocal);
|
||||
|
||||
// perform shrink-wrapping
|
||||
// compute extent of atoms on this proc
|
||||
// for triclinic, this is done in lamda space
|
||||
|
||||
if (nonperiodic == 2) {
|
||||
double extent[3][2],all[3][2];
|
||||
|
||||
extent[2][0] = extent[1][0] = extent[0][0] = BIG;
|
||||
@ -309,37 +310,91 @@ void Domain::reset_box()
|
||||
|
||||
MPI_Allreduce(extent,all,6,MPI_DOUBLE,MPI_MAX,world);
|
||||
|
||||
// for triclinic, convert back to box coords before changing box
|
||||
|
||||
if (triclinic) lamda2x(atom->nlocal);
|
||||
|
||||
// in shrink-wrapped dims, set box by atom extent
|
||||
// if minimum set, enforce min box size settings
|
||||
// for triclinic, convert lamda extent to box coords, then set box lo/hi
|
||||
// decided NOT to do the next comment - don't want to sneakily change tilt
|
||||
// for triclinic, adjust tilt factors if 2nd dim is shrink-wrapped,
|
||||
// so that displacement in 1st dim stays the same
|
||||
|
||||
if (triclinic == 0) {
|
||||
if (xperiodic == 0) {
|
||||
if (boundary[0][0] == 2) boxlo[0] = -all[0][0] - SMALL;
|
||||
else if (boundary[0][0] == 3) boxlo[0] = MIN(-all[0][0]-SMALL,minxlo);
|
||||
if (boundary[0][1] == 2) boxhi[0] = all[0][1] + SMALL;
|
||||
else if (boundary[0][1] == 3) boxhi[0] = MAX(all[0][1]+SMALL,minxhi);
|
||||
if (boundary[0][0] == 2) boxlo[0] = -all[0][0] - small[0];
|
||||
else if (boundary[0][0] == 3)
|
||||
boxlo[0] = MIN(-all[0][0]-small[0],minxlo);
|
||||
if (boundary[0][1] == 2) boxhi[0] = all[0][1] + small[0];
|
||||
else if (boundary[0][1] == 3) boxhi[0] = MAX(all[0][1]+small[0],minxhi);
|
||||
if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box");
|
||||
}
|
||||
if (yperiodic == 0) {
|
||||
if (boundary[1][0] == 2) boxlo[1] = -all[1][0] - SMALL;
|
||||
else if (boundary[1][0] == 3) boxlo[1] = MIN(-all[1][0]-SMALL,minylo);
|
||||
if (boundary[1][1] == 2) boxhi[1] = all[1][1] + SMALL;
|
||||
else if (boundary[1][1] == 3) boxhi[1] = MAX(all[1][1]+SMALL,minyhi);
|
||||
if (boundary[1][0] == 2) boxlo[1] = -all[1][0] - small[1];
|
||||
else if (boundary[1][0] == 3)
|
||||
boxlo[1] = MIN(-all[1][0]-small[1],minylo);
|
||||
if (boundary[1][1] == 2) boxhi[1] = all[1][1] + small[1];
|
||||
else if (boundary[1][1] == 3) boxhi[1] = MAX(all[1][1]+small[1],minyhi);
|
||||
if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box");
|
||||
}
|
||||
if (zperiodic == 0) {
|
||||
if (boundary[2][0] == 2) boxlo[2] = -all[2][0] - SMALL;
|
||||
else if (boundary[2][0] == 3) boxlo[2] = MIN(-all[2][0]-SMALL,minzlo);
|
||||
if (boundary[2][1] == 2) boxhi[2] = all[2][1] + SMALL;
|
||||
else if (boundary[2][1] == 3) boxhi[2] = MAX(all[2][1]+SMALL,minzhi);
|
||||
if (boundary[2][0] == 2) boxlo[2] = -all[2][0] - small[2];
|
||||
else if (boundary[2][0] == 3)
|
||||
boxlo[2] = MIN(-all[2][0]-small[2],minzlo);
|
||||
if (boundary[2][1] == 2) boxhi[2] = all[2][1] + small[2];
|
||||
else if (boundary[2][1] == 3) boxhi[2] = MAX(all[2][1]+small[2],minzhi);
|
||||
if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box");
|
||||
}
|
||||
|
||||
} else {
|
||||
double lo[3],hi[3];
|
||||
if (xperiodic == 0) {
|
||||
lo[0] = -all[0][0]; lo[1] = 0.0; lo[2] = 0.0;
|
||||
lamda2x(lo,lo);
|
||||
hi[0] = all[0][1]; hi[1] = 0.0; hi[2] = 0.0;
|
||||
lamda2x(hi,hi);
|
||||
if (boundary[0][0] == 2) boxlo[0] = lo[0] - small[0];
|
||||
else if (boundary[0][0] == 3) boxlo[0] = MIN(lo[0]-small[0],minxlo);
|
||||
if (boundary[0][1] == 2) boxhi[0] = hi[0] + small[0];
|
||||
else if (boundary[0][1] == 3) boxhi[0] = MAX(hi[0]+small[0],minxhi);
|
||||
if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box");
|
||||
}
|
||||
if (yperiodic == 0) {
|
||||
lo[0] = 0.0; lo[1] = -all[1][0]; lo[2] = 0.0;
|
||||
lamda2x(lo,lo);
|
||||
hi[0] = 0.0; hi[1] = all[1][1]; hi[2] = 0.0;
|
||||
lamda2x(hi,hi);
|
||||
if (boundary[1][0] == 2) boxlo[1] = lo[1] - small[1];
|
||||
else if (boundary[1][0] == 3) boxlo[1] = MIN(lo[1]-small[1],minylo);
|
||||
if (boundary[1][1] == 2) boxhi[1] = hi[1] + small[1];
|
||||
else if (boundary[1][1] == 3) boxhi[1] = MAX(hi[1]+small[1],minyhi);
|
||||
if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box");
|
||||
//xy *= (boxhi[1]-boxlo[1]) / yprd;
|
||||
}
|
||||
if (zperiodic == 0) {
|
||||
lo[0] = 0.0; lo[1] = 0.0; lo[2] = -all[2][0];
|
||||
lamda2x(lo,lo);
|
||||
hi[0] = 0.0; hi[1] = 0.0; hi[2] = all[2][1];
|
||||
lamda2x(hi,hi);
|
||||
if (boundary[2][0] == 2) boxlo[2] = lo[2] - small[2];
|
||||
else if (boundary[2][0] == 3) boxlo[2] = MIN(lo[2]-small[2],minzlo);
|
||||
if (boundary[2][1] == 2) boxhi[2] = hi[2] + small[2];
|
||||
else if (boundary[2][1] == 3) boxhi[2] = MAX(hi[2]+small[2],minzhi);
|
||||
if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box");
|
||||
//xz *= (boxhi[2]-boxlo[2]) / xprd;
|
||||
//yz *= (boxhi[2]-boxlo[2]) / yprd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset box whether shrink-wrapping or not
|
||||
|
||||
set_global_box();
|
||||
set_local_box();
|
||||
|
||||
// if shrink-wrapped, convert to lamda coords for new box
|
||||
// must re-invoke pbc() b/c x2lamda result can be outside 0,1 due to roundoff
|
||||
// if shrink-wrapped & triclinic, re-convert to lamda coords for new box
|
||||
// re-invoke pbc() b/c x2lamda result can be outside [0,1] due to roundoff
|
||||
|
||||
if (nonperiodic == 2 && triclinic) {
|
||||
x2lamda(atom->nlocal);
|
||||
|
||||
@ -101,7 +101,8 @@ class Domain : protected Pointers {
|
||||
int minimum_image_check(double, double, double);
|
||||
void minimum_image(double &, double &, double &);
|
||||
void minimum_image(double *);
|
||||
void closest_image(const double * const, const double * const, double * const);
|
||||
void closest_image(const double * const, const double * const,
|
||||
double * const);
|
||||
void set_lattice(int, char **);
|
||||
void add_region(int, char **);
|
||||
void delete_region(int, char **);
|
||||
@ -115,6 +116,9 @@ class Domain : protected Pointers {
|
||||
void x2lamda(double *, double *);
|
||||
void bbox(double *, double *, double *, double *);
|
||||
void box_corners();
|
||||
|
||||
private:
|
||||
double small[3]; // fractions of box lengths
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -50,6 +50,11 @@ void Finish::end(int flag)
|
||||
MPI_Comm_rank(world,&me);
|
||||
MPI_Comm_size(world,&nprocs);
|
||||
|
||||
// recompute natoms in case atoms have been lost
|
||||
|
||||
bigint nblocal = atom->nlocal;
|
||||
MPI_Allreduce(&nblocal,&atom->nlocal,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
|
||||
// choose flavors of statistical output
|
||||
// flag determines caller
|
||||
// flag = 0 = just loop summary
|
||||
@ -591,7 +596,8 @@ void Finish::end(int flag)
|
||||
double nspec_all;
|
||||
if (atom->molecular) {
|
||||
nspec = 0;
|
||||
for (i = 0; i < atom->nlocal; i++) nspec += atom->nspecial[i][2];
|
||||
int nlocal = atom->nlocal;
|
||||
for (i = 0; i < nlocal; i++) nspec += atom->nspecial[i][2];
|
||||
tmp = nspec;
|
||||
MPI_Allreduce(&tmp,&nspec_all,1,MPI_DOUBLE,MPI_SUM,world);
|
||||
}
|
||||
|
||||
@ -198,18 +198,26 @@ FixBoxRelax::FixBoxRelax(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0))
|
||||
error->all(FLERR,"Invalid fix box/relax command pressure settings");
|
||||
|
||||
// require periodicity in tensile dimension
|
||||
|
||||
if (p_flag[0] && domain->xperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension");
|
||||
if (p_flag[1] && domain->yperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension");
|
||||
if (p_flag[2] && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix box/relax on a non-periodic dimension");
|
||||
|
||||
// require periodicity in 2nd dim of off-diagonal tilt component
|
||||
|
||||
if (p_flag[3] && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix box/relax on a 2nd non-periodic dimension");
|
||||
error->all(FLERR,
|
||||
"Cannot use fix box/relax on a 2nd non-periodic dimension");
|
||||
if (p_flag[4] && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix box/relax on a 2nd non-periodic dimension");
|
||||
error->all(FLERR,
|
||||
"Cannot use fix box/relax on a 2nd non-periodic dimension");
|
||||
if (p_flag[5] && domain->yperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix box/relax on a 2nd non-periodic dimension");
|
||||
error->all(FLERR,
|
||||
"Cannot use fix box/relax on a 2nd non-periodic dimension");
|
||||
|
||||
if (!domain->triclinic && (p_flag[3] || p_flag[4] || p_flag[5]))
|
||||
error->all(FLERR,"Can not specify Pxy/Pxz/Pyz in "
|
||||
@ -689,18 +697,21 @@ int FixBoxRelax::modify_param(int narg, char **arg)
|
||||
strcpy(id_temp,arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(arg[1]);
|
||||
if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
temperature = modify->compute[icompute];
|
||||
|
||||
if (temperature->tempflag == 0)
|
||||
error->all(FLERR,"Fix_modify temperature ID does not compute temperature");
|
||||
error->all(FLERR,
|
||||
"Fix_modify temperature ID does not compute temperature");
|
||||
if (temperature->igroup != 0 && comm->me == 0)
|
||||
error->warning(FLERR,"Temperature for fix modify is not for group all");
|
||||
|
||||
// reset id_temp of pressure to new temperature ID
|
||||
|
||||
icompute = modify->find_compute(id_press);
|
||||
if (icompute < 0) error->all(FLERR,"Pressure ID for fix modify does not exist");
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Pressure ID for fix modify does not exist");
|
||||
modify->compute[icompute]->reset_extra_compute_fix(id_temp);
|
||||
|
||||
return 2;
|
||||
|
||||
@ -223,19 +223,31 @@ FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
|
||||
if (dimflag[0] || dimflag[1] || dimflag[2]) box_change_size = 1;
|
||||
if (dimflag[3] || dimflag[4] || dimflag[5]) box_change_shape = 1;
|
||||
|
||||
// check periodicity
|
||||
// no tensile deformation on shrink-wrapped dims
|
||||
// b/c shrink wrap will change box-length
|
||||
|
||||
if ((set[0].style && domain->xperiodic == 0) ||
|
||||
(set[1].style && domain->yperiodic == 0) ||
|
||||
(set[2].style && domain->zperiodic == 0))
|
||||
error->all(FLERR,"Cannot use fix deform on a non-periodic boundary");
|
||||
if (set[0].style &&
|
||||
(domain->boundary[0][0] >= 2 || domain->boundary[0][1] >= 2))
|
||||
error->all(FLERR,"Cannot use fix deform on a shrink-wrapped boundary");
|
||||
if (set[1].style &&
|
||||
(domain->boundary[1][0] >= 2 || domain->boundary[1][1] >= 2))
|
||||
error->all(FLERR,"Cannot use fix deform on a shrink-wrapped boundary");
|
||||
if (set[2].style &&
|
||||
(domain->boundary[2][0] >= 2 || domain->boundary[2][1] >= 2))
|
||||
error->all(FLERR,"Cannot use fix deform on a shrink-wrapped boundary");
|
||||
|
||||
if (set[3].style && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix deform on a 2nd non-periodic boundary");
|
||||
if (set[4].style && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix deform on a 2nd non-periodic boundary");
|
||||
if (set[5].style && domain->yperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix deform on a 2nd non-periodic boundary");
|
||||
// no tilt deformation on shrink-wrapped 2nd dim
|
||||
// b/c shrink wrap will change tilt factor in domain::reset_box()
|
||||
|
||||
if (set[3].style &&
|
||||
(domain->boundary[2][0] >= 2 || domain->boundary[2][1] >= 2))
|
||||
error->all(FLERR,"Cannot use fix deform tilt on a shrink-wrapped 2nd dim");
|
||||
if (set[4].style &&
|
||||
(domain->boundary[2][0] >= 2 || domain->boundary[2][1] >= 2))
|
||||
error->all(FLERR,"Cannot use fix deform tilt on a shrink-wrapped 2nd dim");
|
||||
if (set[4].style &&
|
||||
(domain->boundary[1][0] >= 2 || domain->boundary[1][1] >= 2))
|
||||
error->all(FLERR,"Cannot use fix deform tilt on a shrink-wrapped 2nd dim");
|
||||
|
||||
// apply scaling to FINAL,DELTA,VEL,WIGGLE since they have dist/vel units
|
||||
|
||||
@ -563,11 +575,11 @@ void FixDeform::init()
|
||||
lo = set[3].tilt_min;
|
||||
hi = set[3].tilt_max;
|
||||
} else lo = hi = set[3].tilt_stop;
|
||||
if (lo < -0.5*(set[1].hi_start-set[1].lo_start) ||
|
||||
hi > 0.5*(set[1].hi_start-set[1].lo_start)) flag = 1;
|
||||
if (lo/(set[1].hi_start-set[1].lo_start) < -0.5 ||
|
||||
hi/(set[1].hi_start-set[1].lo_start) > 0.5) flag = 1;
|
||||
if (set[1].style) {
|
||||
if (lo < -0.5*(set[1].hi_stop-set[1].lo_stop) ||
|
||||
hi > 0.5*(set[1].hi_stop-set[1].lo_stop)) flag = 1;
|
||||
if (lo/(set[1].hi_stop-set[1].lo_stop) < -0.5 ||
|
||||
hi/(set[1].hi_stop-set[1].lo_stop) > 0.5) flag = 1;
|
||||
}
|
||||
if (flag) error->all(FLERR,"Fix deform is changing yz too much with xy");
|
||||
}
|
||||
@ -623,6 +635,8 @@ void FixDeform::init()
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
box flipped on previous step
|
||||
do not allow box flip in a non-periodic dimension (can tilt but not flip)
|
||||
this is b/c the box length will be changed (dramatically) by flip
|
||||
perform irregular comm to migrate atoms to new procs
|
||||
reset box tilts for flipped config and create new box in domain
|
||||
remap to put far-away atoms back into new box
|
||||
@ -666,14 +680,17 @@ void FixDeform::end_of_step()
|
||||
if (varflag) modify->clearstep_compute();
|
||||
|
||||
// set new box size
|
||||
// for NONE, target is current box size
|
||||
// for TRATE, set target directly based on current time, also set h_rate
|
||||
// for WIGGLE, set target directly based on current time, also set h_rate
|
||||
// for VARIABLE, set target directly via variable eval, also set h_rate
|
||||
// for NONE, target is current box size
|
||||
// for others except VOLUME, target is linear value between start and stop
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (set[i].style == TRATE) {
|
||||
if (set[i].style == NONE) {
|
||||
set[i].lo_target = domain->boxlo[i];
|
||||
set[i].hi_target = domain->boxhi[i];
|
||||
} else if (set[i].style == TRATE) {
|
||||
double delt = (update->ntimestep - update->beginstep) * update->dt;
|
||||
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
|
||||
0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt));
|
||||
@ -696,9 +713,6 @@ void FixDeform::end_of_step()
|
||||
set[i].hi_target = set[i].hi_start + 0.5*del;
|
||||
h_rate[i] = input->variable->compute_equal(set[i].hratevar);
|
||||
h_ratelo[i] = -0.5*h_rate[i];
|
||||
} else if (set[i].style == NONE) {
|
||||
set[i].lo_target = domain->boxlo[i];
|
||||
set[i].hi_target = domain->boxhi[i];
|
||||
} else if (set[i].style != VOLUME) {
|
||||
set[i].lo_target = set[i].lo_start +
|
||||
delta*(set[i].lo_stop - set[i].lo_start);
|
||||
@ -758,17 +772,21 @@ void FixDeform::end_of_step()
|
||||
}
|
||||
|
||||
// for triclinic, set new box shape
|
||||
// for NONE, target is current tilt
|
||||
// for TRATE, set target directly based on current time. also set h_rate
|
||||
// for WIGGLE, set target directly based on current time. also set h_rate
|
||||
// for VARIABLE, set target directly via variable eval. also set h_rate
|
||||
// for NONE, target is current tilt
|
||||
// for other styles, target is linear value between start and stop values
|
||||
|
||||
if (triclinic) {
|
||||
double *h = domain->h;
|
||||
|
||||
for (i = 3; i < 6; i++) {
|
||||
if (set[i].style == TRATE) {
|
||||
if (set[i].style == NONE) {
|
||||
if (i == 5) set[i].tilt_target = domain->xy;
|
||||
else if (i == 4) set[i].tilt_target = domain->xz;
|
||||
else if (i == 3) set[i].tilt_target = domain->yz;
|
||||
} else if (set[i].style == TRATE) {
|
||||
double delt = (update->ntimestep - update->beginstep) * update->dt;
|
||||
set[i].tilt_target = set[i].tilt_start * exp(set[i].rate*delt);
|
||||
h_rate[i] = set[i].rate * domain->h[i];
|
||||
@ -782,10 +800,6 @@ void FixDeform::end_of_step()
|
||||
double delta_tilt = input->variable->compute_equal(set[i].hvar);
|
||||
set[i].tilt_target = set[i].tilt_start + delta_tilt;
|
||||
h_rate[i] = input->variable->compute_equal(set[i].hratevar);
|
||||
} else if (set[i].style == NONE) {
|
||||
if (i == 5) set[i].tilt_target = domain->xy;
|
||||
else if (i == 4) set[i].tilt_target = domain->xz;
|
||||
else if (i == 3) set[i].tilt_target = domain->yz;
|
||||
} else {
|
||||
set[i].tilt_target = set[i].tilt_start +
|
||||
delta*(set[i].tilt_stop - set[i].tilt_start);
|
||||
@ -801,6 +815,7 @@ void FixDeform::end_of_step()
|
||||
double denom = set[idenom].hi_target - set[idenom].lo_target;
|
||||
|
||||
double current = h[i]/h[idenom];
|
||||
|
||||
while (set[i].tilt_target/denom - current > 0.0)
|
||||
set[i].tilt_target -= denom;
|
||||
while (set[i].tilt_target/denom - current < 0.0)
|
||||
@ -813,36 +828,59 @@ void FixDeform::end_of_step()
|
||||
|
||||
if (varflag) modify->addstep_compute(update->ntimestep + nevery);
|
||||
|
||||
// if any tilt targets exceed bounds, set flip flag and new tilt_flip values
|
||||
// flip will be performed on next timestep before reneighboring
|
||||
// if any tilt ratios exceed 0.5, set flip = 1 & compute new tilt_flip values
|
||||
// do not flip in x or y if non-periodic
|
||||
// when yz flips and xy is non-zero, xz must also change
|
||||
// this is to keep the edge vectors of the flipped shape matrix
|
||||
// an integer combination of the edge vectors of the unflipped shape matrix
|
||||
// flip is performed on next timestep before reneighboring
|
||||
|
||||
if (triclinic) {
|
||||
double xprd = set[0].hi_target - set[0].lo_target;
|
||||
double yprd = set[1].hi_target - set[1].lo_target;
|
||||
if (set[3].tilt_target < -0.5*yprd || set[3].tilt_target > 0.5*yprd ||
|
||||
set[4].tilt_target < -0.5*xprd || set[4].tilt_target > 0.5*xprd ||
|
||||
set[5].tilt_target < -0.5*xprd || set[5].tilt_target > 0.5*xprd) {
|
||||
|
||||
flip = 1;
|
||||
next_reneighbor = update->ntimestep + 1;
|
||||
double xprdinv = 1.0 / xprd;
|
||||
double yprdinv = 1.0 / yprd;
|
||||
if (set[3].tilt_target*yprdinv < -0.5 ||
|
||||
set[3].tilt_target*yprdinv > 0.5 ||
|
||||
set[4].tilt_target*xprdinv < -0.5 ||
|
||||
set[4].tilt_target*xprdinv > 0.5 ||
|
||||
set[5].tilt_target*xprdinv < -0.5 ||
|
||||
set[5].tilt_target*xprdinv > 0.5) {
|
||||
set[3].tilt_flip = set[3].tilt_target;
|
||||
set[4].tilt_flip = set[4].tilt_target;
|
||||
set[5].tilt_flip = set[5].tilt_target;
|
||||
|
||||
if (set[3].tilt_flip < -0.5*yprd) {
|
||||
if (domain->yperiodic) {
|
||||
if (set[3].tilt_flip*yprdinv < -0.5) {
|
||||
set[3].tilt_flip += yprd;
|
||||
set[4].tilt_flip += set[5].tilt_flip;
|
||||
} else if (set[3].tilt_flip >= 0.5*yprd) {
|
||||
flip = 1;
|
||||
} else if (set[3].tilt_flip*yprdinv > 0.5) {
|
||||
set[3].tilt_flip -= yprd;
|
||||
set[4].tilt_flip -= set[5].tilt_flip;
|
||||
flipy = 1;
|
||||
}
|
||||
if (set[4].tilt_flip < -0.5*xprd) set[4].tilt_flip += xprd;
|
||||
if (set[4].tilt_flip > 0.5*xprd) set[4].tilt_flip -= xprd;
|
||||
if (set[5].tilt_flip < -0.5*xprd) set[5].tilt_flip += xprd;
|
||||
if (set[5].tilt_flip > 0.5*xprd) set[5].tilt_flip -= xprd;
|
||||
}
|
||||
if (domain->xperiodic) {
|
||||
if (set[4].tilt_flip*xprdinv < -0.5) {
|
||||
set[4].tilt_flip += xprd;
|
||||
flip = 1;
|
||||
}
|
||||
if (set[4].tilt_flip*xprdinv > 0.5) {
|
||||
set[4].tilt_flip -= xprd;
|
||||
flip = 1;
|
||||
}
|
||||
if (set[5].tilt_flip*xprdinv < -0.5) {
|
||||
set[5].tilt_flip += xprd;
|
||||
flip = 1;
|
||||
}
|
||||
if (set[5].tilt_flip*xprdinv > 0.5) {
|
||||
set[5].tilt_flip -= xprd;
|
||||
flip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (flip) next_reneighbor = update->ntimestep + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,8 @@ class FixDeform : public Fix {
|
||||
void end_of_step();
|
||||
|
||||
private:
|
||||
int triclinic,scaleflag,flip;
|
||||
int triclinic,scaleflag;
|
||||
int flip,flipx,flipy;
|
||||
double *h_rate,*h_ratelo;
|
||||
int varflag; // 1 if VARIABLE option is used, 0 if not
|
||||
int kspace_flag; // 1 if KSpace invoked, 0 if not
|
||||
|
||||
@ -312,18 +312,26 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
|
||||
if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0))
|
||||
error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings");
|
||||
|
||||
// require periodicity in tensile dimension
|
||||
|
||||
if (p_flag[0] && domain->xperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension");
|
||||
if (p_flag[1] && domain->yperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension");
|
||||
if (p_flag[2] && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension");
|
||||
|
||||
// require periodicity in 2nd dim of off-diagonal tilt component
|
||||
|
||||
if (p_flag[3] && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
|
||||
error->all(FLERR,
|
||||
"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
|
||||
if (p_flag[4] && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
|
||||
error->all(FLERR,
|
||||
"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
|
||||
if (p_flag[5] && domain->yperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
|
||||
error->all(FLERR,
|
||||
"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
|
||||
|
||||
if (scaleyz == 1 && domain->zperiodic == 0)
|
||||
error->all(FLERR,"Cannot use fix nvt/npt/nph "
|
||||
@ -2120,11 +2128,12 @@ void FixNH::nh_omega_dot()
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
if box tilt exceeds limits,
|
||||
create new box in domain
|
||||
remap to put far-away atoms back into new box
|
||||
if any tilt ratios exceed 0.5, set flip = 1 & compute new tilt_flip values
|
||||
do not flip in x or y if non-periodic
|
||||
when yz flips and xy is non-zero, xz must also change
|
||||
this is to keep the edge vectors of the flipped shape matrix
|
||||
an integer combination of the edge vectors of the unflipped shape matrix
|
||||
perform irregular on atoms in lamda coords to get atoms to new procs
|
||||
force reneighboring on next timestep
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixNH::pre_exchange()
|
||||
@ -2132,14 +2141,15 @@ void FixNH::pre_exchange()
|
||||
double xprd = domain->xprd;
|
||||
double yprd = domain->yprd;
|
||||
|
||||
// flip is triggered when tilt exceeds 0.5 by
|
||||
// an amount DELTAFLIP that is somewhat arbitrary
|
||||
// flip is triggered when tilt exceeds 0.5 by an amount DELTAFLIP
|
||||
// this avoids immediate re-flipping due to tilt oscillations
|
||||
|
||||
double xtiltmax = (0.5+DELTAFLIP)*xprd;
|
||||
double ytiltmax = (0.5+DELTAFLIP)*yprd;
|
||||
|
||||
int flip = 0;
|
||||
|
||||
if (domain->yperiodic) {
|
||||
if (domain->yz < -ytiltmax) {
|
||||
flip = 1;
|
||||
domain->yz += yprd;
|
||||
@ -2149,7 +2159,9 @@ void FixNH::pre_exchange()
|
||||
domain->yz -= yprd;
|
||||
domain->xz -= domain->xy;
|
||||
}
|
||||
}
|
||||
|
||||
if (domain->xperiodic) {
|
||||
if (domain->xz < -xtiltmax) {
|
||||
flip = 1;
|
||||
domain->xz += xprd;
|
||||
@ -2157,7 +2169,6 @@ void FixNH::pre_exchange()
|
||||
flip = 1;
|
||||
domain->xz -= xprd;
|
||||
}
|
||||
|
||||
if (domain->xy < -xtiltmax) {
|
||||
flip = 1;
|
||||
domain->xy += xprd;
|
||||
@ -2165,6 +2176,7 @@ void FixNH::pre_exchange()
|
||||
flip = 1;
|
||||
domain->xy -= xprd;
|
||||
}
|
||||
}
|
||||
|
||||
if (flip) {
|
||||
domain->set_global_box();
|
||||
@ -2180,4 +2192,3 @@ void FixNH::pre_exchange()
|
||||
domain->lamda2x(atom->nlocal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user