From 8be0384eaba39510df3be8116d2c1b3f4eca4180 Mon Sep 17 00:00:00 2001 From: sjplimp Date: Fri, 1 Feb 2013 00:39:50 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9372 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/atom_vec_body.cpp | 1409 +++++++++++++++++++++++++++++++++++++++++ src/atom_vec_body.h | 147 +++++ 2 files changed, 1556 insertions(+) create mode 100644 src/atom_vec_body.cpp create mode 100644 src/atom_vec_body.h diff --git a/src/atom_vec_body.cpp b/src/atom_vec_body.cpp new file mode 100644 index 0000000000..af955bad4c --- /dev/null +++ b/src/atom_vec_body.cpp @@ -0,0 +1,1409 @@ +/* ---------------------------------------------------------------------- + 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 "atom_vec_body.h" +#include "style_body.h" +#include "body.h" +#include "atom.h" +#include "comm.h" +#include "domain.h" +#include "modify.h" +#include "force.h" +#include "fix.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 +#define DELTA_BONUS 10000 + +/* ---------------------------------------------------------------------- */ + +AtomVecBody::AtomVecBody(LAMMPS *lmp) : AtomVec(lmp) +{ + molecular = 0; + + // size_forward and size_border set in settings(), via Body class + + comm_x_only = comm_f_only = 0; + size_forward = 0; + size_reverse = 6; + size_border = 0; + size_velocity = 6; + size_data_atom = 7; + size_data_vel = 7; + xcol_data = 5; + + atom->body_flag = 1; + atom->rmass_flag = 1; + atom->angmom_flag = atom->torque_flag = 1; + + nlocal_bonus = nghost_bonus = nmax_bonus = 0; + bonus = NULL; + + bptr = NULL; + + nargcopy = 0; + argcopy = NULL; + copyflag = 1; + + if (sizeof(double) == sizeof(int)) intdoubleratio = 1; + else if (sizeof(double) == 2*sizeof(int)) intdoubleratio = 2; + else error->all(FLERR,"Internal error in atom_style body"); +} + +/* ---------------------------------------------------------------------- */ + +AtomVecBody::~AtomVecBody() +{ + int nall = nlocal_bonus + nghost_bonus; + for (int i = 0; i < nall; i++) { + memory->destroy(bonus[i].ivalue); + memory->destroy(bonus[i].dvalue); + } + memory->sfree(bonus); + + delete bptr; + + for (int i = 0; i < nargcopy; i++) delete [] argcopy[i]; + delete [] argcopy; +} + +/* ---------------------------------------------------------------------- + process additional args + instantiate Body class + set size_forward and size_border to max sizes +------------------------------------------------------------------------- */ + +void AtomVecBody::settings(int narg, char **arg) +{ + if (narg < 1) error->all(FLERR,"Invalid atom_style body command"); + + if (0) bptr = NULL; + +#define BODY_CLASS +#define BodyStyle(key,Class) \ + else if (strcmp(arg[0],#key) == 0) bptr = new Class(lmp,narg,arg); +#include "style_body.h" +#undef BodyStyle +#undef BODY_CLASS + + else error->all(FLERR,"Invalid body style"); + + bptr->avec = this; + + // max size of forward/border comm + // 7,16 are packed in pack_comm/pack_border + // bptr values = max number of additional ivalues/dvalues from Body class + + size_forward = 7 + bptr->size_forward; + size_border = 16 + bptr->size_border; + + // make copy of args if called externally, so can write to restart file + // make no copy of args if called from read_restart() + + if (copyflag) { + nargcopy = narg; + argcopy = new char*[nargcopy]; + for (int i = 0; i < nargcopy; i++) { + int n = strlen(arg[i]) + 1; + argcopy[i] = new char[n]; + strcpy(argcopy[i],arg[i]); + } + } +} + +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by DELTA + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVecBody::grow(int n) +{ + if (n == 0) nmax += DELTA; + else nmax = n; + atom->nmax = nmax; + if (nmax < 0 || nmax > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + tag = memory->grow(atom->tag,nmax,"atom:tag"); + type = memory->grow(atom->type,nmax,"atom:type"); + mask = memory->grow(atom->mask,nmax,"atom:mask"); + image = memory->grow(atom->image,nmax,"atom:image"); + x = memory->grow(atom->x,nmax,3,"atom:x"); + v = memory->grow(atom->v,nmax,3,"atom:v"); + f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f"); + + rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); + angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom"); + torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); + body = memory->grow(atom->body,nmax,"atom:body"); + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVecBody::grow_reset() +{ + tag = atom->tag; type = atom->type; + mask = atom->mask; image = atom->image; + x = atom->x; v = atom->v; f = atom->f; + rmass = atom->rmass; angmom = atom->angmom; torque = atom->torque; + body = atom->body; +} + +/* ---------------------------------------------------------------------- + grow bonus data structure +------------------------------------------------------------------------- */ + +void AtomVecBody::grow_bonus() +{ + nmax_bonus += DELTA_BONUS; + if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT) + error->one(FLERR,"Per-processor system is too big"); + + bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus), + "atom:bonus"); +} + +/* ---------------------------------------------------------------------- + copy atom I info to atom J + if delflag and atom J has bonus data, then delete it +------------------------------------------------------------------------- */ + +void AtomVecBody::copy(int i, int j, int delflag) +{ + tag[j] = tag[i]; + type[j] = type[i]; + mask[j] = mask[i]; + image[j] = image[i]; + x[j][0] = x[i][0]; + x[j][1] = x[i][1]; + x[j][2] = x[i][2]; + v[j][0] = v[i][0]; + v[j][1] = v[i][1]; + v[j][2] = v[i][2]; + + rmass[j] = rmass[i]; + angmom[j][0] = angmom[i][0]; + angmom[j][1] = angmom[i][1]; + angmom[j][2] = angmom[i][2]; + + // if deleting atom J via delflag and J has bonus data, then delete it + + if (delflag && body[j] >= 0) { + memory->destroy(bonus[body[j]].ivalue); + memory->destroy(bonus[body[j]].dvalue); + copy_bonus(nlocal_bonus-1,body[j]); + nlocal_bonus--; + } + + // if atom I has bonus data, reset I's bonus.ilocal to loc J + + if (body[i] >= 0) bonus[body[i]].ilocal = j; + body[j] = body[i]; + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j); +} + +/* ---------------------------------------------------------------------- + copy bonus data from I to J, effectively deleting the J entry + insure index pointers between per-atom and bonus data are updated +------------------------------------------------------------------------- */ + +void AtomVecBody::copy_bonus(int i, int j) +{ + memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); + body[bonus[j].ilocal] = j; +} + +/* ---------------------------------------------------------------------- + clear ghost info in bonus data + called before ghosts are recommunicated in comm and irregular +------------------------------------------------------------------------- */ + +void AtomVecBody::clear_bonus() +{ + int nall = nlocal_bonus + nghost_bonus; + for (int i = nlocal_bonus; i < nall; i++) { + memory->destroy(bonus[i].ivalue); + memory->destroy(bonus[i].dvalue); + } + nghost_bonus = 0; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + double *quat; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (body[j] >= 0) { + quat = bonus[body[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + m += bptr->pack_comm_body(&bonus[body[j]],&buf[m]); + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (body[j] >= 0) { + quat = bonus[body[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + m += bptr->pack_comm_body(&bonus[body[j]],&buf[m]); + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + double *quat; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + if (body[j] >= 0) { + quat = bonus[body[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + m += bptr->pack_comm_body(&bonus[body[j]],&buf[m]); + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz; + dy = pbc[1]*domain->yprd + pbc[3]*domain->yz; + dz = pbc[2]*domain->zprd; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (body[j] >= 0) { + quat = bonus[body[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + m += bptr->pack_comm_body(&bonus[body[j]],&buf[m]); + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + if (body[j] >= 0) { + quat = bonus[body[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + m += bptr->pack_comm_body(&bonus[body[j]],&buf[m]); + } + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_comm_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + double *quat; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (body[j] >= 0) { + quat = bonus[body[j]].quat; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + m += bptr->pack_comm_body(&bonus[body[j]],&buf[m]); + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::unpack_comm(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + if (body[i] >= 0) { + quat = bonus[body[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + m += bptr->unpack_comm_body(&bonus[body[i]],&buf[m]); + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + if (body[i] >= 0) { + quat = bonus[body[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + m += bptr->unpack_comm_body(&bonus[body[i]],&buf[m]); + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + angmom[i][0] = buf[m++]; + angmom[i][1] = buf[m++]; + angmom[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::unpack_comm_hybrid(int n, int first, double *buf) +{ + int i,m,last; + double *quat; + + m = 0; + last = first + n; + for (i = first; i < last; i++) + if (body[i] >= 0) { + quat = bonus[body[i]].quat; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + m += bptr->unpack_comm_body(&bonus[body[i]],&buf[m]); + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_reverse(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = f[i][0]; + buf[m++] = f[i][1]; + buf[m++] = f[i][2]; + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_reverse_hybrid(int n, int first, double *buf) +{ + int i,m,last; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + buf[m++] = torque[i][0]; + buf[m++] = torque[i][1]; + buf[m++] = torque[i][2]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + f[j][0] += buf[m++]; + f[j][1] += buf[m++]; + f[j][2] += buf[m++]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::unpack_reverse_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + torque[j][0] += buf[m++]; + torque[j][1] += buf[m++]; + torque[j][2] += buf[m++]; + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_border(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + if (body[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[body[j]].quat; + inertia = bonus[body[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[body[j]].ninteger; + buf[m++] = bonus[body[j]].ndouble; + m += bptr->pack_border_body(&bonus[body[j]],&buf[m]); + } + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + if (body[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[body[j]].quat; + inertia = bonus[body[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[body[j]].ninteger; + buf[m++] = bonus[body[j]].ndouble; + m += bptr->pack_border_body(&bonus[body[j]],&buf[m]); + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m; + double dx,dy,dz,dvx,dvy,dvz; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + if (pbc_flag == 0) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0]; + buf[m++] = x[j][1]; + buf[m++] = x[j][2]; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + if (body[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[body[j]].quat; + inertia = bonus[body[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[body[j]].ninteger; + buf[m++] = bonus[body[j]].ndouble; + m += bptr->pack_border_body(&bonus[body[j]],&buf[m]); + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + if (domain->triclinic == 0) { + dx = pbc[0]*domain->xprd; + dy = pbc[1]*domain->yprd; + dz = pbc[2]*domain->zprd; + } else { + dx = pbc[0]; + dy = pbc[1]; + dz = pbc[2]; + } + if (!deform_vremap) { + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + if (body[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[body[j]].quat; + inertia = bonus[body[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[body[j]].ninteger; + buf[m++] = bonus[body[j]].ndouble; + m += bptr->pack_border_body(&bonus[body[j]],&buf[m]); + } + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } else { + dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4]; + dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3]; + dvz = pbc[2]*h_rate[2]; + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = x[j][0] + dx; + buf[m++] = x[j][1] + dy; + buf[m++] = x[j][2] + dz; + buf[m++] = tag[j]; + buf[m++] = type[j]; + buf[m++] = mask[j]; + if (body[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[body[j]].quat; + inertia = bonus[body[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[body[j]].ninteger; + buf[m++] = bonus[body[j]].ndouble; + m += bptr->pack_border_body(&bonus[body[j]],&buf[m]); + } + if (mask[i] & deform_groupbit) { + buf[m++] = v[j][0] + dvx; + buf[m++] = v[j][1] + dvy; + buf[m++] = v[j][2] + dvz; + } else { + buf[m++] = v[j][0]; + buf[m++] = v[j][1]; + buf[m++] = v[j][2]; + } + buf[m++] = angmom[j][0]; + buf[m++] = angmom[j][1]; + buf[m++] = angmom[j][2]; + } + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::pack_border_hybrid(int n, int *list, double *buf) +{ + int i,j,m; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + for (i = 0; i < n; i++) { + j = list[i]; + if (body[j] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + quat = bonus[body[j]].quat; + inertia = bonus[body[j]].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[body[j]].ninteger; + buf[m++] = bonus[body[j]].ndouble; + m += bptr->pack_border_body(&bonus[body[j]],&buf[m]); + } + } + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::unpack_border(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + body[i] = static_cast (buf[m++]); + if (body[i] == 0) body[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ninteger = static_cast (buf[m++]); + bonus[j].ndouble = static_cast (buf[m++]); + memory->create(bonus[j].ivalue,bonus[j].ninteger,"body:ivalue"); + memory->create(bonus[j].dvalue,bonus[j].ndouble,"body:dvalue"); + m += bptr->unpack_border_body(&bonus[j],&buf[m]); + bonus[j].ilocal = i; + body[i] = j; + nghost_bonus++; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::unpack_border_vel(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + if (i == nmax) grow(0); + x[i][0] = buf[m++]; + x[i][1] = buf[m++]; + x[i][2] = buf[m++]; + tag[i] = static_cast (buf[m++]); + type[i] = static_cast (buf[m++]); + mask[i] = static_cast (buf[m++]); + body[i] = static_cast (buf[m++]); + if (body[i] == 0) body[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ninteger = static_cast (buf[m++]); + bonus[j].ndouble = static_cast (buf[m++]); + memory->create(bonus[j].ivalue,bonus[j].ninteger,"body:ivalue"); + memory->create(bonus[j].dvalue,bonus[j].ndouble,"body:dvalue"); + m += bptr->unpack_border_body(&bonus[j],&buf[m]); + bonus[j].ilocal = i; + body[i] = j; + nghost_bonus++; + } + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + angmom[i][0] = buf[m++]; + angmom[i][1] = buf[m++]; + angmom[i][2] = buf[m++]; + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::unpack_border_hybrid(int n, int first, double *buf) +{ + int i,j,m,last; + double *quat,*c1,*c2,*c3,*inertia; + + m = 0; + last = first + n; + for (i = first; i < last; i++) { + body[i] = static_cast (buf[m++]); + if (body[i] == 0) body[i] = -1; + else { + j = nlocal_bonus + nghost_bonus; + if (j == nmax_bonus) grow_bonus(); + quat = bonus[j].quat; + inertia = bonus[j].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[j].ninteger = static_cast (buf[m++]); + bonus[j].ndouble = static_cast (buf[m++]); + memory->create(bonus[j].ivalue,bonus[j].ninteger,"body:ivalue"); + memory->create(bonus[j].dvalue,bonus[j].ndouble,"body:dvalue"); + m += bptr->unpack_border_body(&bonus[j],&buf[m]); + bonus[j].ilocal = i; + body[i] = j; + nghost_bonus++; + } + } + return m; +} + +/* ---------------------------------------------------------------------- + pack data for atom I for sending to another proc + xyz must be 1st 3 values, so comm::exchange() can test on them +------------------------------------------------------------------------- */ + +int AtomVecBody::pack_exchange(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + buf[m++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + *((tagint *) &buf[m++]) = image[i]; + + buf[m++] = rmass[i]; + buf[m++] = angmom[i][0]; + buf[m++] = angmom[i][1]; + buf[m++] = angmom[i][2]; + + if (body[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = body[i]; + double *quat = bonus[j].quat; + double *inertia = bonus[j].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[j].ninteger; + buf[m++] = bonus[j].ndouble; + memcpy(&buf[m],bonus[j].ivalue,bonus[j].ninteger*sizeof(int)); + if (intdoubleratio == 1) m += bonus[j].ninteger; + else m += (bonus[j].ninteger+1)/2; + memcpy(&buf[m],bonus[j].dvalue,bonus[j].ndouble*sizeof(double)); + m += bonus[j].ndouble; + } + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVecBody::unpack_exchange(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + tag[nlocal] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = *((tagint *) &buf[m++]); + + rmass[nlocal] = buf[m++]; + angmom[nlocal][0] = buf[m++]; + angmom[nlocal][1] = buf[m++]; + angmom[nlocal][2] = buf[m++]; + + body[nlocal] = static_cast (buf[m++]); + if (body[nlocal] == 0) body[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[nlocal_bonus].ninteger = static_cast (buf[m++]); + bonus[nlocal_bonus].ndouble = static_cast (buf[m++]); + memory->create(bonus[nlocal_bonus].ivalue,bonus[nlocal_bonus].ninteger, + "body:ivalue"); + memory->create(bonus[nlocal_bonus].dvalue,bonus[nlocal_bonus].ndouble, + "body:dvalue"); + memcpy(bonus[nlocal_bonus].ivalue,&buf[m], + bonus[nlocal_bonus].ninteger*sizeof(int)); + if (intdoubleratio == 1) m += bonus[nlocal_bonus].ninteger; + else m += (bonus[nlocal_bonus].ninteger+1)/2; + memcpy(bonus[nlocal_bonus].dvalue,&buf[m], + bonus[nlocal_bonus].ndouble*sizeof(double)); + m += bonus[nlocal_bonus].ndouble; + + bonus[nlocal_bonus].ilocal = nlocal; + body[nlocal] = nlocal_bonus++; + } + + if (atom->nextra_grow) + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + m += modify->fix[atom->extra_grow[iextra]]-> + unpack_exchange(nlocal,&buf[m]); + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- + size of restart data for all atoms owned by this proc + include extra data stored by fixes +------------------------------------------------------------------------- */ + +int AtomVecBody::size_restart() +{ + int i; + + int n = 0; + int nlocal = atom->nlocal; + for (i = 0; i < nlocal; i++) + if (body[i] >= 0) { + n += 25; + if (intdoubleratio == 1) n += bonus[body[i]].ninteger; + else n += (bonus[body[i]].ninteger+1)/2; + n += bonus[body[i]].ndouble; + } else n += 16; + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + for (i = 0; i < nlocal; i++) + n += modify->fix[atom->extra_restart[iextra]]->size_restart(i); + + return n; +} + +/* ---------------------------------------------------------------------- + pack atom I's data for restart file including extra quantities + xyz must be 1st 3 values, so that read_restart can test on them + molecular types may be negative, but write as positive +------------------------------------------------------------------------- */ + +int AtomVecBody::pack_restart(int i, double *buf) +{ + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + buf[m++] = tag[i]; + buf[m++] = type[i]; + buf[m++] = mask[i]; + *((tagint *) &buf[m++]) = image[i]; + buf[m++] = v[i][0]; + buf[m++] = v[i][1]; + buf[m++] = v[i][2]; + + buf[m++] = rmass[i]; + buf[m++] = angmom[i][0]; + buf[m++] = angmom[i][1]; + buf[m++] = angmom[i][2]; + + if (body[i] < 0) buf[m++] = 0; + else { + buf[m++] = 1; + int j = body[i]; + double *quat = bonus[j].quat; + double *inertia = bonus[j].inertia; + buf[m++] = quat[0]; + buf[m++] = quat[1]; + buf[m++] = quat[2]; + buf[m++] = quat[3]; + buf[m++] = inertia[0]; + buf[m++] = inertia[1]; + buf[m++] = inertia[2]; + buf[m++] = bonus[j].ninteger; + buf[m++] = bonus[j].ndouble; + memcpy(&buf[m],bonus[j].ivalue,bonus[j].ninteger*sizeof(int)); + if (intdoubleratio == 1) m += bonus[j].ninteger; + else m += (bonus[j].ninteger+1)/2; + memcpy(&buf[m],bonus[j].dvalue,bonus[j].ndouble*sizeof(double)); + m += bonus[j].ndouble; + } + + if (atom->nextra_restart) + for (int iextra = 0; iextra < atom->nextra_restart; iextra++) + m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]); + + buf[0] = m; + return m; +} + +/* ---------------------------------------------------------------------- + unpack data for one atom from restart file including extra quantities +------------------------------------------------------------------------- */ + +int AtomVecBody::unpack_restart(double *buf) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) { + grow(0); + if (atom->nextra_store) + memory->grow(atom->extra,nmax,atom->nextra_store,"atom:extra"); + } + + int m = 1; + x[nlocal][0] = buf[m++]; + x[nlocal][1] = buf[m++]; + x[nlocal][2] = buf[m++]; + tag[nlocal] = static_cast (buf[m++]); + type[nlocal] = static_cast (buf[m++]); + mask[nlocal] = static_cast (buf[m++]); + image[nlocal] = *((tagint *) &buf[m++]); + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + rmass[nlocal] = buf[m++]; + angmom[nlocal][0] = buf[m++]; + angmom[nlocal][1] = buf[m++]; + angmom[nlocal][2] = buf[m++]; + + body[nlocal] = static_cast (buf[m++]); + if (body[nlocal] == 0) body[nlocal] = -1; + else { + if (nlocal_bonus == nmax_bonus) grow_bonus(); + double *quat = bonus[nlocal_bonus].quat; + double *inertia = bonus[nlocal_bonus].inertia; + quat[0] = buf[m++]; + quat[1] = buf[m++]; + quat[2] = buf[m++]; + quat[3] = buf[m++]; + inertia[0] = buf[m++]; + inertia[1] = buf[m++]; + inertia[2] = buf[m++]; + bonus[nlocal_bonus].ninteger = static_cast (buf[m++]); + bonus[nlocal_bonus].ndouble = static_cast (buf[m++]); + memory->create(bonus[nlocal_bonus].ivalue,bonus[nlocal_bonus].ninteger, + "body:ivalue"); + memory->create(bonus[nlocal_bonus].dvalue,bonus[nlocal_bonus].ndouble, + "body:dvalue"); + memcpy(bonus[nlocal_bonus].ivalue,&buf[m], + bonus[nlocal_bonus].ninteger*sizeof(int)); + if (intdoubleratio == 1) m += bonus[nlocal_bonus].ninteger; + else m += (bonus[nlocal_bonus].ninteger+1)/2; + memcpy(bonus[nlocal_bonus].dvalue,&buf[m], + bonus[nlocal_bonus].ndouble*sizeof(double)); + m += bonus[nlocal_bonus].ndouble; + bonus[nlocal_bonus].ilocal = nlocal; + body[nlocal] = nlocal_bonus++; + } + + double **extra = atom->extra; + if (atom->nextra_store) { + int size = static_cast (buf[0]) - m; + for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++]; + } + + atom->nlocal++; + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::write_restart_settings(FILE *fp) +{ + fwrite(&nargcopy,sizeof(int),1,fp); + for (int i = 0; i < nargcopy; i++) { + int n = strlen(argcopy[i]) + 1; + fwrite(&n,sizeof(int),1,fp); + fwrite(argcopy[i],sizeof(char),n,fp); + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVecBody::read_restart_settings(FILE *fp) +{ + int n; + + int me = comm->me; + if (me == 0) fread(&nargcopy,sizeof(int),1,fp); + MPI_Bcast(&nargcopy,1,MPI_INT,0,world); + argcopy = new char*[nargcopy]; + + for (int i = 0; i < nargcopy; i++) { + if (me == 0) fread(&n,sizeof(int),1,fp); + MPI_Bcast(&n,1,MPI_INT,0,world); + argcopy[i] = new char[n]; + if (me == 0) fread(argcopy[i],sizeof(char),n,fp); + MPI_Bcast(argcopy[i],n,MPI_CHAR,0,world); + } + + copyflag = 0; + settings(nargcopy,argcopy); +} + +/* ---------------------------------------------------------------------- + create one atom of itype at coord + set other values to defaults +------------------------------------------------------------------------- */ + +void AtomVecBody::create_atom(int itype, double *coord) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = 0; + type[nlocal] = itype; + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | + ((tagint) IMGMAX << IMGBITS) | IMGMAX; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + rmass[nlocal] = 1.0; + angmom[nlocal][0] = 0.0; + angmom[nlocal][1] = 0.0; + angmom[nlocal][2] = 0.0; + body[nlocal] = -1; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVecBody::data_atom(double *coord, tagint imagetmp, char **values) +{ + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + tag[nlocal] = atoi(values[0]); + if (tag[nlocal] <= 0) + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + + type[nlocal] = atoi(values[1]); + if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + body[nlocal] = atoi(values[2]); + if (body[nlocal] == 0) body[nlocal] = -1; + else if (body[nlocal] == 1) body[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[3]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + + image[nlocal] = imagetmp; + + mask[nlocal] = 1; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + angmom[nlocal][0] = 0.0; + angmom[nlocal][1] = 0.0; + angmom[nlocal][2] = 0.0; + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one line in Atoms section of data file + initialize other atom quantities for this sub-style +------------------------------------------------------------------------- */ + +int AtomVecBody::data_atom_hybrid(int nlocal, char **values) +{ + body[nlocal] = atoi(values[0]); + if (body[nlocal] == 0) body[nlocal] = -1; + else if (body[nlocal] == 1) body[nlocal] = 0; + else error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + rmass[nlocal] = atof(values[1]); + if (rmass[nlocal] <= 0.0) + error->one(FLERR,"Invalid density in Atoms section of data file"); + + return 2; +} + +/* ---------------------------------------------------------------------- + unpack one body from Bodies section of data file +------------------------------------------------------------------------- */ + +void AtomVecBody::data_body(int m, int ninteger, int ndouble, + char **ivalues, char **dvalues) +{ + if (body[m]) error->one(FLERR,"Assigning body parameters to non-body atom"); + if (nlocal_bonus == nmax_bonus) grow_bonus(); + bptr->data_body(nlocal_bonus,ninteger,ndouble,ivalues,dvalues); + bonus[nlocal_bonus].ilocal = m; + body[m] = nlocal_bonus++; +} + +/* ---------------------------------------------------------------------- + unpack one tri from Velocities section of data file +------------------------------------------------------------------------- */ + +void AtomVecBody::data_vel(int m, char **values) +{ + v[m][0] = atof(values[0]); + v[m][1] = atof(values[1]); + v[m][2] = atof(values[2]); + angmom[m][0] = atof(values[3]); + angmom[m][1] = atof(values[4]); + angmom[m][2] = atof(values[5]); +} + +/* ---------------------------------------------------------------------- + unpack hybrid quantities from one body in Velocities section of data file +------------------------------------------------------------------------- */ + +int AtomVecBody::data_vel_hybrid(int m, char **values) +{ + angmom[m][0] = atof(values[0]); + angmom[m][1] = atof(values[1]); + angmom[m][2] = atof(values[2]); + return 3; +} + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVecBody::memory_usage() +{ + bigint bytes = 0; + + if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax); + if (atom->memcheck("type")) bytes += memory->usage(type,nmax); + if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax); + if (atom->memcheck("image")) bytes += memory->usage(image,nmax); + if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3); + if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3); + if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3); + + if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); + if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3); + if (atom->memcheck("torque")) bytes += + memory->usage(torque,nmax*comm->nthreads,3); + if (atom->memcheck("body")) bytes += memory->usage(body,nmax); + + bytes += nmax_bonus*sizeof(Bonus); + + int nall = nlocal_bonus + nghost_bonus; + for (int i = 0; i < nall; i++) { + bytes += bonus[i].ninteger * sizeof(int); + bytes += bonus[i].ndouble * sizeof(double); + } + + return bytes; +} diff --git a/src/atom_vec_body.h b/src/atom_vec_body.h new file mode 100644 index 0000000000..5f6207375c --- /dev/null +++ b/src/atom_vec_body.h @@ -0,0 +1,147 @@ +/* ---------------------------------------------------------------------- + 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 ATOM_CLASS + +AtomStyle(body,AtomVecBody) + +#else + +#ifndef LMP_ATOM_VEC_BODY_H +#define LMP_ATOM_VEC_BODY_H + +#include "atom_vec.h" + +namespace LAMMPS_NS { + +class AtomVecBody : public AtomVec { + public: + class Body *bptr; + + struct Bonus { + double quat[4]; + double inertia[3]; + int ninteger,ndouble; + int *ivalue; + double *dvalue; + int ilocal; + }; + struct Bonus *bonus; + + AtomVecBody(class LAMMPS *); + ~AtomVecBody(); + void settings(int, char **); + void grow(int); + void grow_reset(); + void copy(int, int, int); + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + int pack_comm_hybrid(int, int *, double *); + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + int unpack_comm_hybrid(int, int, double *); + int pack_reverse(int, int, double *); + int pack_reverse_hybrid(int, int, double *); + void unpack_reverse(int, int *, double *); + int unpack_reverse_hybrid(int, int *, double *); + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + int pack_border_hybrid(int, int *, double *); + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int unpack_border_hybrid(int, int, double *); + int pack_exchange(int, double *); + int unpack_exchange(double *); + int size_restart(); + int pack_restart(int, double *); + int unpack_restart(double *); + void write_restart_settings(FILE *); + void read_restart_settings(FILE *); + void create_atom(int, double *); + void data_atom(double *, tagint, char **); + int data_atom_hybrid(int, char **); + void data_vel(int, char **); + int data_vel_hybrid(int, char **); + bigint memory_usage(); + + // manipulate Bonus data structure for extra atom info + + void clear_bonus(); + void data_body(int, int, int, char **, char **); + + private: + int *tag,*type,*mask; + tagint *image; + double **x,**v,**f; + double *rmass; + double **angmom,**torque; + int *body; + + int nlocal_bonus,nghost_bonus,nmax_bonus; + + int nargcopy; // copy of command-line args + char **argcopy; // for writing to restart file + int copyflag; + int intdoubleratio; // sizeof(double) / sizeof(int) + + void grow_bonus(); + void copy_bonus(int, int); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Atom_style tri can only be used in 3d simulations + +Self-explanatory. + +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom ID in Atoms section of data file + +Atom IDs must be positive integers. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + +E: Invalid density in Atoms section of data file + +Density value cannot be <= 0.0. + +E: Assigning tri parameters to non-tri atom + +Self-explanatory. + +E: Invalid shape in Triangles section of data file + +Two or more of the triangle corners are duplicate points. + +E: Inconsistent triangle in data file + +The centroid of the triangle as defined by the corner points is not +the atom coordinate. + +E: Insufficient Jacobi rotations for triangle + +The calculation of the intertia tensor of the triangle failed. This +should not happen if it is a reasonably shaped triangle. + +*/