2006-09-28 03:51:33 +08:00
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
|
|
|
www.cs.sandia.gov/~sjplimp/lammps.html
|
|
|
|
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
|
|
|
|
|
|
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
|
|
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
|
|
|
certain rights in this software. This software is distributed under
|
|
|
|
the GNU General Public License.
|
|
|
|
|
|
|
|
See the README file in the top-level LAMMPS directory.
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
#include "mpi.h"
|
|
|
|
#include "stdlib.h"
|
|
|
|
#include "string.h"
|
|
|
|
#include "stdio.h"
|
|
|
|
#include "math.h"
|
|
|
|
#include "domain.h"
|
|
|
|
#include "atom.h"
|
|
|
|
#include "force.h"
|
|
|
|
#include "update.h"
|
|
|
|
#include "modify.h"
|
|
|
|
#include "fix.h"
|
|
|
|
#include "region.h"
|
2006-11-14 06:17:52 +08:00
|
|
|
#include "lattice.h"
|
2006-09-28 03:51:33 +08:00
|
|
|
#include "comm.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "error.h"
|
|
|
|
|
|
|
|
#define RegionInclude
|
|
|
|
#include "style.h"
|
|
|
|
#undef RegionInclude
|
|
|
|
|
|
|
|
#define BIG 1.0e20
|
|
|
|
#define SMALL 1.0e-4
|
|
|
|
#define DELTA 1
|
|
|
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
|
|
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
default is periodic
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
Domain::Domain()
|
|
|
|
{
|
|
|
|
box_exist = 0;
|
|
|
|
|
|
|
|
nonperiodic = 0;
|
|
|
|
xperiodic = yperiodic = zperiodic = 1;
|
2006-11-14 06:17:52 +08:00
|
|
|
periodicity[0] = xperiodic;
|
|
|
|
periodicity[1] = yperiodic;
|
|
|
|
periodicity[2] = zperiodic;
|
|
|
|
|
2006-09-28 03:51:33 +08:00
|
|
|
boundary[0][0] = boundary[0][1] = 0;
|
|
|
|
boundary[1][0] = boundary[1][1] = 0;
|
|
|
|
boundary[2][0] = boundary[2][1] = 0;
|
|
|
|
|
|
|
|
boxxlo = boxylo = boxzlo = -0.5;
|
|
|
|
boxxhi = boxyhi = boxzhi = 0.5;
|
|
|
|
|
2006-11-14 06:17:52 +08:00
|
|
|
lattice = NULL;
|
2006-09-28 03:51:33 +08:00
|
|
|
nregion = maxregion = 0;
|
|
|
|
regions = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
Domain::~Domain()
|
|
|
|
{
|
2006-11-14 06:17:52 +08:00
|
|
|
delete lattice;
|
2006-09-28 03:51:33 +08:00
|
|
|
for (int i = 0; i < nregion; i++) delete regions[i];
|
|
|
|
memory->sfree(regions);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::init()
|
|
|
|
{
|
|
|
|
// set box_change if box dimensions ever change
|
|
|
|
// due to shrink-wrapping, fix nph, npt, volume/rescale, uniaxial
|
|
|
|
|
|
|
|
box_change = 0;
|
|
|
|
if (nonperiodic == 2) box_change = 1;
|
|
|
|
for (int i = 0; i < modify->nfix; i++) {
|
|
|
|
if (strcmp(modify->fix[i]->style,"nph") == 0) box_change = 1;
|
|
|
|
if (strcmp(modify->fix[i]->style,"npt") == 0) box_change = 1;
|
|
|
|
if (strcmp(modify->fix[i]->style,"volume/rescale") == 0) box_change = 1;
|
|
|
|
if (strcmp(modify->fix[i]->style,"uniaxial") == 0) box_change = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
2006-11-14 06:17:52 +08:00
|
|
|
set initial global box from boxlo/hi (already set by caller)
|
|
|
|
adjust for shrink-wrapped dims
|
2006-09-28 03:51:33 +08:00
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::set_initial_box()
|
|
|
|
{
|
|
|
|
if (boundary[0][0] == 2) boxxlo -= SMALL;
|
|
|
|
else if (boundary[0][0] == 3) minxlo = boxxlo;
|
|
|
|
if (boundary[0][1] == 2) boxxhi += SMALL;
|
|
|
|
else if (boundary[0][1] == 3) minxhi = boxxhi;
|
|
|
|
|
|
|
|
if (boundary[1][0] == 2) boxylo -= SMALL;
|
|
|
|
else if (boundary[1][0] == 3) minylo = boxylo;
|
|
|
|
if (boundary[1][1] == 2) boxyhi += SMALL;
|
|
|
|
else if (boundary[1][1] == 3) minyhi = boxyhi;
|
|
|
|
|
|
|
|
if (boundary[2][0] == 2) boxzlo -= SMALL;
|
|
|
|
else if (boundary[2][0] == 3) minzlo = boxzlo;
|
|
|
|
if (boundary[2][1] == 2) boxzhi += SMALL;
|
|
|
|
else if (boundary[2][1] == 3) minzhi = boxzhi;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
2006-11-14 06:17:52 +08:00
|
|
|
set global prd, prd_half, prd[], boxlo/hi[] from boxlo/hi
|
2006-09-28 03:51:33 +08:00
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::set_global_box()
|
|
|
|
{
|
|
|
|
xprd = boxxhi - boxxlo;
|
|
|
|
yprd = boxyhi - boxylo;
|
|
|
|
zprd = boxzhi - boxzlo;
|
|
|
|
|
|
|
|
xprd_half = 0.5*xprd;
|
|
|
|
yprd_half = 0.5*yprd;
|
|
|
|
zprd_half = 0.5*zprd;
|
|
|
|
|
|
|
|
prd[0] = xprd; prd[1] = yprd; prd[2] = zprd;
|
|
|
|
boxlo[0] = boxxlo; boxlo[1] = boxylo; boxlo[2] = boxzlo;
|
|
|
|
boxhi[0] = boxxhi; boxhi[1] = boxyhi; boxhi[2] = boxzhi;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
2006-11-14 06:17:52 +08:00
|
|
|
set local subxlo-subzhi, sublo/hi[] from global boxxlo-boxzhi and proc grid
|
2006-09-28 03:51:33 +08:00
|
|
|
for uppermost proc, insure subhi = boxhi (in case round-off occurs)
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::set_local_box()
|
|
|
|
{
|
|
|
|
subxlo = boxxlo + comm->myloc[0] * xprd / comm->procgrid[0];
|
|
|
|
if (comm->myloc[0] < comm->procgrid[0]-1)
|
|
|
|
subxhi = boxxlo + (comm->myloc[0]+1) * xprd / comm->procgrid[0];
|
|
|
|
else subxhi = boxxhi;
|
|
|
|
|
|
|
|
subylo = boxylo + comm->myloc[1] * yprd / comm->procgrid[1];
|
|
|
|
if (comm->myloc[1] < comm->procgrid[1]-1)
|
|
|
|
subyhi = boxylo + (comm->myloc[1]+1) * yprd / comm->procgrid[1];
|
|
|
|
else subyhi = boxyhi;
|
|
|
|
|
|
|
|
subzlo = boxzlo + comm->myloc[2] * zprd / comm->procgrid[2];
|
|
|
|
if (comm->myloc[2] < comm->procgrid[2]-1)
|
|
|
|
subzhi = boxzlo + (comm->myloc[2]+1) * zprd / comm->procgrid[2];
|
|
|
|
else subzhi = boxzhi;
|
|
|
|
|
|
|
|
sublo[0] = subxlo; sublo[1] = subylo; sublo[2] = subzlo;
|
|
|
|
subhi[0] = subxhi; subhi[1] = subyhi; subhi[2] = subzhi;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
reset global & local boxes due to global box boundary changes
|
2006-11-14 06:17:52 +08:00
|
|
|
if shrink-wrapped, determine atom extent and reset boxlo/hi
|
|
|
|
set global & local boxes from new boxlo/hi values
|
2006-09-28 03:51:33 +08:00
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::reset_box()
|
|
|
|
{
|
|
|
|
if (nonperiodic == 2) {
|
|
|
|
|
|
|
|
// compute extent of atoms on this proc
|
|
|
|
|
|
|
|
double extent[3][2],all[3][2];
|
|
|
|
|
|
|
|
extent[2][0] = extent[1][0] = extent[0][0] = BIG;
|
|
|
|
extent[2][1] = extent[1][1] = extent[0][1] = -BIG;
|
|
|
|
|
|
|
|
double **x = atom->x;
|
|
|
|
int nlocal = atom->nlocal;
|
|
|
|
|
|
|
|
for (int i = 0; i < nlocal; i++) {
|
|
|
|
extent[0][0] = MIN(extent[0][0],x[i][0]);
|
|
|
|
extent[0][1] = MAX(extent[0][1],x[i][0]);
|
|
|
|
extent[1][0] = MIN(extent[1][0],x[i][1]);
|
|
|
|
extent[1][1] = MAX(extent[1][1],x[i][1]);
|
|
|
|
extent[2][0] = MIN(extent[2][0],x[i][2]);
|
|
|
|
extent[2][1] = MAX(extent[2][1],x[i][2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// compute extent across all procs
|
|
|
|
// flip sign of MIN to do it in one Allreduce MAX
|
|
|
|
|
|
|
|
extent[0][0] = -extent[0][0];
|
|
|
|
extent[1][0] = -extent[1][0];
|
|
|
|
extent[2][0] = -extent[2][0];
|
|
|
|
|
|
|
|
MPI_Allreduce(extent,all,6,MPI_DOUBLE,MPI_MAX,world);
|
|
|
|
|
2006-11-14 06:17:52 +08:00
|
|
|
// in shrink-wrapped dims, set box by atom extent
|
2006-09-28 03:51:33 +08:00
|
|
|
|
|
|
|
if (xperiodic == 0) {
|
|
|
|
if (boundary[0][0] == 2) boxxlo = -all[0][0] - SMALL;
|
|
|
|
else if (boundary[0][0] == 3) boxxlo = MIN(-all[0][0]-SMALL,minxlo);
|
|
|
|
if (boundary[0][1] == 2) boxxhi = all[0][1] + SMALL;
|
|
|
|
else if (boundary[0][1] == 3) boxxhi = MAX(all[0][1]+SMALL,minxhi);
|
2006-12-11 23:32:21 +08:00
|
|
|
if (boxxlo > boxxhi) error->all("Illegal simulation box");
|
2006-09-28 03:51:33 +08:00
|
|
|
}
|
|
|
|
if (yperiodic == 0) {
|
|
|
|
if (boundary[1][0] == 2) boxylo = -all[1][0] - SMALL;
|
|
|
|
else if (boundary[1][0] == 3) boxylo = MIN(-all[1][0]-SMALL,minylo);
|
|
|
|
if (boundary[1][1] == 2) boxyhi = all[1][1] + SMALL;
|
|
|
|
else if (boundary[1][1] == 3) boxyhi = MAX(all[1][1]+SMALL,minyhi);
|
2006-12-11 23:32:21 +08:00
|
|
|
if (boxylo > boxyhi) error->all("Illegal simulation box");
|
2006-09-28 03:51:33 +08:00
|
|
|
}
|
|
|
|
if (zperiodic == 0) {
|
|
|
|
if (boundary[2][0] == 2) boxzlo = -all[2][0] - SMALL;
|
|
|
|
else if (boundary[2][0] == 3) boxzlo = MIN(-all[2][0]-SMALL,minzlo);
|
|
|
|
if (boundary[2][1] == 2) boxzhi = all[2][1] + SMALL;
|
|
|
|
else if (boundary[2][1] == 3) boxzhi = MAX(all[2][1]+SMALL,minzhi);
|
2006-12-11 23:32:21 +08:00
|
|
|
if (boxzlo > boxzhi) error->all("Illegal simulation box");
|
2006-09-28 03:51:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
set_global_box();
|
|
|
|
set_local_box();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
enforce PBC and modify box image flags for each atom
|
|
|
|
called every reneighboring
|
|
|
|
resulting coord must satisfy lo <= coord < hi
|
|
|
|
MAX is important since coord - prd < lo can happen when coord = hi
|
|
|
|
image = 10 bits for each dimension
|
|
|
|
increment/decrement in wrap-around fashion
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::pbc()
|
|
|
|
{
|
|
|
|
int i,idim,otherdims;
|
|
|
|
int nlocal = atom->nlocal;
|
|
|
|
double **x = atom->x;
|
|
|
|
int *image = atom->image;
|
|
|
|
|
|
|
|
if (xperiodic) {
|
|
|
|
for (i = 0; i < nlocal; i++) {
|
|
|
|
if (x[i][0] < boxxlo) {
|
|
|
|
x[i][0] += xprd;
|
|
|
|
idim = image[i] & 1023;
|
|
|
|
otherdims = image[i] ^ idim;
|
|
|
|
idim--;
|
|
|
|
idim &= 1023;
|
|
|
|
image[i] = otherdims | idim;
|
|
|
|
}
|
|
|
|
if (x[i][0] >= boxxhi) {
|
|
|
|
x[i][0] -= xprd;
|
|
|
|
x[i][0] = MAX(x[i][0],boxxlo);
|
|
|
|
idim = image[i] & 1023;
|
|
|
|
otherdims = image[i] ^ idim;
|
|
|
|
idim++;
|
|
|
|
idim &= 1023;
|
|
|
|
image[i] = otherdims | idim;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (yperiodic) {
|
|
|
|
for (i = 0; i < nlocal; i++) {
|
|
|
|
if (x[i][1] < boxylo) {
|
|
|
|
x[i][1] += yprd;
|
|
|
|
idim = (image[i] >> 10) & 1023;
|
|
|
|
otherdims = image[i] ^ (idim << 10);
|
|
|
|
idim--;
|
|
|
|
idim &= 1023;
|
|
|
|
image[i] = otherdims | (idim << 10);
|
|
|
|
}
|
|
|
|
if (x[i][1] >= boxyhi) {
|
|
|
|
x[i][1] -= yprd;
|
|
|
|
x[i][1] = MAX(x[i][1],boxylo);
|
|
|
|
idim = (image[i] >> 10) & 1023;
|
|
|
|
otherdims = image[i] ^ (idim << 10);
|
|
|
|
idim++;
|
|
|
|
idim &= 1023;
|
|
|
|
image[i] = otherdims | (idim << 10);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zperiodic) {
|
|
|
|
for (i = 0; i < nlocal; i++) {
|
|
|
|
if (x[i][2] < boxzlo) {
|
|
|
|
x[i][2] += zprd;
|
|
|
|
idim = image[i] >> 20;
|
|
|
|
otherdims = image[i] ^ (idim << 20);
|
|
|
|
idim--;
|
|
|
|
idim &= 1023;
|
|
|
|
image[i] = otherdims | (idim << 20);
|
|
|
|
}
|
|
|
|
if (x[i][2] >= boxzhi) {
|
|
|
|
x[i][2] -= zprd;
|
|
|
|
x[i][2] = MAX(x[i][2],boxzlo);
|
|
|
|
idim = image[i] >> 20;
|
|
|
|
otherdims = image[i] ^ (idim << 20);
|
|
|
|
idim++;
|
|
|
|
idim &= 1023;
|
|
|
|
image[i] = otherdims | (idim << 20);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
minimum image convention
|
|
|
|
use 1/2 of box size as test
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::minimum_image(double *dx, double *dy, double *dz)
|
|
|
|
{
|
|
|
|
if (xperiodic) {
|
|
|
|
if (fabs(*dx) > xprd_half) {
|
|
|
|
if (*dx < 0.0) *dx += xprd;
|
|
|
|
else *dx -= xprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (yperiodic) {
|
|
|
|
if (fabs(*dy) > yprd_half) {
|
|
|
|
if (*dy < 0.0) *dy += yprd;
|
|
|
|
else *dy -= yprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (zperiodic) {
|
|
|
|
if (fabs(*dz) > zprd_half) {
|
|
|
|
if (*dz < 0.0) *dz += zprd;
|
|
|
|
else *dz -= zprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
minimum image convention
|
|
|
|
use 1/2 of box size as test
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::minimum_image(double *x)
|
|
|
|
{
|
|
|
|
if (xperiodic) {
|
|
|
|
if (fabs(x[0]) > xprd_half) {
|
|
|
|
if (x[0] < 0.0) x[0] += xprd;
|
|
|
|
else x[0] -= xprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (yperiodic) {
|
|
|
|
if (fabs(x[1]) > yprd_half) {
|
|
|
|
if (x[1] < 0.0) x[1] += yprd;
|
|
|
|
else x[1] -= yprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (zperiodic) {
|
|
|
|
if (fabs(x[2]) > zprd_half) {
|
|
|
|
if (x[2] < 0.0) x[2] += zprd;
|
|
|
|
else x[2] -= zprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
remap the point into the periodic box no matter how far away
|
|
|
|
adjust image accordingly
|
|
|
|
resulting coord must satisfy lo <= coord < hi
|
|
|
|
MAX is important since coord - prd < lo can happen when coord = hi
|
|
|
|
image = 10 bits for each dimension
|
|
|
|
increment/decrement in wrap-around fashion
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::remap(double &x, double &y, double &z, int &image)
|
|
|
|
{
|
|
|
|
if (xperiodic) {
|
|
|
|
while (x < boxxlo) {
|
|
|
|
x += xprd;
|
|
|
|
int idim = image & 1023;
|
|
|
|
int otherdims = image ^ idim;
|
|
|
|
idim--;
|
|
|
|
idim &= 1023;
|
|
|
|
image = otherdims | idim;
|
|
|
|
}
|
|
|
|
while (x >= boxxhi) {
|
|
|
|
x -= xprd;
|
|
|
|
int idim = image & 1023;
|
|
|
|
int otherdims = image ^ idim;
|
|
|
|
idim++;
|
|
|
|
idim &= 1023;
|
|
|
|
image = otherdims | idim;
|
|
|
|
}
|
|
|
|
x = MAX(x,boxxlo);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (yperiodic) {
|
|
|
|
while (y < boxylo) {
|
|
|
|
y += yprd;
|
|
|
|
int idim = (image >> 10) & 1023;
|
|
|
|
int otherdims = image ^ (idim << 10);
|
|
|
|
idim--;
|
|
|
|
idim &= 1023;
|
|
|
|
image = otherdims | (idim << 10);
|
|
|
|
}
|
|
|
|
while (y >= boxyhi) {
|
|
|
|
y -= yprd;
|
|
|
|
int idim = (image >> 10) & 1023;
|
|
|
|
int otherdims = image ^ (idim << 10);
|
|
|
|
idim++;
|
|
|
|
idim &= 1023;
|
|
|
|
image = otherdims | (idim << 10);
|
|
|
|
}
|
|
|
|
y = MAX(y,boxylo);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zperiodic) {
|
|
|
|
while (z < boxzlo) {
|
|
|
|
z += zprd;
|
|
|
|
int idim = image >> 20;
|
|
|
|
int otherdims = image ^ (idim << 20);
|
|
|
|
idim--;
|
|
|
|
idim &= 1023;
|
|
|
|
image = otherdims | (idim << 20);
|
|
|
|
}
|
|
|
|
while (z >= boxzhi) {
|
|
|
|
z -= zprd;
|
|
|
|
int idim = image >> 20;
|
|
|
|
int otherdims = image ^ (idim << 20);
|
2006-12-11 23:32:21 +08:00
|
|
|
idim++;
|
2006-09-28 03:51:33 +08:00
|
|
|
idim &= 1023;
|
|
|
|
image = otherdims | (idim << 20);
|
|
|
|
}
|
|
|
|
z = MAX(z,boxzlo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
unmap the point via image flags
|
|
|
|
don't reset image flag
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::unmap(double &x, double &y, double &z, int image)
|
|
|
|
{
|
|
|
|
int xbox = (image & 1023) - 512;
|
|
|
|
int ybox = (image >> 10 & 1023) - 512;
|
|
|
|
int zbox = (image >> 20) - 512;
|
|
|
|
|
|
|
|
x = x + xbox*xprd;
|
|
|
|
y = y + ybox*yprd;
|
|
|
|
z = z + zbox*zprd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
2006-11-14 06:17:52 +08:00
|
|
|
create a lattice
|
|
|
|
delete it if style = none
|
2006-09-28 03:51:33 +08:00
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::set_lattice(int narg, char **arg)
|
|
|
|
{
|
2006-11-14 06:17:52 +08:00
|
|
|
delete lattice;
|
|
|
|
lattice = new Lattice(narg,arg);
|
|
|
|
if (lattice->style == 0) {
|
|
|
|
delete lattice;
|
|
|
|
lattice = NULL;
|
2006-09-28 03:51:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
create a new region
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::add_region(int narg, char **arg)
|
|
|
|
{
|
|
|
|
if (narg < 2) error->all("Illegal region command");
|
|
|
|
|
|
|
|
// error checks
|
|
|
|
|
|
|
|
for (int iregion = 0; iregion < nregion; iregion++)
|
|
|
|
if (strcmp(arg[0],regions[iregion]->id) == 0)
|
|
|
|
error->all("Reuse of region ID");
|
|
|
|
|
|
|
|
// extend Region list if necessary
|
|
|
|
|
|
|
|
if (nregion == maxregion) {
|
|
|
|
maxregion += DELTA;
|
|
|
|
regions = (Region **)
|
|
|
|
memory->srealloc(regions,maxregion*sizeof(Region *),"domain:regions");
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the Region
|
|
|
|
|
|
|
|
if (strcmp(arg[1],"none") == 0) error->all("Invalid region style");
|
|
|
|
|
|
|
|
#define RegionClass
|
|
|
|
#define RegionStyle(key,Class) \
|
|
|
|
else if (strcmp(arg[1],#key) == 0) regions[nregion] = new Class(narg,arg);
|
|
|
|
#include "style.h"
|
|
|
|
#undef RegionClass
|
|
|
|
|
|
|
|
else error->all("Invalid region style");
|
|
|
|
|
|
|
|
nregion++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
boundary settings from the input script
|
|
|
|
------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void Domain::set_boundary(int narg, char **arg)
|
|
|
|
{
|
|
|
|
if (narg != 3) error->all("Illegal boundary command");
|
|
|
|
|
|
|
|
char c;
|
|
|
|
for (int idim = 0; idim < 3; idim++)
|
|
|
|
for (int iside = 0; iside < 2; iside++) {
|
|
|
|
if (iside == 0) c = arg[idim][0];
|
|
|
|
else if (iside == 1 && strlen(arg[idim]) == 1) c = arg[idim][0];
|
|
|
|
else c = arg[idim][1];
|
|
|
|
|
|
|
|
if (c == 'p') boundary[idim][iside] = 0;
|
|
|
|
else if (c == 'f') boundary[idim][iside] = 1;
|
|
|
|
else if (c == 's') boundary[idim][iside] = 2;
|
|
|
|
else if (c == 'm') boundary[idim][iside] = 3;
|
|
|
|
else error->all("Illegal boundary command");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int idim = 0; idim < 3; idim++)
|
|
|
|
if ((boundary[idim][0] == 0 && boundary[idim][1]) ||
|
|
|
|
(boundary[idim][0] && boundary[idim][1] == 0))
|
|
|
|
error->all("Both sides of boundary must be periodic");
|
|
|
|
|
|
|
|
if (boundary[0][0] == 0) xperiodic = 1;
|
|
|
|
else xperiodic = 0;
|
|
|
|
if (boundary[1][0] == 0) yperiodic = 1;
|
|
|
|
else yperiodic = 0;
|
|
|
|
if (boundary[2][0] == 0) zperiodic = 1;
|
|
|
|
else zperiodic = 0;
|
|
|
|
|
2006-11-14 06:17:52 +08:00
|
|
|
periodicity[0] = xperiodic;
|
|
|
|
periodicity[1] = yperiodic;
|
|
|
|
periodicity[2] = zperiodic;
|
|
|
|
|
2006-09-28 03:51:33 +08:00
|
|
|
nonperiodic = 0;
|
|
|
|
if (xperiodic == 0 || yperiodic == 0 || zperiodic == 0) {
|
|
|
|
nonperiodic = 1;
|
|
|
|
if (boundary[0][0] >= 2 || boundary[0][1] >= 2 ||
|
|
|
|
boundary[1][0] >= 2 || boundary[1][1] >= 2 ||
|
|
|
|
boundary[2][0] >= 2 || boundary[2][1] >= 2) nonperiodic = 2;
|
|
|
|
}
|
|
|
|
}
|