diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp index 8ef78f900..8d2dc979f 100644 --- a/src/DIPOLE/atom_vec_dipole.cpp +++ b/src/DIPOLE/atom_vec_dipole.cpp @@ -1,915 +1,913 @@ /* ---------------------------------------------------------------------- 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 "atom_vec_dipole.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecDipole::AtomVecDipole(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; mass_type = 1; comm_x_only = 0; comm_f_only = 1; size_forward = 6; size_reverse = 3; size_border = 11; size_velocity = 3; size_data_atom = 9; size_data_vel = 4; xcol_data = 4; atom->q_flag = atom->mu_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecDipole::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"); q = memory->grow(atom->q,nmax,"atom:q"); mu = memory->grow(atom->mu,nmax,4,"atom:mu"); 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 AtomVecDipole::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; q = atom->q; mu = atom->mu; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecDipole::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]; q[j] = q[i]; mu[j][0] = mu[i][0]; mu[j][1] = mu[i][1]; mu[j][2] = mu[i][2]; mu[j][3] = mu[i][3]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecDipole::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[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; } 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++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecDipole::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; 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++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; 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]; } } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecDipole::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecDipole::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; mu[i][0] = buf[m++]; mu[i][1] = buf[m++]; mu[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecDipole::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; mu[i][0] = buf[m++]; mu[i][1] = buf[m++]; mu[i][2] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecDipole::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { mu[i][0] = buf[m++]; mu[i][1] = buf[m++]; mu[i][2] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecDipole::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecDipole::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecDipole::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = q[j]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = mu[j][3]; } } 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]; buf[m++] = q[j]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = mu[j][3]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecDipole::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; 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]; buf[m++] = q[j]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = mu[j][3]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = mu[j][3]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = mu[j][3]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecDipole::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = q[j]; buf[m++] = mu[j][0]; buf[m++] = mu[j][1]; buf[m++] = mu[j][2]; buf[m++] = mu[j][3]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecDipole::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; mu[i][0] = buf[m++]; mu[i][1] = buf[m++]; mu[i][2] = buf[m++]; mu[i][3] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecDipole::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; mu[i][0] = buf[m++]; mu[i][1] = buf[m++]; mu[i][2] = buf[m++]; mu[i][3] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecDipole::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { q[i] = buf[m++]; mu[i][0] = buf[m++]; mu[i][1] = buf[m++]; mu[i][2] = buf[m++]; mu[i][3] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- pack all atom quantities for shipping to another proc xyz must be 1st 3 values, so that comm::exchange can test on them ------------------------------------------------------------------------- */ int AtomVecDipole::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = q[i]; buf[m++] = mu[i][0]; buf[m++] = mu[i][1]; buf[m++] = mu[i][2]; buf[m++] = mu[i][3]; 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 AtomVecDipole::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++]); q[nlocal] = buf[m++]; mu[nlocal][0] = buf[m++]; mu[nlocal][1] = buf[m++]; mu[nlocal][2] = buf[m++]; mu[nlocal][3] = buf[m++]; 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 AtomVecDipole::size_restart() { int i; int nlocal = atom->nlocal; int n = 16 * nlocal; 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 AtomVecDipole::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = q[i]; buf[m++] = mu[i][0]; buf[m++] = mu[i][1]; buf[m++] = mu[i][2]; buf[m++] = mu[i][3]; 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 AtomVecDipole::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++]; q[nlocal] = buf[m++]; mu[nlocal][0] = buf[m++]; mu[nlocal][1] = buf[m++]; mu[nlocal][2] = buf[m++]; mu[nlocal][3] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecDipole::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; q[nlocal] = 0.0; mu[nlocal][0] = 0.0; mu[nlocal][1] = 0.0; mu[nlocal][2] = 0.0; mu[nlocal][3] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecDipole::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"); q[nlocal] = atof(values[2]); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; x[nlocal][2] = coord[2]; mu[nlocal][0] = atof(values[6]); mu[nlocal][1] = atof(values[7]); mu[nlocal][2] = atof(values[8]); mu[nlocal][3] = sqrt(mu[nlocal][0]*mu[nlocal][0] + mu[nlocal][1]*mu[nlocal][1] + mu[nlocal][2]*mu[nlocal][2]); image[nlocal] = imagetmp; mask[nlocal] = 1; v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; v[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 AtomVecDipole::data_atom_hybrid(int nlocal, char **values) { q[nlocal] = atof(values[0]); mu[nlocal][0] = atof(values[1]); mu[nlocal][1] = atof(values[2]); mu[nlocal][2] = atof(values[3]); mu[nlocal][3] = sqrt(mu[nlocal][0]*mu[nlocal][0] + mu[nlocal][1]*mu[nlocal][1] + mu[nlocal][2]*mu[nlocal][2]); return 4; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecDipole::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = q[i]; buf[i][3] = x[i][0]; buf[i][4] = x[i][1]; buf[i][5] = x[i][2]; buf[i][6] = mu[i][0]; buf[i][7] = mu[i][1]; buf[i][8] = mu[i][2]; buf[i][9] = (image[i] & IMGMASK) - IMGMAX; buf[i][10] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][11] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecDipole::pack_data_hybrid(int i, double *buf) { buf[0] = q[i]; buf[1] = mu[i][0]; buf[2] = mu[i][1]; buf[3] = mu[i][2]; return 4; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecDipole::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e " "%-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],buf[i][2], buf[i][3],buf[i][4],buf[i][5], buf[i][6],buf[i][7],buf[i][8], (int) buf[i][9],(int) buf[i][10],(int) buf[i][11]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecDipole::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e %-1.16e %-1.16e",buf[0],buf[1],buf[2],buf[3]); return 4; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecDipole::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("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("mu")) bytes += memory->usage(mu,nmax,4); return bytes; } diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp index ff89b769d..e7af84e6d 100644 --- a/src/MOLECULE/atom_vec_angle.cpp +++ b/src/MOLECULE/atom_vec_angle.cpp @@ -1,930 +1,928 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_angle.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecAngle::AtomVecAngle(LAMMPS *lmp) : AtomVec(lmp) { molecular = 1; bonds_allow = angles_allow = 1; mass_type = 1; comm_x_only = comm_f_only = 1; size_forward = 3; size_reverse = 3; size_border = 7; size_velocity = 3; size_data_atom = 6; size_data_vel = 4; xcol_data = 4; atom->molecule_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecAngle::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"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial"); special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special"); num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond"); bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom, "atom:bond_type"); bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom, "atom:bond_atom"); num_angle = memory->grow(atom->num_angle,nmax,"atom:num_angle"); angle_type = memory->grow(atom->angle_type,nmax,atom->angle_per_atom, "atom:angle_type"); angle_atom1 = memory->grow(atom->angle_atom1,nmax,atom->angle_per_atom, "atom:angle_atom1"); angle_atom2 = memory->grow(atom->angle_atom2,nmax,atom->angle_per_atom, "atom:angle_atom2"); angle_atom3 = memory->grow(atom->angle_atom3,nmax,atom->angle_per_atom, "atom:angle_atom3"); 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 AtomVecAngle::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; molecule = atom->molecule; nspecial = atom->nspecial; special = atom->special; num_bond = atom->num_bond; bond_type = atom->bond_type; bond_atom = atom->bond_atom; num_angle = atom->num_angle; angle_type = atom->angle_type; angle_atom1 = atom->angle_atom1; angle_atom2 = atom->angle_atom2; angle_atom3 = atom->angle_atom3; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecAngle::copy(int i, int j, int delflag) { int k; 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]; molecule[j] = molecule[i]; num_bond[j] = num_bond[i]; for (k = 0; k < num_bond[j]; k++) { bond_type[j][k] = bond_type[i][k]; bond_atom[j][k] = bond_atom[i][k]; } num_angle[j] = num_angle[i]; for (k = 0; k < num_angle[j]; k++) { angle_type[j][k] = angle_type[i][k]; angle_atom1[j][k] = angle_atom1[i][k]; angle_atom2[j][k] = angle_atom2[i][k]; angle_atom3[j][k] = angle_atom3[i][k]; } nspecial[j][0] = nspecial[i][0]; nspecial[j][1] = nspecial[i][1]; nspecial[j][2] = nspecial[i][2]; for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecAngle::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecAngle::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; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecAngle::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; } } /* ---------------------------------------------------------------------- */ void AtomVecAngle::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecAngle::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecAngle::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecAngle::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = molecule[j]; } } 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]; buf[m++] = molecule[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecAngle::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; 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]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = molecule[j]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecAngle::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = molecule[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecAngle::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); molecule[i] = static_cast (buf[m++]); } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecAngle::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); molecule[i] = static_cast (buf[m++]); v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecAngle::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) molecule[i] = static_cast (buf[m++]); 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 AtomVecAngle::pack_exchange(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = bond_type[i][k]; buf[m++] = bond_atom[i][k]; } buf[m++] = num_angle[i]; for (k = 0; k < num_angle[i]; k++) { buf[m++] = angle_type[i][k]; buf[m++] = angle_atom1[i][k]; buf[m++] = angle_atom2[i][k]; buf[m++] = angle_atom3[i][k]; } buf[m++] = nspecial[i][0]; buf[m++] = nspecial[i][1]; buf[m++] = nspecial[i][2]; for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; 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 AtomVecAngle::unpack_exchange(double *buf) { int k; 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++]); molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } num_angle[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_angle[nlocal]; k++) { angle_type[nlocal][k] = static_cast (buf[m++]); angle_atom1[nlocal][k] = static_cast (buf[m++]); angle_atom2[nlocal][k] = static_cast (buf[m++]); angle_atom3[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = static_cast (buf[m++]); nspecial[nlocal][1] = static_cast (buf[m++]); nspecial[nlocal][2] = static_cast (buf[m++]); for (k = 0; k < nspecial[nlocal][2]; k++) special[nlocal][k] = static_cast (buf[m++]); 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 AtomVecAngle::size_restart() { int i; int nlocal = atom->nlocal; int n = 0; for (i = 0; i < nlocal; i++) n += 14 + 2*num_bond[i] + 4*num_angle[i]; 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 AtomVecAngle::pack_restart(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = MAX(bond_type[i][k],-bond_type[i][k]); buf[m++] = bond_atom[i][k]; } buf[m++] = num_angle[i]; for (k = 0; k < num_angle[i]; k++) { buf[m++] = MAX(angle_type[i][k],-angle_type[i][k]); buf[m++] = angle_atom1[i][k]; buf[m++] = angle_atom2[i][k]; buf[m++] = angle_atom3[i][k]; } 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 AtomVecAngle::unpack_restart(double *buf) { int k; 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++]; molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } num_angle[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_angle[nlocal]; k++) { angle_type[nlocal][k] = static_cast (buf[m++]); angle_atom1[nlocal][k] = static_cast (buf[m++]); angle_atom2[nlocal][k] = static_cast (buf[m++]); angle_atom3[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecAngle::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; molecule[nlocal] = 0; num_bond[nlocal] = 0; num_angle[nlocal] = 0; nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecAngle::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"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type 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; num_bond[nlocal] = 0; num_angle[nlocal] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecAngle::data_atom_hybrid(int nlocal, char **values) { molecule[nlocal] = atoi(values[0]); num_bond[nlocal] = 0; num_angle[nlocal] = 0; return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecAngle::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = molecule[i]; buf[i][2] = type[i]; buf[i][3] = x[i][0]; buf[i][4] = x[i][1]; buf[i][5] = x[i][2]; buf[i][6] = (image[i] & IMGMASK) - IMGMAX; buf[i][7] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecAngle::pack_data_hybrid(int i, double *buf) { buf[0] = molecule[i]; return 1; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecAngle::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2], buf[i][3],buf[i][4],buf[i][5], (int) buf[i][6],(int) buf[i][7],(int) buf[i][8]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecAngle::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d",(int) buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecAngle::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("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); if (atom->memcheck("special")) bytes += memory->usage(special,nmax,atom->maxspecial); if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax); if (atom->memcheck("bond_type")) bytes += memory->usage(bond_type,nmax,atom->bond_per_atom); if (atom->memcheck("bond_atom")) bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom); if (atom->memcheck("num_angle")) bytes += memory->usage(num_angle,nmax); if (atom->memcheck("angle_type")) bytes += memory->usage(angle_type,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom1")) bytes += memory->usage(angle_atom1,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom2")) bytes += memory->usage(angle_atom2,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom3")) bytes += memory->usage(angle_atom3,nmax,atom->angle_per_atom); return bytes; } diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp index 6f4ff6048..377c552ee 100644 --- a/src/MOLECULE/atom_vec_bond.cpp +++ b/src/MOLECULE/atom_vec_bond.cpp @@ -1,864 +1,862 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_bond.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecBond::AtomVecBond(LAMMPS *lmp) : AtomVec(lmp) { molecular = 1; bonds_allow = 1; mass_type = 1; comm_x_only = comm_f_only = 1; size_forward = 3; size_reverse = 3; size_border = 7; size_velocity = 3; size_data_atom = 6; size_data_vel = 4; xcol_data = 4; atom->molecule_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecBond::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"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial"); special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special"); num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond"); bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom, "atom:bond_type"); bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom, "atom:bond_atom"); 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 AtomVecBond::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; molecule = atom->molecule; nspecial = atom->nspecial; special = atom->special; num_bond = atom->num_bond; bond_type = atom->bond_type; bond_atom = atom->bond_atom; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecBond::copy(int i, int j, int delflag) { int k; 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]; molecule[j] = molecule[i]; num_bond[j] = num_bond[i]; for (k = 0; k < num_bond[j]; k++) { bond_type[j][k] = bond_type[i][k]; bond_atom[j][k] = bond_atom[i][k]; } nspecial[j][0] = nspecial[i][0]; nspecial[j][1] = nspecial[i][1]; nspecial[j][2] = nspecial[i][2]; for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecBond::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecBond::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; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecBond::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; } } /* ---------------------------------------------------------------------- */ void AtomVecBond::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecBond::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecBond::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecBond::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = molecule[j]; } } 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]; buf[m++] = molecule[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecBond::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; 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]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = molecule[j]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecBond::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = molecule[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecBond::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); molecule[i] = static_cast (buf[m++]); } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecBond::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); molecule[i] = static_cast (buf[m++]); v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecBond::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) molecule[i] = static_cast (buf[m++]); 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 AtomVecBond::pack_exchange(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = bond_type[i][k]; buf[m++] = bond_atom[i][k]; } buf[m++] = nspecial[i][0]; buf[m++] = nspecial[i][1]; buf[m++] = nspecial[i][2]; for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; 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 AtomVecBond::unpack_exchange(double *buf) { int k; 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++]); molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = static_cast (buf[m++]); nspecial[nlocal][1] = static_cast (buf[m++]); nspecial[nlocal][2] = static_cast (buf[m++]); for (k = 0; k < nspecial[nlocal][2]; k++) special[nlocal][k] = static_cast (buf[m++]); 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 AtomVecBond::size_restart() { int i; int nlocal = atom->nlocal; int n = 0; for (i = 0; i < nlocal; i++) n += 13 + 2*num_bond[i]; 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 AtomVecBond::pack_restart(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = MAX(bond_type[i][k],-bond_type[i][k]); buf[m++] = bond_atom[i][k]; } 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 AtomVecBond::unpack_restart(double *buf) { int k; 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++]; molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecBond::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; molecule[nlocal] = 0; num_bond[nlocal] = 0; nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecBond::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"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type 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; num_bond[nlocal] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecBond::data_atom_hybrid(int nlocal, char **values) { molecule[nlocal] = atoi(values[0]); num_bond[nlocal] = 0; return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecBond::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = molecule[i]; buf[i][2] = type[i]; buf[i][3] = x[i][0]; buf[i][4] = x[i][1]; buf[i][5] = x[i][2]; buf[i][6] = (image[i] & IMGMASK) - IMGMAX; buf[i][7] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecBond::pack_data_hybrid(int i, double *buf) { buf[0] = molecule[i]; return 1; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecBond::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2], buf[i][3],buf[i][4],buf[i][5], (int) buf[i][6],(int) buf[i][7],(int) buf[i][8]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecBond::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d",(int) buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecBond::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("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); if (atom->memcheck("special")) bytes += memory->usage(special,nmax,atom->maxspecial); if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax); if (atom->memcheck("bond_type")) bytes += memory->usage(bond_type,nmax,atom->bond_per_atom); if (atom->memcheck("bond_atom")) bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom); return bytes; } diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp index 268d9cc9e..8f4022bd3 100644 --- a/src/MOLECULE/atom_vec_full.cpp +++ b/src/MOLECULE/atom_vec_full.cpp @@ -1,1113 +1,1111 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_full.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecFull::AtomVecFull(LAMMPS *lmp) : AtomVec(lmp) { molecular = 1; bonds_allow = angles_allow = dihedrals_allow = impropers_allow = 1; mass_type = 1; comm_x_only = comm_f_only = 1; size_forward = 3; size_reverse = 3; size_border = 8; size_velocity = 3; size_data_atom = 7; size_data_vel = 4; xcol_data = 5; atom->molecule_flag = atom->q_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecFull::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"); q = memory->grow(atom->q,nmax,"atom:q"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial"); special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special"); num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond"); bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom, "atom:bond_type"); bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom, "atom:bond_atom"); num_angle = memory->grow(atom->num_angle,nmax,"atom:num_angle"); angle_type = memory->grow(atom->angle_type,nmax,atom->angle_per_atom, "atom:angle_type"); angle_atom1 = memory->grow(atom->angle_atom1,nmax,atom->angle_per_atom, "atom:angle_atom1"); angle_atom2 = memory->grow(atom->angle_atom2,nmax,atom->angle_per_atom, "atom:angle_atom2"); angle_atom3 = memory->grow(atom->angle_atom3,nmax,atom->angle_per_atom, "atom:angle_atom3"); num_dihedral = memory->grow(atom->num_dihedral,nmax,"atom:num_dihedral"); dihedral_type = memory->grow(atom->dihedral_type,nmax, atom->dihedral_per_atom,"atom:dihedral_type"); dihedral_atom1 = memory->grow(atom->dihedral_atom1,nmax,atom->dihedral_per_atom, "atom:dihedral_atom1"); dihedral_atom2 = memory->grow(atom->dihedral_atom2,nmax,atom->dihedral_per_atom, "atom:dihedral_atom2"); dihedral_atom3 = memory->grow(atom->dihedral_atom3,nmax,atom->dihedral_per_atom, "atom:dihedral_atom3"); dihedral_atom4 = memory->grow(atom->dihedral_atom4,nmax,atom->dihedral_per_atom, "atom:dihedral_atom4"); num_improper = memory->grow(atom->num_improper,nmax,"atom:num_improper"); improper_type = memory->grow(atom->improper_type,nmax,atom->improper_per_atom, "atom:improper_type"); improper_atom1 = memory->grow(atom->improper_atom1,nmax,atom->improper_per_atom, "atom:improper_atom1"); improper_atom2 = memory->grow(atom->improper_atom2,nmax,atom->improper_per_atom, "atom:improper_atom2"); improper_atom3 = memory->grow(atom->improper_atom3,nmax,atom->improper_per_atom, "atom:improper_atom3"); improper_atom4 = memory->grow(atom->improper_atom4,nmax,atom->improper_per_atom, "atom:improper_atom4"); 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 AtomVecFull::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; q = atom->q; molecule = atom->molecule; nspecial = atom->nspecial; special = atom->special; num_bond = atom->num_bond; bond_type = atom->bond_type; bond_atom = atom->bond_atom; num_angle = atom->num_angle; angle_type = atom->angle_type; angle_atom1 = atom->angle_atom1; angle_atom2 = atom->angle_atom2; angle_atom3 = atom->angle_atom3; num_dihedral = atom->num_dihedral; dihedral_type = atom->dihedral_type; dihedral_atom1 = atom->dihedral_atom1; dihedral_atom2 = atom->dihedral_atom2; dihedral_atom3 = atom->dihedral_atom3; dihedral_atom4 = atom->dihedral_atom4; num_improper = atom->num_improper; improper_type = atom->improper_type; improper_atom1 = atom->improper_atom1; improper_atom2 = atom->improper_atom2; improper_atom3 = atom->improper_atom3; improper_atom4 = atom->improper_atom4; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecFull::copy(int i, int j, int delflag) { int k; 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]; q[j] = q[i]; molecule[j] = molecule[i]; num_bond[j] = num_bond[i]; for (k = 0; k < num_bond[j]; k++) { bond_type[j][k] = bond_type[i][k]; bond_atom[j][k] = bond_atom[i][k]; } num_angle[j] = num_angle[i]; for (k = 0; k < num_angle[j]; k++) { angle_type[j][k] = angle_type[i][k]; angle_atom1[j][k] = angle_atom1[i][k]; angle_atom2[j][k] = angle_atom2[i][k]; angle_atom3[j][k] = angle_atom3[i][k]; } num_dihedral[j] = num_dihedral[i]; for (k = 0; k < num_dihedral[j]; k++) { dihedral_type[j][k] = dihedral_type[i][k]; dihedral_atom1[j][k] = dihedral_atom1[i][k]; dihedral_atom2[j][k] = dihedral_atom2[i][k]; dihedral_atom3[j][k] = dihedral_atom3[i][k]; dihedral_atom4[j][k] = dihedral_atom4[i][k]; } num_improper[j] = num_improper[i]; for (k = 0; k < num_improper[j]; k++) { improper_type[j][k] = improper_type[i][k]; improper_atom1[j][k] = improper_atom1[i][k]; improper_atom2[j][k] = improper_atom2[i][k]; improper_atom3[j][k] = improper_atom3[i][k]; improper_atom4[j][k] = improper_atom4[i][k]; } nspecial[j][0] = nspecial[i][0]; nspecial[j][1] = nspecial[i][1]; nspecial[j][2] = nspecial[i][2]; for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecFull::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecFull::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; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecFull::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; } } /* ---------------------------------------------------------------------- */ void AtomVecFull::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecFull::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecFull::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecFull::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = q[j]; buf[m++] = molecule[j]; } } 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]; buf[m++] = q[j]; buf[m++] = molecule[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecFull::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; 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]; buf[m++] = q[j]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; buf[m++] = molecule[j]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecFull::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = q[j]; buf[m++] = molecule[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecFull::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; molecule[i] = static_cast (buf[m++]); } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecFull::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; molecule[i] = static_cast (buf[m++]); v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecFull::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { q[i] = buf[m++]; molecule[i] = static_cast (buf[m++]); } 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 AtomVecFull::pack_exchange(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = q[i]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = bond_type[i][k]; buf[m++] = bond_atom[i][k]; } buf[m++] = num_angle[i]; for (k = 0; k < num_angle[i]; k++) { buf[m++] = angle_type[i][k]; buf[m++] = angle_atom1[i][k]; buf[m++] = angle_atom2[i][k]; buf[m++] = angle_atom3[i][k]; } buf[m++] = num_dihedral[i]; for (k = 0; k < num_dihedral[i]; k++) { buf[m++] = dihedral_type[i][k]; buf[m++] = dihedral_atom1[i][k]; buf[m++] = dihedral_atom2[i][k]; buf[m++] = dihedral_atom3[i][k]; buf[m++] = dihedral_atom4[i][k]; } buf[m++] = num_improper[i]; for (k = 0; k < num_improper[i]; k++) { buf[m++] = improper_type[i][k]; buf[m++] = improper_atom1[i][k]; buf[m++] = improper_atom2[i][k]; buf[m++] = improper_atom3[i][k]; buf[m++] = improper_atom4[i][k]; } buf[m++] = nspecial[i][0]; buf[m++] = nspecial[i][1]; buf[m++] = nspecial[i][2]; for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; 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 AtomVecFull::unpack_exchange(double *buf) { int k; 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++]); q[nlocal] = buf[m++]; molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } num_angle[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_angle[nlocal]; k++) { angle_type[nlocal][k] = static_cast (buf[m++]); angle_atom1[nlocal][k] = static_cast (buf[m++]); angle_atom2[nlocal][k] = static_cast (buf[m++]); angle_atom3[nlocal][k] = static_cast (buf[m++]); } num_dihedral[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_dihedral[nlocal]; k++) { dihedral_type[nlocal][k] = static_cast (buf[m++]); dihedral_atom1[nlocal][k] = static_cast (buf[m++]); dihedral_atom2[nlocal][k] = static_cast (buf[m++]); dihedral_atom3[nlocal][k] = static_cast (buf[m++]); dihedral_atom4[nlocal][k] = static_cast (buf[m++]); } num_improper[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_improper[nlocal]; k++) { improper_type[nlocal][k] = static_cast (buf[m++]); improper_atom1[nlocal][k] = static_cast (buf[m++]); improper_atom2[nlocal][k] = static_cast (buf[m++]); improper_atom3[nlocal][k] = static_cast (buf[m++]); improper_atom4[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = static_cast (buf[m++]); nspecial[nlocal][1] = static_cast (buf[m++]); nspecial[nlocal][2] = static_cast (buf[m++]); for (k = 0; k < nspecial[nlocal][2]; k++) special[nlocal][k] = static_cast (buf[m++]); 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 AtomVecFull::size_restart() { int i; int nlocal = atom->nlocal; int n = 0; for (i = 0; i < nlocal; i++) n += 17 + 2*num_bond[i] + 4*num_angle[i] + 5*num_dihedral[i] + 5*num_improper[i]; 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 AtomVecFull::pack_restart(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = q[i]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = MAX(bond_type[i][k],-bond_type[i][k]); buf[m++] = bond_atom[i][k]; } buf[m++] = num_angle[i]; for (k = 0; k < num_angle[i]; k++) { buf[m++] = MAX(angle_type[i][k],-angle_type[i][k]); buf[m++] = angle_atom1[i][k]; buf[m++] = angle_atom2[i][k]; buf[m++] = angle_atom3[i][k]; } buf[m++] = num_dihedral[i]; for (k = 0; k < num_dihedral[i]; k++) { buf[m++] = MAX(dihedral_type[i][k],-dihedral_type[i][k]); buf[m++] = dihedral_atom1[i][k]; buf[m++] = dihedral_atom2[i][k]; buf[m++] = dihedral_atom3[i][k]; buf[m++] = dihedral_atom4[i][k]; } buf[m++] = num_improper[i]; for (k = 0; k < num_improper[i]; k++) { buf[m++] = MAX(improper_type[i][k],-improper_type[i][k]); buf[m++] = improper_atom1[i][k]; buf[m++] = improper_atom2[i][k]; buf[m++] = improper_atom3[i][k]; buf[m++] = improper_atom4[i][k]; } 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 AtomVecFull::unpack_restart(double *buf) { int k; 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++]; q[nlocal] = buf[m++]; molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } num_angle[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_angle[nlocal]; k++) { angle_type[nlocal][k] = static_cast (buf[m++]); angle_atom1[nlocal][k] = static_cast (buf[m++]); angle_atom2[nlocal][k] = static_cast (buf[m++]); angle_atom3[nlocal][k] = static_cast (buf[m++]); } num_dihedral[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_dihedral[nlocal]; k++) { dihedral_type[nlocal][k] = static_cast (buf[m++]); dihedral_atom1[nlocal][k] = static_cast (buf[m++]); dihedral_atom2[nlocal][k] = static_cast (buf[m++]); dihedral_atom3[nlocal][k] = static_cast (buf[m++]); dihedral_atom4[nlocal][k] = static_cast (buf[m++]); } num_improper[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_improper[nlocal]; k++) { improper_type[nlocal][k] = static_cast (buf[m++]); improper_atom1[nlocal][k] = static_cast (buf[m++]); improper_atom2[nlocal][k] = static_cast (buf[m++]); improper_atom3[nlocal][k] = static_cast (buf[m++]); improper_atom4[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecFull::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; q[nlocal] = 0.0; molecule[nlocal] = 0; num_bond[nlocal] = 0; num_angle[nlocal] = 0; num_dihedral[nlocal] = 0; num_improper[nlocal] = 0; nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecFull::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"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type in Atoms section of data file"); q[nlocal] = atof(values[3]); 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; num_bond[nlocal] = 0; num_angle[nlocal] = 0; num_dihedral[nlocal] = 0; num_improper[nlocal] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecFull::data_atom_hybrid(int nlocal, char **values) { molecule[nlocal] = atoi(values[0]); q[nlocal] = atof(values[1]); num_bond[nlocal] = 0; num_angle[nlocal] = 0; num_dihedral[nlocal] = 0; num_improper[nlocal] = 0; return 2; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecFull::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = molecule[i]; buf[i][2] = type[i]; buf[i][3] = q[i]; buf[i][4] = x[i][0]; buf[i][5] = x[i][1]; buf[i][6] = x[i][2]; buf[i][7] = (image[i] & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecFull::pack_data_hybrid(int i, double *buf) { buf[0] = molecule[i]; buf[1] = q[i]; return 2; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecFull::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2], buf[i][3],buf[i][4],buf[i][5],buf[i][6], (int) buf[i][7],(int) buf[i][8],(int) buf[i][9]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecFull::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d %-1.16e",(int) buf[0],buf[1]); return 2; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecFull::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("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); if (atom->memcheck("special")) bytes += memory->usage(special,nmax,atom->maxspecial); if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax); if (atom->memcheck("bond_type")) bytes += memory->usage(bond_type,nmax,atom->bond_per_atom); if (atom->memcheck("bond_atom")) bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom); if (atom->memcheck("num_angle")) bytes += memory->usage(num_angle,nmax); if (atom->memcheck("angle_type")) bytes += memory->usage(angle_type,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom1")) bytes += memory->usage(angle_atom1,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom2")) bytes += memory->usage(angle_atom2,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom3")) bytes += memory->usage(angle_atom3,nmax,atom->angle_per_atom); if (atom->memcheck("num_dihedral")) bytes += memory->usage(num_dihedral,nmax); if (atom->memcheck("dihedral_type")) bytes += memory->usage(dihedral_type,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom1")) bytes += memory->usage(dihedral_atom1,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom2")) bytes += memory->usage(dihedral_atom2,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom3")) bytes += memory->usage(dihedral_atom3,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom4")) bytes += memory->usage(dihedral_atom4,nmax,atom->dihedral_per_atom); if (atom->memcheck("num_improper")) bytes += memory->usage(num_improper,nmax); if (atom->memcheck("improper_type")) bytes += memory->usage(improper_type,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom1")) bytes += memory->usage(improper_atom1,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom2")) bytes += memory->usage(improper_atom2,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom3")) bytes += memory->usage(improper_atom3,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom4")) bytes += memory->usage(improper_atom4,nmax,atom->improper_per_atom); return bytes; } diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp index 9ee77a0f2..57e275f04 100644 --- a/src/MOLECULE/atom_vec_molecular.cpp +++ b/src/MOLECULE/atom_vec_molecular.cpp @@ -1,1090 +1,1088 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_molecular.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecMolecular::AtomVecMolecular(LAMMPS *lmp) : AtomVec(lmp) { molecular = 1; bonds_allow = angles_allow = dihedrals_allow = impropers_allow = 1; mass_type = 1; comm_x_only = comm_f_only = 1; size_forward = 3; size_reverse = 3; size_border = 7; size_velocity = 3; size_data_atom = 6; size_data_vel = 4; xcol_data = 4; atom->molecule_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecMolecular::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"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial"); special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special"); num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond"); bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom, "atom:bond_type"); bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom, "atom:bond_atom"); num_angle = memory->grow(atom->num_angle,nmax,"atom:num_angle"); angle_type = memory->grow(atom->angle_type,nmax,atom->angle_per_atom, "atom:angle_type"); angle_atom1 = memory->grow(atom->angle_atom1,nmax,atom->angle_per_atom, "atom:angle_atom1"); angle_atom2 = memory->grow(atom->angle_atom2,nmax,atom->angle_per_atom, "atom:angle_atom2"); angle_atom3 = memory->grow(atom->angle_atom3,nmax,atom->angle_per_atom, "atom:angle_atom3"); num_dihedral = memory->grow(atom->num_dihedral,nmax,"atom:num_dihedral"); dihedral_type = memory->grow(atom->dihedral_type,nmax, atom->dihedral_per_atom,"atom:dihedral_type"); dihedral_atom1 = memory->grow(atom->dihedral_atom1,nmax,atom->dihedral_per_atom, "atom:dihedral_atom1"); dihedral_atom2 = memory->grow(atom->dihedral_atom2,nmax,atom->dihedral_per_atom, "atom:dihedral_atom2"); dihedral_atom3 = memory->grow(atom->dihedral_atom3,nmax,atom->dihedral_per_atom, "atom:dihedral_atom3"); dihedral_atom4 = memory->grow(atom->dihedral_atom4,nmax,atom->dihedral_per_atom, "atom:dihedral_atom4"); num_improper = memory->grow(atom->num_improper,nmax,"atom:num_improper"); improper_type = memory->grow(atom->improper_type,nmax,atom->improper_per_atom, "atom:improper_type"); improper_atom1 = memory->grow(atom->improper_atom1,nmax,atom->improper_per_atom, "atom:improper_atom1"); improper_atom2 = memory->grow(atom->improper_atom2,nmax,atom->improper_per_atom, "atom:improper_atom2"); improper_atom3 = memory->grow(atom->improper_atom3,nmax,atom->improper_per_atom, "atom:improper_atom3"); improper_atom4 = memory->grow(atom->improper_atom4,nmax,atom->improper_per_atom, "atom:improper_atom4"); 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 AtomVecMolecular::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; molecule = atom->molecule; nspecial = atom->nspecial; special = atom->special; num_bond = atom->num_bond; bond_type = atom->bond_type; bond_atom = atom->bond_atom; num_angle = atom->num_angle; angle_type = atom->angle_type; angle_atom1 = atom->angle_atom1; angle_atom2 = atom->angle_atom2; angle_atom3 = atom->angle_atom3; num_dihedral = atom->num_dihedral; dihedral_type = atom->dihedral_type; dihedral_atom1 = atom->dihedral_atom1; dihedral_atom2 = atom->dihedral_atom2; dihedral_atom3 = atom->dihedral_atom3; dihedral_atom4 = atom->dihedral_atom4; num_improper = atom->num_improper; improper_type = atom->improper_type; improper_atom1 = atom->improper_atom1; improper_atom2 = atom->improper_atom2; improper_atom3 = atom->improper_atom3; improper_atom4 = atom->improper_atom4; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecMolecular::copy(int i, int j, int delflag) { int k; 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]; molecule[j] = molecule[i]; num_bond[j] = num_bond[i]; for (k = 0; k < num_bond[j]; k++) { bond_type[j][k] = bond_type[i][k]; bond_atom[j][k] = bond_atom[i][k]; } num_angle[j] = num_angle[i]; for (k = 0; k < num_angle[j]; k++) { angle_type[j][k] = angle_type[i][k]; angle_atom1[j][k] = angle_atom1[i][k]; angle_atom2[j][k] = angle_atom2[i][k]; angle_atom3[j][k] = angle_atom3[i][k]; } num_dihedral[j] = num_dihedral[i]; for (k = 0; k < num_dihedral[j]; k++) { dihedral_type[j][k] = dihedral_type[i][k]; dihedral_atom1[j][k] = dihedral_atom1[i][k]; dihedral_atom2[j][k] = dihedral_atom2[i][k]; dihedral_atom3[j][k] = dihedral_atom3[i][k]; dihedral_atom4[j][k] = dihedral_atom4[i][k]; } num_improper[j] = num_improper[i]; for (k = 0; k < num_improper[j]; k++) { improper_type[j][k] = improper_type[i][k]; improper_atom1[j][k] = improper_atom1[i][k]; improper_atom2[j][k] = improper_atom2[i][k]; improper_atom3[j][k] = improper_atom3[i][k]; improper_atom4[j][k] = improper_atom4[i][k]; } nspecial[j][0] = nspecial[i][0]; nspecial[j][1] = nspecial[i][1]; nspecial[j][2] = nspecial[i][2]; for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::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; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecMolecular::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; } } /* ---------------------------------------------------------------------- */ void AtomVecMolecular::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecMolecular::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = molecule[j]; } } 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]; buf[m++] = molecule[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::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; 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]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = molecule[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = molecule[j]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = molecule[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecMolecular::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); molecule[i] = static_cast (buf[m++]); } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecMolecular::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); molecule[i] = static_cast (buf[m++]); v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecMolecular::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) molecule[i] = static_cast (buf[m++]); 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 AtomVecMolecular::pack_exchange(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = bond_type[i][k]; buf[m++] = bond_atom[i][k]; } buf[m++] = num_angle[i]; for (k = 0; k < num_angle[i]; k++) { buf[m++] = angle_type[i][k]; buf[m++] = angle_atom1[i][k]; buf[m++] = angle_atom2[i][k]; buf[m++] = angle_atom3[i][k]; } buf[m++] = num_dihedral[i]; for (k = 0; k < num_dihedral[i]; k++) { buf[m++] = dihedral_type[i][k]; buf[m++] = dihedral_atom1[i][k]; buf[m++] = dihedral_atom2[i][k]; buf[m++] = dihedral_atom3[i][k]; buf[m++] = dihedral_atom4[i][k]; } buf[m++] = num_improper[i]; for (k = 0; k < num_improper[i]; k++) { buf[m++] = improper_type[i][k]; buf[m++] = improper_atom1[i][k]; buf[m++] = improper_atom2[i][k]; buf[m++] = improper_atom3[i][k]; buf[m++] = improper_atom4[i][k]; } buf[m++] = nspecial[i][0]; buf[m++] = nspecial[i][1]; buf[m++] = nspecial[i][2]; for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k]; 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 AtomVecMolecular::unpack_exchange(double *buf) { int k; 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++]); molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } num_angle[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_angle[nlocal]; k++) { angle_type[nlocal][k] = static_cast (buf[m++]); angle_atom1[nlocal][k] = static_cast (buf[m++]); angle_atom2[nlocal][k] = static_cast (buf[m++]); angle_atom3[nlocal][k] = static_cast (buf[m++]); } num_dihedral[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_dihedral[nlocal]; k++) { dihedral_type[nlocal][k] = static_cast (buf[m++]); dihedral_atom1[nlocal][k] = static_cast (buf[m++]); dihedral_atom2[nlocal][k] = static_cast (buf[m++]); dihedral_atom3[nlocal][k] = static_cast (buf[m++]); dihedral_atom4[nlocal][k] = static_cast (buf[m++]); } num_improper[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_improper[nlocal]; k++) { improper_type[nlocal][k] = static_cast (buf[m++]); improper_atom1[nlocal][k] = static_cast (buf[m++]); improper_atom2[nlocal][k] = static_cast (buf[m++]); improper_atom3[nlocal][k] = static_cast (buf[m++]); improper_atom4[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = static_cast (buf[m++]); nspecial[nlocal][1] = static_cast (buf[m++]); nspecial[nlocal][2] = static_cast (buf[m++]); for (k = 0; k < nspecial[nlocal][2]; k++) special[nlocal][k] = static_cast (buf[m++]); 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 AtomVecMolecular::size_restart() { int i; int nlocal = atom->nlocal; int n = 0; for (i = 0; i < nlocal; i++) n += 16 + 2*num_bond[i] + 4*num_angle[i] + 5*num_dihedral[i] + 5*num_improper[i]; 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 AtomVecMolecular::pack_restart(int i, double *buf) { int k; 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = molecule[i]; buf[m++] = num_bond[i]; for (k = 0; k < num_bond[i]; k++) { buf[m++] = MAX(bond_type[i][k],-bond_type[i][k]); buf[m++] = bond_atom[i][k]; } buf[m++] = num_angle[i]; for (k = 0; k < num_angle[i]; k++) { buf[m++] = MAX(angle_type[i][k],-angle_type[i][k]); buf[m++] = angle_atom1[i][k]; buf[m++] = angle_atom2[i][k]; buf[m++] = angle_atom3[i][k]; } buf[m++] = num_dihedral[i]; for (k = 0; k < num_dihedral[i]; k++) { buf[m++] = MAX(dihedral_type[i][k],-dihedral_type[i][k]); buf[m++] = dihedral_atom1[i][k]; buf[m++] = dihedral_atom2[i][k]; buf[m++] = dihedral_atom3[i][k]; buf[m++] = dihedral_atom4[i][k]; } buf[m++] = num_improper[i]; for (k = 0; k < num_improper[i]; k++) { buf[m++] = MAX(improper_type[i][k],-improper_type[i][k]); buf[m++] = improper_atom1[i][k]; buf[m++] = improper_atom2[i][k]; buf[m++] = improper_atom3[i][k]; buf[m++] = improper_atom4[i][k]; } 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 AtomVecMolecular::unpack_restart(double *buf) { int k; 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++]; molecule[nlocal] = static_cast (buf[m++]); num_bond[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_bond[nlocal]; k++) { bond_type[nlocal][k] = static_cast (buf[m++]); bond_atom[nlocal][k] = static_cast (buf[m++]); } num_angle[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_angle[nlocal]; k++) { angle_type[nlocal][k] = static_cast (buf[m++]); angle_atom1[nlocal][k] = static_cast (buf[m++]); angle_atom2[nlocal][k] = static_cast (buf[m++]); angle_atom3[nlocal][k] = static_cast (buf[m++]); } num_dihedral[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_dihedral[nlocal]; k++) { dihedral_type[nlocal][k] = static_cast (buf[m++]); dihedral_atom1[nlocal][k] = static_cast (buf[m++]); dihedral_atom2[nlocal][k] = static_cast (buf[m++]); dihedral_atom3[nlocal][k] = static_cast (buf[m++]); dihedral_atom4[nlocal][k] = static_cast (buf[m++]); } num_improper[nlocal] = static_cast (buf[m++]); for (k = 0; k < num_improper[nlocal]; k++) { improper_type[nlocal][k] = static_cast (buf[m++]); improper_atom1[nlocal][k] = static_cast (buf[m++]); improper_atom2[nlocal][k] = static_cast (buf[m++]); improper_atom3[nlocal][k] = static_cast (buf[m++]); improper_atom4[nlocal][k] = static_cast (buf[m++]); } nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecMolecular::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; molecule[nlocal] = 0; num_bond[nlocal] = 0; num_angle[nlocal] = 0; num_dihedral[nlocal] = 0; num_improper[nlocal] = 0; nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecMolecular::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"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type 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; num_bond[nlocal] = 0; num_angle[nlocal] = 0; num_dihedral[nlocal] = 0; num_improper[nlocal] = 0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecMolecular::data_atom_hybrid(int nlocal, char **values) { molecule[nlocal] = atoi(values[0]); num_bond[nlocal] = 0; num_angle[nlocal] = 0; num_dihedral[nlocal] = 0; num_improper[nlocal] = 0; return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecMolecular::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = molecule[i]; buf[i][2] = type[i]; buf[i][3] = x[i][0]; buf[i][4] = x[i][1]; buf[i][5] = x[i][2]; buf[i][6] = (image[i] & IMGMASK) - IMGMAX; buf[i][7] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecMolecular::pack_data_hybrid(int i, double *buf) { buf[0] = molecule[i]; return 1; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecMolecular::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2], buf[i][3],buf[i][4],buf[i][5], (int) buf[i][6],(int) buf[i][7],(int) buf[i][8]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecMolecular::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d",(int) buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecMolecular::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("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3); if (atom->memcheck("special")) bytes += memory->usage(special,nmax,atom->maxspecial); if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax); if (atom->memcheck("bond_type")) bytes += memory->usage(bond_type,nmax,atom->bond_per_atom); if (atom->memcheck("bond_atom")) bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom); if (atom->memcheck("num_angle")) bytes += memory->usage(num_angle,nmax); if (atom->memcheck("angle_type")) bytes += memory->usage(angle_type,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom1")) bytes += memory->usage(angle_atom1,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom2")) bytes += memory->usage(angle_atom2,nmax,atom->angle_per_atom); if (atom->memcheck("angle_atom3")) bytes += memory->usage(angle_atom3,nmax,atom->angle_per_atom); if (atom->memcheck("num_dihedral")) bytes += memory->usage(num_dihedral,nmax); if (atom->memcheck("dihedral_type")) bytes += memory->usage(dihedral_type,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom1")) bytes += memory->usage(dihedral_atom1,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom2")) bytes += memory->usage(dihedral_atom2,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom3")) bytes += memory->usage(dihedral_atom3,nmax,atom->dihedral_per_atom); if (atom->memcheck("dihedral_atom4")) bytes += memory->usage(dihedral_atom4,nmax,atom->dihedral_per_atom); if (atom->memcheck("num_improper")) bytes += memory->usage(num_improper,nmax); if (atom->memcheck("improper_type")) bytes += memory->usage(improper_type,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom1")) bytes += memory->usage(improper_atom1,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom2")) bytes += memory->usage(improper_atom2,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom3")) bytes += memory->usage(improper_atom3,nmax,atom->improper_per_atom); if (atom->memcheck("improper_atom4")) bytes += memory->usage(improper_atom4,nmax,atom->improper_per_atom); return bytes; } diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp index 9d8c6a74d..6f3a9d627 100644 --- a/src/PERI/atom_vec_peri.cpp +++ b/src/PERI/atom_vec_peri.cpp @@ -1,925 +1,923 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Mike Parks (SNL) ------------------------------------------------------------------------- */ #include "float.h" #include "stdlib.h" #include "atom_vec_peri.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "citeme.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 static const char cite_peri_package[] = "PERI package for Peridynamics:\n\n" "@Article{Parks08,\n" " author = {M. L. Parks, R. B. Lehoucq, S. J. Plimpton, S. A. Silling},\n" " title = {Implementing peridynamics within a molecular dynamics code},\n" " journal = {Comp.~Phys.~Comm.},\n" " year = 2008,\n" " volume = 179,\n" " pages = {777--783}\n" "}\n\n"; /* ---------------------------------------------------------------------- */ AtomVecPeri::AtomVecPeri(LAMMPS *lmp) : AtomVec(lmp) { if (lmp->citeme) lmp->citeme->add(cite_peri_package); molecular = 0; comm_x_only = 0; comm_f_only = 1; size_forward = 4; size_reverse = 3; size_border = 11; size_velocity = 3; size_data_atom = 7; size_data_vel = 4; xcol_data = 5; atom->peri_flag = 1; atom->vfrac_flag = atom->rmass_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecPeri::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"); vfrac = memory->grow(atom->vfrac,nmax,"atom:vfrac"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); s0 = memory->grow(atom->s0,nmax,"atom:s0"); x0 = memory->grow(atom->x0,nmax,3,"atom:x0"); 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 AtomVecPeri::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; vfrac = atom->vfrac; rmass = atom->rmass; s0 = atom->s0; x0 = atom->x0; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecPeri::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]; vfrac[j] = vfrac[i]; rmass[j] = rmass[i]; s0[j] = s0[i]; x0[j][0] = x0[i][0]; x0[j][1] = x0[i][1]; x0[j][2] = x0[i][2]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecPeri::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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++] = s0[j]; } } 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; buf[m++] = s0[j]; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecPeri::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; 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++] = s0[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = s0[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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++] = s0[j]; 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]; } } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecPeri::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = s0[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecPeri::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; s0[i] = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecPeri::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; s0[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecPeri::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) s0[i] = buf[m++]; return m; } /* ---------------------------------------------------------------------- */ int AtomVecPeri::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecPeri::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecPeri::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = vfrac[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; buf[m++] = x0[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]; } 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]; buf[m++] = vfrac[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; buf[m++] = x0[j][2]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecPeri::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; 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]; buf[m++] = vfrac[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; buf[m++] = x0[j][2]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = vfrac[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; buf[m++] = x0[j][2]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = vfrac[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; buf[m++] = x0[j][2]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecPeri::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = vfrac[j]; buf[m++] = s0[j]; buf[m++] = x0[j][0]; buf[m++] = x0[j][1]; buf[m++] = x0[j][2]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecPeri::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); vfrac[i] = buf[m++]; s0[i] = buf[m++]; x0[i][0] = buf[m++]; x0[i][1] = buf[m++]; x0[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecPeri::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); vfrac[i] = buf[m++]; s0[i] = buf[m++]; x0[i][0] = buf[m++]; x0[i][1] = buf[m++]; x0[i][2] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecPeri::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { vfrac[i] = buf[m++]; s0[i] = buf[m++]; x0[i][0] = buf[m++]; x0[i][1] = buf[m++]; x0[i][2] = buf[m++]; } 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 AtomVecPeri::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = vfrac[i]; buf[m++] = rmass[i]; buf[m++] = s0[i]; buf[m++] = x0[i][0]; buf[m++] = x0[i][1]; buf[m++] = x0[i][2]; 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 AtomVecPeri::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++]); vfrac[nlocal] = buf[m++]; rmass[nlocal] = buf[m++]; s0[nlocal] = buf[m++]; x0[nlocal][0] = buf[m++]; x0[nlocal][1] = buf[m++]; x0[nlocal][2] = buf[m++]; 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 AtomVecPeri::size_restart() { int i; int nlocal = atom->nlocal; int n = 17 * nlocal; 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 AtomVecPeri::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = vfrac[i]; buf[m++] = rmass[i]; buf[m++] = s0[i]; buf[m++] = x0[i][0]; buf[m++] = x0[i][1]; buf[m++] = x0[i][2]; 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 AtomVecPeri::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++]; vfrac[nlocal] = buf[m++]; rmass[nlocal] = buf[m++]; s0[nlocal] = buf[m++]; x0[nlocal][0] = buf[m++]; x0[nlocal][1] = buf[m++]; x0[nlocal][2] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecPeri::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; vfrac[nlocal] = 1.0; rmass[nlocal] = 1.0; s0[nlocal] = DBL_MAX; x0[nlocal][0] = coord[0]; x0[nlocal][1] = coord[1]; x0[nlocal][2] = coord[2]; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecPeri::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"); vfrac[nlocal] = atof(values[2]); rmass[nlocal] = atof(values[3]); if (rmass[nlocal] <= 0.0) error->one(FLERR,"Invalid mass value"); 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; s0[nlocal] = DBL_MAX; x0[nlocal][0] = coord[0]; x0[nlocal][1] = coord[1]; x0[nlocal][2] = coord[2]; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecPeri::data_atom_hybrid(int nlocal, char **values) { vfrac[nlocal] = atof(values[0]); rmass[nlocal] = atof(values[1]); if (rmass[nlocal] <= 0.0) error->one(FLERR,"Invalid mass value"); s0[nlocal] = DBL_MAX; x0[nlocal][0] = x[nlocal][0]; x0[nlocal][1] = x[nlocal][1]; x0[nlocal][2] = x[nlocal][2]; return 2; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecPeri::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = vfrac[i]; buf[i][3] = rmass[i]; buf[i][4] = x[i][0]; buf[i][5] = x[i][1]; buf[i][6] = x[i][2]; buf[i][7] = (image[i] & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecPeri::pack_data_hybrid(int i, double *buf) { buf[0] = vfrac[i]; buf[1] = rmass[i]; return 2; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecPeri::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1], buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6], (int) buf[i][7],(int) buf[i][8],(int) buf[i][9]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecPeri::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e",buf[0],buf[1]); return 2; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecPeri::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("vfrac")) bytes += memory->usage(vfrac,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("s0")) bytes += memory->usage(s0,nmax); if (atom->memcheck("x0")) bytes += memory->usage(x0,nmax,3); return bytes; } diff --git a/src/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp index 87f522647..e2354b5bb 100644 --- a/src/USER-AWPMD/atom_vec_wavepacket.cpp +++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp @@ -1,1144 +1,1142 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Ilya Valuev (JIHT, Moscow, Russia) ------------------------------------------------------------------------- */ #include "math.h" #include "stdlib.h" #include "atom_vec_wavepacket.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 /* ---------------------------------------------------------------------- */ AtomVecWavepacket::AtomVecWavepacket(LAMMPS *lmp) : AtomVec(lmp) { comm_x_only = comm_f_only = 0; mass_type = 1; molecular = 0; size_forward = 4; // coords[3]+radius[1] size_reverse = 10; // force[3]+erforce[1]+ervelforce[1]+vforce[3]+csforce[2] size_border = 10; // coords[3]+tag[1]+type[1]+mask[1]+q[1]+spin[1]+eradius[1]+etag[1] size_velocity = 6; // +velocities[3]+ ervel[1]+cs[2] size_data_atom = 11; // for input file: 1-tag 2-type 3-q 4-spin 5-eradius 6-etag 7-cs_re 8-cs_im 9-x 10-y 11-z size_data_vel = 5; // for input file: vx vy vz ervel xcol_data = 9; // starting column for x data atom->wavepacket_flag = 1; atom->electron_flag = 1; // compatible with eff atom->q_flag = atom->spin_flag = atom->eradius_flag = atom->ervel_flag = atom->erforce_flag = 1; atom->cs_flag = atom->csforce_flag = atom->vforce_flag = atom->ervelforce_flag = atom->etag_flag = 1; } /* ---------------------------------------------------------------------- grow atom-electron arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecWavepacket::grow(int n) { if (n == 0) nmax += DELTA; else nmax = n; atom->nmax = nmax; 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"); q = memory->grow(atom->q,nmax,"atom:q"); spin = memory->grow(atom->spin,nmax,"atom:spin"); eradius = memory->grow(atom->eradius,nmax,"atom:eradius"); ervel = memory->grow(atom->ervel,nmax,"atom:ervel"); erforce = memory->grow(atom->erforce,nmax*comm->nthreads,"atom:erforce"); cs = memory->grow(atom->cs,2*nmax,"atom:cs"); csforce = memory->grow(atom->csforce,2*nmax,"atom:csforce"); vforce = memory->grow(atom->vforce,3*nmax,"atom:vforce"); ervelforce = memory->grow(atom->ervelforce,nmax,"atom:ervelforce"); etag = memory->grow(atom->etag,nmax,"atom:etag"); 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 AtomVecWavepacket::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; q = atom->q; eradius = atom->eradius; ervel = atom->ervel; erforce = atom->erforce; cs = atom->cs; csforce = atom->csforce; vforce = atom->vforce; ervelforce = atom->ervelforce; etag = atom->etag; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecWavepacket::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]; q[j] = q[i]; spin[j] = spin[i]; eradius[j] = eradius[i]; ervel[j] = ervel[i]; cs[2*j] = cs[2*i]; cs[2*j+1] = cs[2*i+1]; etag[j] = etag[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ // this will be used as partial pack for unsplit Hartree packets (v, ervel not regarded as separate variables) int AtomVecWavepacket::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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++] = eradius[j]; } } 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; buf[m++] = eradius[j]; } } return m; } /* ---------------------------------------------------------------------- */ // this is a complete pack of all 'position' variables of AWPMD int AtomVecWavepacket::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; 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++] = eradius[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } } 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; buf[m++] = eradius[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } } 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++] = eradius[j]; 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++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = eradius[j]; buf[m++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecWavepacket::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; eradius[i] = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecWavepacket::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; eradius[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; ervel[i] = buf[m++]; cs[2*i] = buf[m++]; cs[2*i+1] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++){ eradius[i] = buf[m++]; ervel[i] = buf[m++]; cs[2*i] = buf[m++]; cs[2*i+1] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::pack_reverse(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { //10 buf[m++] = f[i][0]; buf[m++] = f[i][1]; buf[m++] = f[i][2]; buf[m++] = erforce[i]; buf[m++] = ervelforce[i]; buf[m++] = vforce[3*i]; buf[m++] = vforce[3*i+1]; buf[m++] = vforce[3*i+2]; buf[m++] = csforce[2*i]; buf[m++] = csforce[2*i+1]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::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++] = erforce[i]; buf[m++] = ervelforce[i]; buf[m++] = vforce[3*i]; buf[m++] = vforce[3*i+1]; buf[m++] = vforce[3*i+2]; buf[m++] = csforce[2*i]; buf[m++] = csforce[2*i+1]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecWavepacket::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++]; erforce[j] += buf[m++]; ervelforce[j] += buf[m++]; vforce[3*j] += buf[m++]; vforce[3*j+1] += buf[m++]; vforce[3*j+2] += buf[m++]; csforce[2*j] += buf[m++]; csforce[2*j+1] += buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::unpack_reverse_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; erforce[j] += buf[m++]; ervelforce[j] += buf[m++]; vforce[3*j] += buf[m++]; vforce[3*j+1] += buf[m++]; vforce[3*j+2] += buf[m++]; csforce[2*j] += buf[m++]; csforce[2*j+1] += buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ // will be used for Hartree unsplit version (the etag is added however) int AtomVecWavepacket::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = etag[j]; } } 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = etag[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::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; 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = etag[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } } 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 (domain->triclinic == 0) { 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = etag[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } } 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = etag[j]; 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++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = etag[j]; buf[m++] = ervel[j]; buf[m++] = cs[2*j]; buf[m++] = cs[2*j+1]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecWavepacket::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; spin[i] = static_cast (buf[m++]); eradius[i] = buf[m++]; etag[i] = (int)buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecWavepacket::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; spin[i] = static_cast (buf[m++]); eradius[i] = buf[m++]; etag[i] = (int)buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; ervel[i] = buf[m++]; cs[2*i] = buf[m++]; cs[2*i+1] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecWavepacket::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { q[i] = buf[m++]; spin[i] = static_cast (buf[m++]); eradius[i] = buf[m++]; etag[i] = (int)buf[m++]; ervel[i] = buf[m++]; cs[2*i] = buf[m++]; cs[2*i+1] = buf[m++]; } 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 AtomVecWavepacket::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = q[i]; buf[m++] = spin[i]; buf[m++] = eradius[i]; buf[m++] = ervel[i]; buf[m++] = etag[i]; buf[m++] = cs[2*i]; buf[m++] = cs[2*i+1]; 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 AtomVecWavepacket::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++]); q[nlocal] = buf[m++]; spin[nlocal] = static_cast (buf[m++]); eradius[nlocal] = buf[m++]; ervel[nlocal] = buf[m++]; etag[nlocal] = buf[m++]; cs[2*nlocal] = buf[m++]; cs[2*nlocal+1] = buf[m++]; 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 AtomVecWavepacket::size_restart() { int i; int nlocal = atom->nlocal; int n = 18 * nlocal; // Associated with pack_restart 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 AtomVecWavepacket::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = q[i]; buf[m++] = spin[i]; buf[m++] = eradius[i]; buf[m++] = ervel[i]; buf[m++] = etag[i]; buf[m++] = cs[2*i]; buf[m++] = cs[2*i+1]; 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 AtomVecWavepacket::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++]; q[nlocal] = buf[m++]; spin[nlocal] = static_cast (buf[m++]); eradius[nlocal] = buf[m++]; ervel[nlocal] = buf[m++]; etag[nlocal] = buf[m++]; cs[2*nlocal] = buf[m++]; cs[2*nlocal+1] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults AWPMD: creates a proton ------------------------------------------------------------------------- */ void AtomVecWavepacket::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; q[nlocal] = 1.; spin[nlocal] = 0.; eradius[nlocal] = 0.0; ervel[nlocal] = 0.0; etag[nlocal]= 0.; cs[2*nlocal] = 0.; cs[2*nlocal+1] = 0.; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities AWPMD: 0-tag 1-type 2-q 3-spin 4-eradius 5-etag 6-cs_re 7-cs_im ------------------------------------------------------------------------- */ void AtomVecWavepacket::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 (ID tag must be >0)"); 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"); q[nlocal] = atof(values[2]); spin[nlocal] = atoi(values[3]); eradius[nlocal] = atof(values[4]); if (eradius[nlocal] < 0.0) error->one(FLERR,"Invalid eradius in Atoms section of data file"); etag[nlocal] = atoi(values[5]); cs[2*nlocal] = atoi(values[6]); cs[2*nlocal+1] = atof(values[7]); 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; ervel[nlocal] = 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 AtomVecWavepacket::data_atom_hybrid(int nlocal, char **values) { q[nlocal] = atof(values[0]); spin[nlocal] = atoi(values[1]); eradius[nlocal] = atof(values[2]); if (eradius[nlocal] < 0.0) error->one(FLERR,"Invalid eradius in Atoms section of data file"); etag[nlocal] = atoi(values[3]); cs[2*nlocal] = atoi(values[4]); cs[2*nlocal+1] = atof(values[5]); v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; v[nlocal][2] = 0.0; ervel[nlocal] = 0.0; return 3; } /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ void AtomVecWavepacket::data_vel(int m, char **values) { v[m][0] = atof(values[0]); v[m][1] = atof(values[1]); v[m][2] = atof(values[2]); ervel[m] = atof(values[3]); } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Velocities section of data file ------------------------------------------------------------------------- */ int AtomVecWavepacket::data_vel_hybrid(int m, char **values) { ervel[m] = atof(values[0]); return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecWavepacket::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = q[i]; buf[i][3] = spin[i]; buf[i][4] = eradius[i]; buf[i][5] = etag[i]; buf[i][6] = cs[2*i]; buf[i][7] = cs[2*i+1]; buf[i][8] = x[i][0]; buf[i][9] = x[i][1]; buf[i][10] = x[i][2]; buf[i][11] = (image[i] & IMGMASK) - IMGMAX; buf[i][12] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][13] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecWavepacket::pack_data_hybrid(int i, double *buf) { buf[0] = q[i]; buf[1] = spin[i]; buf[2] = eradius[i]; buf[3] = etag[i]; buf[4] = cs[2*i]; buf[5] = cs[2*i+1]; return 6; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecWavepacket::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %d %-1.16e %d %-1.16e %-1.16e %-1.16e " "%-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1], buf[i][2],(int) buf[i][3],buf[i][4], (int) buf[i][5],buf[i][6],buf[i][7], buf[i][8],buf[i][9],buf[i][10], (int) buf[i][11],(int) buf[i][12],(int) buf[i][13]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecWavepacket::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %d %-1.16e %d %-1.16e %-1.16e", buf[0],(int) buf[1],buf[2],(int) buf[3],buf[4],buf[5]); return 6; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecWavepacket::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = ervel[i]; } } /* ---------------------------------------------------------------------- pack hybrid velocity info for data file ------------------------------------------------------------------------- */ int AtomVecWavepacket::pack_vel_hybrid(int i, double *buf) { buf[0] = ervel[i]; return 1; } /* ---------------------------------------------------------------------- write velocity info to data file ------------------------------------------------------------------------- */ void AtomVecWavepacket::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e\n", (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3],buf[i][4]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecWavepacket::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e",buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecWavepacket::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("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax); if (atom->memcheck("eradius")) bytes += memory->usage(eradius,nmax); if (atom->memcheck("ervel")) bytes += memory->usage(ervel,nmax); if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax*comm->nthreads); if (atom->memcheck("ervelforce")) bytes += memory->usage(ervelforce,nmax); if (atom->memcheck("cs")) bytes += memory->usage(cs,2*nmax); if (atom->memcheck("csforce")) bytes += memory->usage(csforce,2*nmax); if (atom->memcheck("vforce")) bytes += memory->usage(vforce,3*nmax); if (atom->memcheck("etag")) bytes += memory->usage(etag,nmax); return bytes; } diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp index e861414ef..f78263b3f 100644 --- a/src/USER-EFF/atom_vec_electron.cpp +++ b/src/USER-EFF/atom_vec_electron.cpp @@ -1,997 +1,995 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Andres Jaramillo-Botero (Caltech) ------------------------------------------------------------------------- */ #include "math.h" #include "stdlib.h" #include "atom_vec_electron.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "force.h" #include "fix.h" #include "citeme.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 static const char cite_user_eff_package[] = "USER-EFF package:\n\n" "@Article{Jaramillo-Botero11,\n" " author = {A. Jaramillo-Botero, J. Su, A. Qi, W. A. Goddard III},\n" " title = {Large-Scale, Long-Term Nonadiabatic Electron Molecular Dynamics for Describing Material Properties and Phenomena in Extreme Environments},\n" " journal = {J.~Comp.~Chem.},\n" " year = 2011,\n" " volume = 32,\n" " pages = {497--512}\n" "}\n\n"; /* ---------------------------------------------------------------------- */ AtomVecElectron::AtomVecElectron(LAMMPS *lmp) : AtomVec(lmp) { if (lmp->citeme) lmp->citeme->add(cite_user_eff_package); comm_x_only = comm_f_only = 0; mass_type = 1; molecular = 0; size_forward = 4; size_reverse = 4; size_border = 9; size_velocity = 3; size_data_atom = 8; size_data_vel = 5; xcol_data = 6; atom->ecp_flag = 0; atom->electron_flag = 1; atom->q_flag = atom->spin_flag = atom->eradius_flag = atom->ervel_flag = atom->erforce_flag = 1; } /* ---------------------------------------------------------------------- grow atom-electron arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecElectron::grow(int n) { if (n == 0) nmax += DELTA; else nmax = n; atom->nmax = nmax; 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"); q = memory->grow(atom->q,nmax,"atom:q"); spin = memory->grow(atom->spin,nmax,"atom:spin"); eradius = memory->grow(atom->eradius,nmax,"atom:eradius"); ervel = memory->grow(atom->ervel,nmax,"atom:ervel"); erforce = memory->grow(atom->erforce,nmax*comm->nthreads,"atom:erforce"); 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 AtomVecElectron::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; q = atom->q; eradius = atom->eradius; ervel = atom->ervel; erforce = atom->erforce; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecElectron::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]; q[j] = q[i]; spin[j] = spin[i]; eradius[j] = eradius[i]; ervel[j] = ervel[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecElectron::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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++] = eradius[j]; } } 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; buf[m++] = eradius[j]; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::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; 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++] = eradius[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = eradius[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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++] = eradius[j]; 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]; } } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = eradius[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecElectron::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; eradius[i] = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecElectron::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; eradius[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecElectron::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) eradius[i] = buf[m++]; return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::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++] = erforce[i]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::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++] = erforce[i]; return m; } /* ---------------------------------------------------------------------- */ void AtomVecElectron::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++]; erforce[j] += buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecElectron::unpack_reverse_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; erforce[j] += buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; } } 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::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; 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (domain->triclinic == 0) { 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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecElectron::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = q[j]; buf[m++] = spin[j]; buf[m++] = eradius[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecElectron::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; spin[i] = static_cast (buf[m++]); eradius[i] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecElectron::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; spin[i] = static_cast (buf[m++]); eradius[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecElectron::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { q[i] = buf[m++]; spin[i] = static_cast (buf[m++]); eradius[i] = buf[m++]; } 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 AtomVecElectron::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = q[i]; buf[m++] = spin[i]; buf[m++] = eradius[i]; buf[m++] = ervel[i]; 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 AtomVecElectron::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++]); q[nlocal] = buf[m++]; spin[nlocal] = static_cast (buf[m++]); eradius[nlocal] = buf[m++]; ervel[nlocal] = buf[m++]; 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 AtomVecElectron::size_restart() { int i; int nlocal = atom->nlocal; int n = 15 * nlocal; // Associated with pack_restart 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 AtomVecElectron::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = q[i]; buf[m++] = spin[i]; buf[m++] = eradius[i]; buf[m++] = ervel[i]; 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 AtomVecElectron::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++]; q[nlocal] = buf[m++]; spin[nlocal] = static_cast (buf[m++]); eradius[nlocal] = buf[m++]; ervel[nlocal] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecElectron::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; q[nlocal] = 0.0; spin[nlocal] = 1; eradius[nlocal] = 1.0; ervel[nlocal] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecElectron::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"); q[nlocal] = atof(values[2]); spin[nlocal] = atoi(values[3]); if (spin[nlocal] == 3) atom->ecp_flag = 1; eradius[nlocal] = atof(values[4]); 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; ervel[nlocal] = 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 AtomVecElectron::data_atom_hybrid(int nlocal, char **values) { q[nlocal] = atof(values[0]); spin[nlocal] = atoi(values[1]); eradius[nlocal] = atof(values[2]); if (eradius[nlocal] < 0.0) error->one(FLERR,"Invalid eradius in Atoms section of data file"); v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; v[nlocal][2] = 0.0; ervel[nlocal] = 0.0; return 3; } /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ void AtomVecElectron::data_vel(int m, char **values) { v[m][0] = atof(values[0]); v[m][1] = atof(values[1]); v[m][2] = atof(values[2]); ervel[m] = atof(values[3]); } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Velocities section of data file ------------------------------------------------------------------------- */ int AtomVecElectron::data_vel_hybrid(int m, char **values) { ervel[m] = atof(values[0]); return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecElectron::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = q[i]; buf[i][3] = spin[i]; buf[i][4] = eradius[i]; buf[i][5] = x[i][0]; buf[i][6] = x[i][1]; buf[i][7] = x[i][2]; buf[i][8] = (image[i] & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][10] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecElectron::pack_data_hybrid(int i, double *buf) { buf[0] = q[i]; buf[1] = spin[i]; buf[2] = eradius[i]; return 3; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecElectron::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],buf[i][2], (int) buf[i][3],buf[i][4], buf[i][5],buf[i][6],buf[i][7], (int) buf[i][8],(int) buf[i][9],(int) buf[i][10]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecElectron::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %d %-1.16e",buf[0],(int) buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecElectron::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = ervel[i]; } } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ int AtomVecElectron::pack_vel_hybrid(int i, double *buf) { buf[0] = ervel[i]; return 1; } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ void AtomVecElectron::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e\n", (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3],buf[i][4]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecElectron::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e",buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecElectron::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("q")) bytes += memory->usage(q,nmax); if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax); if (atom->memcheck("eradius")) bytes += memory->usage(eradius,nmax); if (atom->memcheck("ervel")) bytes += memory->usage(ervel,nmax); if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax*comm->nthreads); return bytes; } diff --git a/src/USER-SPH/atom_vec_meso.cpp b/src/USER-SPH/atom_vec_meso.cpp index 2a9fabbd9..9ddb59b2a 100644 --- a/src/USER-SPH/atom_vec_meso.cpp +++ b/src/USER-SPH/atom_vec_meso.cpp @@ -1,951 +1,949 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_meso.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecMeso::AtomVecMeso(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; mass_type = 1; comm_x_only = 0; // we communicate not only x forward but also vest ... comm_f_only = 0; // we also communicate de and drho in reverse direction size_forward = 8; // 3 + rho + e + vest[3], that means we may only communicate 5 in hybrid size_reverse = 5; // 3 + drho + de size_border = 12; // 6 + rho + e + vest[3] + cv size_velocity = 3; size_data_atom = 8; size_data_vel = 4; xcol_data = 6; atom->e_flag = 1; atom->rho_flag = 1; atom->cv_flag = 1; atom->vest_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecMeso::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"); rho = memory->grow(atom->rho, nmax, "atom:rho"); drho = memory->grow(atom->drho, nmax*comm->nthreads, "atom:drho"); e = memory->grow(atom->e, nmax, "atom:e"); de = memory->grow(atom->de, nmax*comm->nthreads, "atom:de"); vest = memory->grow(atom->vest, nmax, 3, "atom:vest"); cv = memory->grow(atom->cv, nmax, "atom:cv"); 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 AtomVecMeso::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; rho = atom->rho; drho = atom->drho; e = atom->e; de = atom->de; vest = atom->vest; cv = atom->cv; } /* ---------------------------------------------------------------------- */ void AtomVecMeso::copy(int i, int j, int delflag) { //printf("in AtomVecMeso::copy\n"); 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]; rho[j] = rho[i]; drho[j] = drho[i]; e[j] = e[i]; de[j] = de[i]; cv[j] = cv[i]; vest[j][0] = vest[i][0]; vest[j][1] = vest[i][1]; vest[j][2] = vest[i][2]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i, j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_comm_hybrid(int n, int *list, double *buf) { //printf("in AtomVecMeso::pack_comm_hybrid\n"); int i, j, m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[j][2]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::unpack_comm_hybrid(int n, int first, double *buf) { //printf("in AtomVecMeso::unpack_comm_hybrid\n"); int i, m, last; m = 0; last = first + n; for (i = first; i < last; i++) { rho[i] = buf[m++]; e[i] = buf[m++]; vest[i][0] = buf[m++]; vest[i][1] = buf[m++]; vest[i][2] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_border_hybrid(int n, int *list, double *buf) { //printf("in AtomVecMeso::pack_border_hybrid\n"); int i, j, m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[j][2]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::unpack_border_hybrid(int n, int first, double *buf) { //printf("in AtomVecMeso::unpack_border_hybrid\n"); int i, m, last; m = 0; last = first + n; for (i = first; i < last; i++) { rho[i] = buf[m++]; e[i] = buf[m++]; vest[i][0] = buf[m++]; vest[i][1] = buf[m++]; vest[i][2] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_reverse_hybrid(int n, int first, double *buf) { //printf("in AtomVecMeso::pack_reverse_hybrid\n"); int i, m, last; m = 0; last = first + n; for (i = first; i < last; i++) { buf[m++] = drho[i]; buf[m++] = de[i]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::unpack_reverse_hybrid(int n, int *list, double *buf) { //printf("in AtomVecMeso::unpack_reverse_hybrid\n"); int i, j, m; m = 0; for (i = 0; i < n; i++) { j = list[i]; drho[j] += buf[m++]; de[j] += buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { //printf("in AtomVecMeso::pack_comm\n"); int i, j, m; double dx, dy, dz; 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++] = rho[j]; buf[m++] = e[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[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; } 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++] = rho[j]; buf[m++] = e[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[j][2]; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_comm_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { //printf("in AtomVecMeso::pack_comm_vel\n"); int i, j, m; double dx, dy, dz; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[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; } 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[j][2]; } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecMeso::unpack_comm(int n, int first, double *buf) { //printf("in AtomVecMeso::unpack_comm\n"); int i, m, last; 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++]; rho[i] = buf[m++]; e[i] = buf[m++]; vest[i][0] = buf[m++]; vest[i][1] = buf[m++]; vest[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecMeso::unpack_comm_vel(int n, int first, double *buf) { //printf("in AtomVecMeso::unpack_comm_vel\n"); int i, m, last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; rho[i] = buf[m++]; e[i] = buf[m++]; vest[i][0] = buf[m++]; vest[i][1] = buf[m++]; vest[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_reverse(int n, int first, double *buf) { //printf("in AtomVecMeso::pack_reverse\n"); 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++] = drho[i]; buf[m++] = de[i]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecMeso::unpack_reverse(int n, int *list, double *buf) { //printf("in AtomVecMeso::unpack_reverse\n"); 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++]; drho[j] += buf[m++]; de[j] += buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { //printf("in AtomVecMeso::pack_border\n"); int i, j, m; double dx, dy, dz; 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]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = cv[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[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]; } 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]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = cv[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[j][2]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecMeso::pack_border_vel(int n, int *list, double *buf, int pbc_flag, int *pbc) { //printf("in AtomVecMeso::pack_border_vel\n"); int i, j, m; double dx, dy, dz; 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]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = cv[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[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]; } 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]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = rho[j]; buf[m++] = e[j]; buf[m++] = cv[j]; buf[m++] = vest[j][0]; buf[m++] = vest[j][1]; buf[m++] = vest[j][2]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ void AtomVecMeso::unpack_border(int n, int first, double *buf) { //printf("in AtomVecMeso::unpack_border\n"); int i, m, last; 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++]); rho[i] = buf[m++]; e[i] = buf[m++]; cv[i] = buf[m++]; vest[i][0] = buf[m++]; vest[i][1] = buf[m++]; vest[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecMeso::unpack_border_vel(int n, int first, double *buf) { //printf("in AtomVecMeso::unpack_border_vel\n"); int i, m, last; 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++]); v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; rho[i] = buf[m++]; e[i] = buf[m++]; cv[i] = buf[m++]; vest[i][0] = buf[m++]; vest[i][1] = buf[m++]; vest[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[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 AtomVecMeso::pack_exchange(int i, double *buf) { //printf("in AtomVecMeso::pack_exchange\n"); 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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = rho[i]; buf[m++] = e[i]; buf[m++] = cv[i]; buf[m++] = vest[i][0]; buf[m++] = vest[i][1]; buf[m++] = vest[i][2]; 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 AtomVecMeso::unpack_exchange(double *buf) { //printf("in AtomVecMeso::unpack_exchange\n"); 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++]); rho[nlocal] = buf[m++]; e[nlocal] = buf[m++]; cv[nlocal] = buf[m++]; vest[nlocal][0] = buf[m++]; vest[nlocal][1] = buf[m++]; vest[nlocal][2] = buf[m++]; 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 AtomVecMeso::size_restart() { int i; int nlocal = atom->nlocal; int n = 17 * nlocal; // 11 + rho + e + cv + vest[3] 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 AtomVecMeso::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = rho[i]; buf[m++] = e[i]; buf[m++] = cv[i]; buf[m++] = vest[i][0]; buf[m++] = vest[i][1]; buf[m++] = vest[i][2]; 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 AtomVecMeso::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++]; rho[nlocal] = buf[m++]; e[nlocal] = buf[m++]; cv[nlocal] = buf[m++]; vest[nlocal][0] = buf[m++]; vest[nlocal][1] = buf[m++]; vest[nlocal][2] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecMeso::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; rho[nlocal] = 0.0; e[nlocal] = 0.0; cv[nlocal] = 1.0; vest[nlocal][0] = 0.0; vest[nlocal][1] = 0.0; vest[nlocal][2] = 0.0; de[nlocal] = 0.0; drho[nlocal] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecMeso::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"); rho[nlocal] = atof(values[2]); e[nlocal] = atof(values[3]); cv[nlocal] = atof(values[4]); x[nlocal][0] = coord[0]; x[nlocal][1] = coord[1]; x[nlocal][2] = coord[2]; //printf("rho=%f, e=%f, cv=%f, x=%f\n", rho[nlocal], e[nlocal], cv[nlocal], x[nlocal][0]); image[nlocal] = imagetmp; mask[nlocal] = 1; v[nlocal][0] = 0.0; v[nlocal][1] = 0.0; v[nlocal][2] = 0.0; vest[nlocal][0] = 0.0; vest[nlocal][1] = 0.0; vest[nlocal][2] = 0.0; de[nlocal] = 0.0; drho[nlocal] = 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 AtomVecMeso::data_atom_hybrid(int nlocal, char **values) { rho[nlocal] = atof(values[0]); e[nlocal] = atof(values[1]); cv[nlocal] = atof(values[2]); return 3; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecMeso::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = rho[i]; buf[i][3] = e[i]; buf[i][4] = cv[i]; buf[i][5] = x[i][0]; buf[i][6] = x[i][1]; buf[i][7] = x[i][2]; buf[i][8] = (image[i] & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][10] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecMeso::pack_data_hybrid(int i, double *buf) { buf[0] = rho[i]; buf[1] = e[i]; buf[2] = cv[i]; return 3; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecMeso::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e " "%d %d %d\n", (int) buf[i][0],(int) buf[i][1], buf[i][2],buf[i][3],buf[i][4], buf[i][5],buf[i][6],buf[i][7], (int) buf[i][8],(int) buf[i][9],(int) buf[i][10]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecMeso::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e %-1.16e",buf[0],buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecMeso::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("rho")) bytes += memory->usage(rho, nmax); if (atom->memcheck("drho")) bytes += memory->usage(drho, nmax*comm->nthreads); if (atom->memcheck("e")) bytes += memory->usage(e, nmax); if (atom->memcheck("de")) bytes += memory->usage(de, nmax*comm->nthreads); if (atom->memcheck("cv")) bytes += memory->usage(cv, nmax); if (atom->memcheck("vest")) bytes += memory->usage(vest, nmax); return bytes; } diff --git a/src/atom_vec.h b/src/atom_vec.h index 934bc59ff..468eda76f 100644 --- a/src/atom_vec.h +++ b/src/atom_vec.h @@ -1,133 +1,141 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ #ifndef LMP_ATOM_VEC_H #define LMP_ATOM_VEC_H #include "stdio.h" #include "pointers.h" namespace LAMMPS_NS { class AtomVec : protected Pointers { public: int molecular; // 0 = atomic, 1 = molecular system int bonds_allow,angles_allow; // 1 if bonds, angles are used int dihedrals_allow,impropers_allow; // 1 if dihedrals, impropers used int mass_type; // 1 if per-type masses int dipole_type; // 1 if per-type dipole moments int comm_x_only; // 1 if only exchange x in forward comm int comm_f_only; // 1 if only exchange f in reverse comm int size_forward; // # of values per atom in comm int size_reverse; // # in reverse comm int size_border; // # in border comm int size_velocity; // # of velocity based quantities int size_data_atom; // number of values in Atom line int size_data_vel; // number of values in Velocity line int size_data_bonus; // number of values in Bonus line int xcol_data; // column (1-N) where x is in Atom line int cudable; // 1 if atom style is CUDA-enabled int *maxsend; // CUDA-specific variable AtomVec(class LAMMPS *); virtual ~AtomVec() {} virtual void settings(int, char **); virtual void init(); virtual void grow(int) = 0; virtual void grow_reset() = 0; virtual void copy(int, int, int) = 0; virtual void clear_bonus() {} virtual int pack_comm(int, int *, double *, int, int *) = 0; virtual int pack_comm_vel(int, int *, double *, int, int *) = 0; virtual int pack_comm_hybrid(int, int *, double *) {return 0;} virtual void unpack_comm(int, int, double *) = 0; virtual void unpack_comm_vel(int, int, double *) = 0; virtual int unpack_comm_hybrid(int, int, double *) {return 0;} virtual int pack_reverse(int, int, double *) = 0; virtual int pack_reverse_hybrid(int, int, double *) {return 0;} virtual void unpack_reverse(int, int *, double *) = 0; virtual int unpack_reverse_hybrid(int, int *, double *) {return 0;} virtual int pack_border(int, int *, double *, int, int *) = 0; virtual int pack_border_vel(int, int *, double *, int, int *) = 0; virtual int pack_border_hybrid(int, int *, double *) {return 0;} virtual void unpack_border(int, int, double *) = 0; virtual void unpack_border_vel(int, int, double *) = 0; virtual int unpack_border_hybrid(int, int, double *) {return 0;} virtual int pack_exchange(int, double *) = 0; virtual int unpack_exchange(double *) = 0; virtual int size_restart() = 0; virtual int pack_restart(int, double *) = 0; virtual int unpack_restart(double *) = 0; virtual void write_restart_settings(FILE *) {} virtual void read_restart_settings(FILE *) {} virtual void create_atom(int, double *) = 0; virtual void data_atom(double *, tagint, char **) = 0; virtual void data_atom_bonus(int, char **) {} virtual int data_atom_hybrid(int, char **) {return 0;} virtual void data_vel(int, char **); virtual int data_vel_hybrid(int, char **) {return 0;} virtual void pack_data(double **) = 0; virtual int pack_data_hybrid(int, double *) {return 0;} virtual void write_data(FILE *, int, double **) = 0; virtual int write_data_hybrid(FILE *, double *) {return 0;} virtual void pack_vel(double **); virtual int pack_vel_hybrid(int, double *) {return 0;} virtual void write_vel(FILE *, int, double **); virtual int write_vel_hybrid(FILE *, double *) {return 0;} int pack_bond(int **); void write_bond(FILE *, int, int **, int); int pack_angle(int **); void write_angle(FILE *, int, int **, int); void pack_dihedral(int **); void write_dihedral(FILE *, int, int **, int); void pack_improper(int **); void write_improper(FILE *, int, int **, int); virtual bigint memory_usage() = 0; protected: int nmax; // local copy of atom->nmax int deform_vremap; // local copy of domain properties int deform_groupbit; double *h_rate; + + union ubuf { + double d; + int64_t i; + ubuf(double arg) : d(arg) {} + ubuf(int64_t arg) : i(arg) {} + ubuf(int arg) : i(arg) {} + }; }; } #endif /* ERROR/WARNING messages: E: Invalid atom_style command Self-explanatory. E: USER-CUDA package requires a cuda enabled atom_style Self-explanatory. */ diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp index 361587af9..c4399baaf 100644 --- a/src/atom_vec_atomic.cpp +++ b/src/atom_vec_atomic.cpp @@ -1,688 +1,686 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_atomic.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecAtomic::AtomVecAtomic(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; mass_type = 1; comm_x_only = comm_f_only = 1; size_forward = 3; size_reverse = 3; size_border = 6; size_velocity = 3; size_data_atom = 5; size_data_vel = 4; xcol_data = 3; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecAtomic::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"); 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 AtomVecAtomic::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecAtomic::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]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecAtomic::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecAtomic::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; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecAtomic::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; } } /* ---------------------------------------------------------------------- */ void AtomVecAtomic::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecAtomic::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecAtomic::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecAtomic::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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 (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecAtomic::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; 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]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ void AtomVecAtomic::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecAtomic::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[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 AtomVecAtomic::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; 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 AtomVecAtomic::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++]); 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 AtomVecAtomic::size_restart() { int i; int nlocal = atom->nlocal; int n = 11 * nlocal; 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 AtomVecAtomic::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; 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 AtomVecAtomic::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++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecAtomic::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; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecAtomic::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"); 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; atom->nlocal++; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecAtomic::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = x[i][0]; buf[i][3] = x[i][1]; buf[i][4] = x[i][2]; buf[i][5] = (image[i] & IMGMASK) - IMGMAX; buf[i][6] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][7] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecAtomic::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],buf[i][2],buf[i][3],buf[i][4], (int) buf[i][5],(int) buf[i][6],(int) buf[i][7]); } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecAtomic::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); return bytes; } diff --git a/src/atom_vec_body.cpp b/src/atom_vec_body.cpp index 8a5153916..db4e5b1da 100644 --- a/src/atom_vec_body.cpp +++ b/src/atom_vec_body.cpp @@ -1,1596 +1,1594 @@ /* ---------------------------------------------------------------------- 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++) { icp->put(bonus[i].iindex); dcp->put(bonus[i].dindex); } 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; icp = bptr->icp; dcp = bptr->dcp; // 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) { icp->put(bonus[body[j]].iindex); dcp->put(bonus[body[j]].dindex); copy_bonus(nlocal_bonus-1,body[j]); nlocal_bonus--; } // if atom I has bonus data, reset I's bonus.ilocal to loc J // do NOT do this if self-copy (I=J) since I's bonus data is already deleted if (body[i] >= 0 && i != j) 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,delflag); } /* ---------------------------------------------------------------------- copy bonus data from I to J, effectively deleting the J entry also reset body that points to I to now point to J ------------------------------------------------------------------------- */ void AtomVecBody::copy_bonus(int i, int j) { body[bonus[i].ilocal] = j; memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); } /* ---------------------------------------------------------------------- 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++) { icp->put(bonus[i].iindex); dcp->put(bonus[i].dindex); } 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]); } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&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]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); 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++]); bonus[j].ivalue = icp->get(bonus[j].ninteger,bonus[j].iindex); bonus[j].dvalue = dcp->get(bonus[j].ndouble,bonus[j].dindex); m += bptr->unpack_border_body(&bonus[j],&buf[m]); bonus[j].ilocal = i; body[i] = j; nghost_bonus++; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ 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++]); bonus[j].ivalue = icp->get(bonus[j].ninteger,bonus[j].iindex); bonus[j].dvalue = dcp->get(bonus[j].ndouble,bonus[j].dindex); 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++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&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++]); bonus[j].ivalue = icp->get(bonus[j].ninteger,bonus[j].iindex); bonus[j].dvalue = dcp->get(bonus[j].ndouble,bonus[j].dindex); 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]; - buf[m] = 0.0; // for valgrind *((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++]); bonus[nlocal_bonus].ivalue = icp->get(bonus[nlocal_bonus].ninteger, bonus[nlocal_bonus].iindex); bonus[nlocal_bonus].dvalue = dcp->get(bonus[nlocal_bonus].ndouble, bonus[nlocal_bonus].dindex); 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]; - buf[m] = 0.0; // for valgrind *((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++]); bonus[nlocal_bonus].ivalue = icp->get(bonus[nlocal_bonus].ninteger, bonus[nlocal_bonus].iindex); bonus[nlocal_bonus].dvalue = dcp->get(bonus[nlocal_bonus].ndouble, bonus[nlocal_bonus].dindex); 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; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecBody::pack_data(double **buf) { double c2mc1[2],c3mc1[3],norm[3]; double area; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; if (body[i] < 0) buf[i][2] = 0; else buf[i][2] = 1; buf[i][3] = rmass[i]; buf[i][4] = x[i][0]; buf[i][5] = x[i][1]; buf[i][6] = x[i][2]; buf[i][7] = (image[i] & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecBody::pack_data_hybrid(int i, double *buf) { if (body[i] < 0) buf[0] = 0; else buf[0] = 1; buf[1] = rmass[i]; return 2; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecBody::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %g %g %g %g %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2], buf[i][3],buf[i][4],buf[i][5],buf[i][6], (int) buf[i][7],(int) buf[i][8],(int) buf[i][9]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecBody::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d %g",(int) buf[0],buf[1]); return 2; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecBody::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = angmom[i][0]; buf[i][5] = angmom[i][1]; buf[i][6] = angmom[i][2]; } } /* ---------------------------------------------------------------------- pack hybrid velocity info for data file ------------------------------------------------------------------------- */ int AtomVecBody::pack_vel_hybrid(int i, double *buf) { buf[0] = angmom[i][0]; buf[1] = angmom[i][1]; buf[2] = angmom[i][2]; return 3; } /* ---------------------------------------------------------------------- write velocity info to data file ------------------------------------------------------------------------- */ void AtomVecBody::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %g %g %g %g %g %g\n", (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecBody::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %g %g %g",buf[0],buf[1],buf[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); bytes += icp->size + dcp->size; 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; } /* ---------------------------------------------------------------------- debug method for sanity checking of own/bonus data pointers ------------------------------------------------------------------------- */ /* void AtomVecBody::check(int flag) { for (int i = 0; i < atom->nlocal; i++) { if (atom->body[i] >= 0 && atom->body[i] >= nlocal_bonus) { printf("Proc %d, step %ld, flag %d\n",comm->me,update->ntimestep,flag); errorx->one(FLERR,"BAD AAA"); } } for (int i = atom->nlocal; i < atom->nlocal+atom->nghost; i++) { if (atom->body[i] >= 0 && (atom->body[i] < nlocal_bonus || atom->body[i] >= nlocal_bonus+nghost_bonus)) { printf("Proc %d, step %ld, flag %d\n",comm->me,update->ntimestep,flag); errorx->one(FLERR,"BAD BBB"); } } for (int i = 0; i < nlocal_bonus; i++) { if (bonus[i].ilocal < 0 || bonus[i].ilocal >= atom->nlocal) { printf("Proc %d, step %ld, flag %d\n",comm->me,update->ntimestep,flag); errorx->one(FLERR,"BAD CCC"); } } for (int i = 0; i < nlocal_bonus; i++) { if (atom->body[bonus[i].ilocal] != i) { printf("Proc %d, step %ld, flag %d\n",comm->me,update->ntimestep,flag); errorx->one(FLERR,"BAD DDD"); } } for (int i = nlocal_bonus; i < nlocal_bonus+nghost_bonus; i++) { if (bonus[i].ilocal < atom->nlocal || bonus[i].ilocal >= atom->nlocal+atom->nghost) { printf("Proc %d, step %ld, flag %d\n",comm->me,update->ntimestep,flag); errorx->one(FLERR,"BAD EEE"); } } for (int i = nlocal_bonus; i < nlocal_bonus+nghost_bonus; i++) { if (atom->body[bonus[i].ilocal] != i) { printf("Proc %d, step %ld, flag %d\n",comm->me,update->ntimestep,flag); errorx->one(FLERR,"BAD FFF"); } } } */ diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp index 61d620831..8a74af12c 100644 --- a/src/atom_vec_charge.cpp +++ b/src/atom_vec_charge.cpp @@ -1,777 +1,775 @@ /* ---------------------------------------------------------------------- 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 "stdlib.h" #include "atom_vec_charge.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecCharge::AtomVecCharge(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; mass_type = 1; comm_x_only = comm_f_only = 1; size_forward = 3; size_reverse = 3; size_border = 7; size_velocity = 3; size_data_atom = 6; size_data_vel = 4; xcol_data = 4; atom->q_flag = 1; } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecCharge::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"); q = memory->grow(atom->q,nmax,"atom:q"); 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 AtomVecCharge::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; q = atom->q; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecCharge::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]; q[j] = q[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecCharge::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; } } 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; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecCharge::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; 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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 (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]; } } } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecCharge::unpack_comm(int n, int first, double *buf) { int i,m,last; 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++]; } } /* ---------------------------------------------------------------------- */ void AtomVecCharge::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecCharge::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]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecCharge::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++]; } } /* ---------------------------------------------------------------------- */ int AtomVecCharge::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = q[j]; } } 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]; buf[m++] = q[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecCharge::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; 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]; buf[m++] = q[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[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]; buf[m++] = q[j]; 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]; } } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecCharge::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = q[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecCharge::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecCharge::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); q[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecCharge::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) q[i] = buf[m++]; 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 AtomVecCharge::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = q[i]; 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 AtomVecCharge::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++]); q[nlocal] = buf[m++]; 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 AtomVecCharge::size_restart() { int i; int nlocal = atom->nlocal; int n = 12 * nlocal; 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 AtomVecCharge::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = q[i]; 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 AtomVecCharge::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++]; q[nlocal] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecCharge::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; q[nlocal] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecCharge::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"); q[nlocal] = atof(values[2]); 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; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecCharge::data_atom_hybrid(int nlocal, char **values) { q[nlocal] = atof(values[0]); return 1; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecCharge::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; buf[i][2] = q[i]; buf[i][3] = x[i][0]; buf[i][4] = x[i][1]; buf[i][5] = x[i][2]; buf[i][6] = (image[i] & IMGMASK) - IMGMAX; buf[i][7] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecCharge::pack_data_hybrid(int i, double *buf) { buf[0] = q[i]; return 1; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecCharge::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],buf[i][2], buf[i][3],buf[i][4],buf[i][5], (int) buf[i][6],(int) buf[i][7],(int) buf[i][8]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecCharge::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e",buf[0]); return 1; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecCharge::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("q")) bytes += memory->usage(q,nmax); return bytes; } diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp index c4352270b..9a90f5dda 100755 --- a/src/atom_vec_ellipsoid.cpp +++ b/src/atom_vec_ellipsoid.cpp @@ -1,1404 +1,1402 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- Contributing author: Mike Brown (SNL) ------------------------------------------------------------------------- */ #include "stdlib.h" #include "atom_vec_ellipsoid.h" #include "math_extra.h" #include "atom.h" #include "comm.h" #include "force.h" #include "domain.h" #include "modify.h" #include "fix.h" #include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace MathConst; #define DELTA 10000 #define DELTA_BONUS 10000 /* ---------------------------------------------------------------------- */ AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; comm_x_only = comm_f_only = 0; size_forward = 7; size_reverse = 6; size_border = 14; size_velocity = 6; size_data_atom = 7; size_data_vel = 7; size_data_bonus = 8; xcol_data = 5; atom->ellipsoid_flag = 1; atom->rmass_flag = atom->angmom_flag = atom->torque_flag = 1; nlocal_bonus = nghost_bonus = nmax_bonus = 0; bonus = NULL; } /* ---------------------------------------------------------------------- */ AtomVecEllipsoid::~AtomVecEllipsoid() { memory->sfree(bonus); } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecEllipsoid::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"); ellipsoid = memory->grow(atom->ellipsoid,nmax,"atom:ellipsoid"); 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 AtomVecEllipsoid::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; ellipsoid = atom->ellipsoid; } /* ---------------------------------------------------------------------- grow bonus data structure ------------------------------------------------------------------------- */ void AtomVecEllipsoid::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 ------------------------------------------------------------------------- */ void AtomVecEllipsoid::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 && ellipsoid[j] >= 0) { copy_bonus(nlocal_bonus-1,ellipsoid[j]); nlocal_bonus--; } // if atom I has bonus data, reset I's bonus.ilocal to loc J // do NOT do this if self-copy (I=J) since I's bonus data is already deleted if (ellipsoid[i] >= 0 && i != j) bonus[ellipsoid[i]].ilocal = j; ellipsoid[j] = ellipsoid[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- copy bonus data from I to J, effectively deleting the J entry also reset ellipsoid that points to I to now point to J ------------------------------------------------------------------------- */ void AtomVecEllipsoid::copy_bonus(int i, int j) { ellipsoid[bonus[i].ilocal] = j; memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); } /* ---------------------------------------------------------------------- clear ghost info in bonus data called before ghosts are recommunicated in comm and irregular ------------------------------------------------------------------------- */ void AtomVecEllipsoid::clear_bonus() { nghost_bonus = 0; } /* ---------------------------------------------------------------------- set shape values in bonus data for particle I oriented aligned with xyz axes this may create or delete entry in bonus data ------------------------------------------------------------------------- */ void AtomVecEllipsoid::set_shape(int i, double shapex, double shapey, double shapez) { if (ellipsoid[i] < 0) { if (shapex == 0.0 && shapey == 0.0 && shapez == 0.0) return; if (nlocal_bonus == nmax_bonus) grow_bonus(); double *shape = bonus[nlocal_bonus].shape; double *quat = bonus[nlocal_bonus].quat; shape[0] = shapex; shape[1] = shapey; shape[2] = shapez; quat[0] = 1.0; quat[1] = 0.0; quat[2] = 0.0; quat[3] = 0.0; bonus[nlocal_bonus].ilocal = i; ellipsoid[i] = nlocal_bonus++; } else if (shapex == 0.0 && shapey == 0.0 && shapez == 0.0) { copy_bonus(nlocal_bonus-1,ellipsoid[i]); nlocal_bonus--; ellipsoid[i] = -1; } else { double *shape = bonus[ellipsoid[i]].shape; shape[0] = shapex; shape[1] = shapey; shape[2] = shapez; } } /* ---------------------------------------------------------------------- */ int AtomVecEllipsoid::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 (ellipsoid[j] >= 0) { quat = bonus[ellipsoid[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } } 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 (ellipsoid[j] >= 0) { quat = bonus[ellipsoid[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecEllipsoid::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 (ellipsoid[j] >= 0) { quat = bonus[ellipsoid[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 (ellipsoid[j] >= 0) { quat = bonus[ellipsoid[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 (ellipsoid[j] >= 0) { quat = bonus[ellipsoid[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 AtomVecEllipsoid::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 (ellipsoid[j] >= 0) { quat = bonus[ellipsoid[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecEllipsoid::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 (ellipsoid[i] >= 0) { quat = bonus[ellipsoid[i]].quat; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; } } } /* ---------------------------------------------------------------------- */ void AtomVecEllipsoid::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 (ellipsoid[i] >= 0) { quat = bonus[ellipsoid[i]].quat; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = 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 AtomVecEllipsoid::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 (ellipsoid[i] >= 0) { quat = bonus[ellipsoid[i]].quat; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecEllipsoid::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 AtomVecEllipsoid::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 AtomVecEllipsoid::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 AtomVecEllipsoid::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 AtomVecEllipsoid::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; double *shape,*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]; buf[m++] = tag[j]; buf[m++] = type[j]; buf[m++] = mask[j]; if (ellipsoid[j] < 0) buf[m++] = 0; else { buf[m++] = 1; shape = bonus[ellipsoid[j]].shape; quat = bonus[ellipsoid[j]].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } } 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 (ellipsoid[j] < 0) buf[m++] = 0; else { buf[m++] = 1; shape = bonus[ellipsoid[j]].shape; quat = bonus[ellipsoid[j]].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecEllipsoid::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 *shape,*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]; buf[m++] = tag[j]; buf[m++] = type[j]; buf[m++] = mask[j]; if (ellipsoid[j] < 0) buf[m++] = 0; else { buf[m++] = 1; shape = bonus[ellipsoid[j]].shape; quat = bonus[ellipsoid[j]].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 (ellipsoid[j] < 0) buf[m++] = 0; else { buf[m++] = 1; shape = bonus[ellipsoid[j]].shape; quat = bonus[ellipsoid[j]].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 (ellipsoid[j] < 0) buf[m++] = 0; else { buf[m++] = 1; shape = bonus[ellipsoid[j]].shape; quat = bonus[ellipsoid[j]].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecEllipsoid::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; double *shape,*quat; m = 0; for (i = 0; i < n; i++) { j = list[i]; if (ellipsoid[j] < 0) buf[m++] = 0; else { buf[m++] = 1; shape = bonus[ellipsoid[j]].shape; quat = bonus[ellipsoid[j]].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecEllipsoid::unpack_border(int n, int first, double *buf) { int i,j,m,last; double *shape,*quat; 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++]); ellipsoid[i] = static_cast (buf[m++]); if (ellipsoid[i] == 0) ellipsoid[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); shape = bonus[j].shape; quat = bonus[j].quat; shape[0] = buf[m++]; shape[1] = buf[m++]; shape[2] = buf[m++]; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; bonus[j].ilocal = i; ellipsoid[i] = j; nghost_bonus++; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecEllipsoid::unpack_border_vel(int n, int first, double *buf) { int i,j,m,last; double *shape,*quat; 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++]); ellipsoid[i] = static_cast (buf[m++]); if (ellipsoid[i] == 0) ellipsoid[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); shape = bonus[j].shape; quat = bonus[j].quat; shape[0] = buf[m++]; shape[1] = buf[m++]; shape[2] = buf[m++]; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; bonus[j].ilocal = i; ellipsoid[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++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecEllipsoid::unpack_border_hybrid(int n, int first, double *buf) { int i,j,m,last; double *shape,*quat; m = 0; last = first + n; for (i = first; i < last; i++) { ellipsoid[i] = static_cast (buf[m++]); if (ellipsoid[i] == 0) ellipsoid[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); shape = bonus[j].shape; quat = bonus[j].quat; shape[0] = buf[m++]; shape[1] = buf[m++]; shape[2] = buf[m++]; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; bonus[j].ilocal = i; ellipsoid[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 AtomVecEllipsoid::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]; - buf[m] = 0.0; // for valgrind *((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 (ellipsoid[i] < 0) buf[m++] = 0; else { buf[m++] = 1; int j = ellipsoid[i]; double *shape = bonus[j].shape; double *quat = bonus[j].quat; buf[m++] = shape[0]; buf[m++] = shape[1]; buf[m++] = shape[2]; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 AtomVecEllipsoid::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++]; ellipsoid[nlocal] = static_cast (buf[m++]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else { if (nlocal_bonus == nmax_bonus) grow_bonus(); double *shape = bonus[nlocal_bonus].shape; double *quat = bonus[nlocal_bonus].quat; shape[0] = buf[m++]; shape[1] = buf[m++]; shape[2] = buf[m++]; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; bonus[nlocal_bonus].ilocal = nlocal; ellipsoid[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 AtomVecEllipsoid::size_restart() { int i; int n = 0; int nlocal = atom->nlocal; for (i = 0; i < nlocal; i++) if (ellipsoid[i] >= 0) n += 23; 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 bonus data xyz must be 1st 3 values, so that read_restart can test on them molecular types may be negative, but write as positive ------------------------------------------------------------------------- */ int AtomVecEllipsoid::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]; - buf[m] = 0.0; // for valgrind *((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 (ellipsoid[i] < 0) buf[m++] = 0; else { buf[m++] = 1; int j = ellipsoid[i]; buf[m++] = bonus[j].shape[0]; buf[m++] = bonus[j].shape[1]; buf[m++] = bonus[j].shape[2]; buf[m++] = bonus[j].quat[0]; buf[m++] = bonus[j].quat[1]; buf[m++] = bonus[j].quat[2]; buf[m++] = bonus[j].quat[3]; } 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 bonus data ------------------------------------------------------------------------- */ int AtomVecEllipsoid::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++]; ellipsoid[nlocal] = static_cast (buf[m++]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else { if (nlocal_bonus == nmax_bonus) grow_bonus(); double *shape = bonus[nlocal_bonus].shape; double *quat = bonus[nlocal_bonus].quat; shape[0] = buf[m++]; shape[1] = buf[m++]; shape[2] = buf[m++]; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; bonus[nlocal_bonus].ilocal = nlocal; ellipsoid[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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecEllipsoid::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; ellipsoid[nlocal] = -1; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecEllipsoid::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"); ellipsoid[nlocal] = atoi(values[2]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else if (ellipsoid[nlocal] == 1) ellipsoid[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 AtomVecEllipsoid::data_atom_hybrid(int nlocal, char **values) { ellipsoid[nlocal] = atoi(values[0]); if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1; else if (ellipsoid[nlocal] == 1) ellipsoid[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 line from Ellipsoids section of data file ------------------------------------------------------------------------- */ void AtomVecEllipsoid::data_atom_bonus(int m, char **values) { if (ellipsoid[m]) error->one(FLERR,"Assigning ellipsoid parameters to non-ellipsoid atom"); if (nlocal_bonus == nmax_bonus) grow_bonus(); double *shape = bonus[nlocal_bonus].shape; shape[0] = 0.5 * atof(values[0]); shape[1] = 0.5 * atof(values[1]); shape[2] = 0.5 * atof(values[2]); if (shape[0] <= 0.0 || shape[1] <= 0.0 || shape[2] <= 0.0) error->one(FLERR,"Invalid shape in Ellipsoids section of data file"); double *quat = bonus[nlocal_bonus].quat; quat[0] = atof(values[3]); quat[1] = atof(values[4]); quat[2] = atof(values[5]); quat[3] = atof(values[6]); MathExtra::qnormalize(quat); // reset ellipsoid mass // previously stored density in rmass rmass[m] *= 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2]; bonus[nlocal_bonus].ilocal = m; ellipsoid[m] = nlocal_bonus++; } /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ void AtomVecEllipsoid::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 line in Velocities section of data file ------------------------------------------------------------------------- */ int AtomVecEllipsoid::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; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecEllipsoid::pack_data(double **buf) { double *shape; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = type[i]; if (ellipsoid[i] < 0) buf[i][2] = 0; else buf[i][2] = 1; if (ellipsoid[i] < 0) buf[i][3] = rmass[i]; else { shape = bonus[ellipsoid[i]].shape; buf[i][3] = rmass[i] / (4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2]); } buf[i][4] = x[i][0]; buf[i][5] = x[i][1]; buf[i][6] = x[i][2]; buf[i][7] = (image[i] & IMGMASK) - IMGMAX; buf[i][8] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecEllipsoid::pack_data_hybrid(int i, double *buf) { if (ellipsoid[i] < 0) buf[0] = 0; else buf[0] = 1; if (ellipsoid[i] < 0) buf[1] = rmass[i]; else { double *shape = bonus[ellipsoid[i]].shape; buf[1] = rmass[i] / (4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2]); } return 2; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecEllipsoid::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2], buf[i][3],buf[i][4],buf[i][5],buf[i][6], (int) buf[i][7],(int) buf[i][8],(int) buf[i][9]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecEllipsoid::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d %-1.16e",(int) buf[0],buf[1]); return 2; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecEllipsoid::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = angmom[i][0]; buf[i][5] = angmom[i][1]; buf[i][6] = angmom[i][2]; } } /* ---------------------------------------------------------------------- pack hybrid velocity info for data file ------------------------------------------------------------------------- */ int AtomVecEllipsoid::pack_vel_hybrid(int i, double *buf) { buf[0] = angmom[i][0]; buf[1] = angmom[i][1]; buf[2] = angmom[i][2]; return 3; } /* ---------------------------------------------------------------------- write velocity info to data file ------------------------------------------------------------------------- */ void AtomVecEllipsoid::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n", (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecEllipsoid::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e %-1.16e",buf[0],buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecEllipsoid::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("ellipsoid")) bytes += memory->usage(ellipsoid,nmax); bytes += nmax_bonus*sizeof(Bonus); return bytes; } diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp index 88651dec4..de95a29fb 100644 --- a/src/atom_vec_line.cpp +++ b/src/atom_vec_line.cpp @@ -1,1305 +1,1303 @@ /* ---------------------------------------------------------------------- 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_line.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 #define EPSILON 0.001 /* ---------------------------------------------------------------------- */ AtomVecLine::AtomVecLine(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; comm_x_only = comm_f_only = 0; size_forward = 4; size_reverse = 6; size_border = 10; size_velocity = 6; size_data_atom = 8; size_data_vel = 7; size_data_bonus = 5; xcol_data = 6; atom->line_flag = 1; atom->molecule_flag = atom->rmass_flag = 1; atom->omega_flag = atom->torque_flag = 1; nlocal_bonus = nghost_bonus = nmax_bonus = 0; bonus = NULL; } /* ---------------------------------------------------------------------- */ AtomVecLine::~AtomVecLine() { memory->sfree(bonus); } /* ---------------------------------------------------------------------- */ void AtomVecLine::init() { AtomVec::init(); if (domain->dimension != 2) error->all(FLERR,"Atom_style line can only be used in 2d simulations"); } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecLine::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"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); omega = memory->grow(atom->omega,nmax,3,"atom:omega"); torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); line = memory->grow(atom->line,nmax,"atom:line"); 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 AtomVecLine::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; molecule = atom->molecule; rmass = atom->rmass; omega = atom->omega; torque = atom->torque; line = atom->line; } /* ---------------------------------------------------------------------- grow bonus data structure ------------------------------------------------------------------------- */ void AtomVecLine::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 ------------------------------------------------------------------------- */ void AtomVecLine::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]; molecule[j] = molecule[i]; rmass[j] = rmass[i]; omega[j][0] = omega[i][0]; omega[j][1] = omega[i][1]; omega[j][2] = omega[i][2]; // if deleting atom J via delflag and J has bonus data, then delete it if (delflag && line[j] >= 0) { copy_bonus(nlocal_bonus-1,line[j]); nlocal_bonus--; } // if atom I has bonus data, reset I's bonus.ilocal to loc J // do NOT do this if self-copy (I=J) since I's bonus data is already deleted if (line[i] >= 0 && i != j) bonus[line[i]].ilocal = j; line[j] = line[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- copy bonus data from I to J, effectively deleting the J entry also reset ine that points to I to now point to J ------------------------------------------------------------------------- */ void AtomVecLine::copy_bonus(int i, int j) { line[bonus[i].ilocal] = j; memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); } /* ---------------------------------------------------------------------- clear ghost info in bonus data called before ghosts are recommunicated in comm and irregular ------------------------------------------------------------------------- */ void AtomVecLine::clear_bonus() { nghost_bonus = 0; } /* ---------------------------------------------------------------------- set length value in bonus data for particle I oriented along x axis this may create or delete entry in bonus data ------------------------------------------------------------------------- */ void AtomVecLine::set_length(int i, double value) { if (line[i] < 0) { if (value == 0.0) return; if (nlocal_bonus == nmax_bonus) grow_bonus(); bonus[nlocal_bonus].length = value; bonus[nlocal_bonus].theta = 0.0; bonus[nlocal_bonus].ilocal = i; line[i] = nlocal_bonus++; } else if (value == 0.0) { copy_bonus(nlocal_bonus-1,line[i]); nlocal_bonus--; line[i] = -1; } else bonus[line[i]].length = value; } /* ---------------------------------------------------------------------- */ int AtomVecLine::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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 (line[j] >= 0) buf[m++] = bonus[line[j]].theta; } } 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 (line[j] >= 0) buf[m++] = bonus[line[j]].theta; } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecLine::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; 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 (line[j] >= 0) buf[m++] = bonus[line[j]].theta; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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 (line[j] >= 0) buf[m++] = bonus[line[j]].theta; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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 (line[j] >= 0) buf[m++] = bonus[line[j]].theta; 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++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecLine::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; if (line[j] >= 0) buf[m++] = bonus[line[j]].theta; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecLine::unpack_comm(int n, int first, double *buf) { int i,m,last; 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 (line[i] >= 0) bonus[line[i]].theta = buf[m++]; } } /* ---------------------------------------------------------------------- */ void AtomVecLine::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; 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 (line[i] >= 0) bonus[line[i]].theta = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; omega[i][0] = buf[m++]; omega[i][1] = buf[m++]; omega[i][2] = buf[m++]; } } /* ---------------------------------------------------------------------- */ int AtomVecLine::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) if (line[i] >= 0) bonus[line[i]].theta = buf[m++]; return m; } /* ---------------------------------------------------------------------- */ int AtomVecLine::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 AtomVecLine::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 AtomVecLine::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 AtomVecLine::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 AtomVecLine::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; buf[m++] = molecule[j]; if (line[j] < 0) buf[m++] = 0; else { buf[m++] = 1; buf[m++] = bonus[line[j]].length; buf[m++] = bonus[line[j]].theta; } } } 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]; buf[m++] = molecule[j]; if (line[j] < 0) buf[m++] = 0; else { buf[m++] = 1; buf[m++] = bonus[line[j]].length; buf[m++] = bonus[line[j]].theta; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecLine::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; 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]; buf[m++] = molecule[j]; if (line[j] < 0) buf[m++] = 0; else { buf[m++] = 1; buf[m++] = bonus[line[j]].length; buf[m++] = bonus[line[j]].theta; } buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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]; buf[m++] = molecule[j]; if (line[j] < 0) buf[m++] = 0; else { buf[m++] = 1; buf[m++] = bonus[line[j]].length; buf[m++] = bonus[line[j]].theta; } buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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]; buf[m++] = molecule[j]; if (line[j] < 0) buf[m++] = 0; else { buf[m++] = 1; buf[m++] = bonus[line[j]].length; buf[m++] = bonus[line[j]].theta; } 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++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecLine::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = molecule[j]; if (line[j] < 0) buf[m++] = 0; else { buf[m++] = 1; buf[m++] = bonus[line[j]].length; buf[m++] = bonus[line[j]].theta; } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecLine::unpack_border(int n, int first, double *buf) { int i,j,m,last; 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++]); molecule[i] = static_cast (buf[m++]); line[i] = static_cast (buf[m++]); if (line[i] == 0) line[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); bonus[j].length = buf[m++]; bonus[j].theta = buf[m++]; bonus[j].ilocal = i; line[i] = j; nghost_bonus++; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecLine::unpack_border_vel(int n, int first, double *buf) { int i,j,m,last; 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++]); molecule[i] = static_cast (buf[m++]); line[i] = static_cast (buf[m++]); if (line[i] == 0) line[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); bonus[j].length = buf[m++]; bonus[j].theta = buf[m++]; bonus[j].ilocal = i; line[i] = j; nghost_bonus++; } v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; omega[i][0] = buf[m++]; omega[i][1] = buf[m++]; omega[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecLine::unpack_border_hybrid(int n, int first, double *buf) { int i,j,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { molecule[i] = static_cast (buf[m++]); line[i] = static_cast (buf[m++]); if (line[i] == 0) line[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); bonus[j].length = buf[m++]; bonus[j].theta = buf[m++]; bonus[j].ilocal = i; line[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 AtomVecLine::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = molecule[i]; buf[m++] = rmass[i]; buf[m++] = omega[i][0]; buf[m++] = omega[i][1]; buf[m++] = omega[i][2]; if (line[i] < 0) buf[m++] = 0; else { buf[m++] = 1; int j = line[i]; buf[m++] = bonus[j].length; buf[m++] = bonus[j].theta; } 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 AtomVecLine::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++]); molecule[nlocal] = static_cast (buf[m++]); rmass[nlocal] = buf[m++]; omega[nlocal][0] = buf[m++]; omega[nlocal][1] = buf[m++]; omega[nlocal][2] = buf[m++]; line[nlocal] = static_cast (buf[m++]); if (line[nlocal] == 0) line[nlocal] = -1; else { if (nlocal_bonus == nmax_bonus) grow_bonus(); bonus[nlocal_bonus].length = buf[m++]; bonus[nlocal_bonus].theta = buf[m++]; bonus[nlocal_bonus].ilocal = nlocal; line[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 AtomVecLine::size_restart() { int i; int n = 0; int nlocal = atom->nlocal; for (i = 0; i < nlocal; i++) if (line[i] >= 0) n += 19; else n += 17; 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 AtomVecLine::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = molecule[i]; buf[m++] = rmass[i]; buf[m++] = omega[i][0]; buf[m++] = omega[i][1]; buf[m++] = omega[i][2]; if (line[i] < 0) buf[m++] = 0; else { buf[m++] = 1; int j = line[i]; buf[m++] = bonus[j].length; buf[m++] = bonus[j].theta; } 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 AtomVecLine::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++]; molecule[nlocal] = static_cast (buf[m++]); rmass[nlocal] = buf[m++]; omega[nlocal][0] = buf[m++]; omega[nlocal][1] = buf[m++]; omega[nlocal][2] = buf[m++]; line[nlocal] = static_cast (buf[m++]); if (line[nlocal] == 0) line[nlocal] = -1; else { if (nlocal_bonus == nmax_bonus) grow_bonus(); bonus[nlocal_bonus].length = buf[m++]; bonus[nlocal_bonus].theta = buf[m++]; bonus[nlocal_bonus].ilocal = nlocal; line[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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecLine::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; molecule[nlocal] = 0; rmass[nlocal] = 1.0; omega[nlocal][0] = 0.0; omega[nlocal][1] = 0.0; omega[nlocal][2] = 0.0; line[nlocal] = -1; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecLine::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"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type in Atoms section of data file"); line[nlocal] = atoi(values[3]); if (line[nlocal] == 0) line[nlocal] = -1; else if (line[nlocal] == 1) line[nlocal] = 0; else error->one(FLERR,"Invalid atom type in Atoms section of data file"); rmass[nlocal] = atof(values[4]); 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; omega[nlocal][0] = 0.0; omega[nlocal][1] = 0.0; omega[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 AtomVecLine::data_atom_hybrid(int nlocal, char **values) { molecule[nlocal] = atoi(values[0]); line[nlocal] = atoi(values[1]); if (line[nlocal] == 0) line[nlocal] = -1; else if (line[nlocal] == 1) line[nlocal] = 0; else error->one(FLERR,"Invalid atom type in Atoms section of data file"); rmass[nlocal] = atof(values[2]); if (rmass[nlocal] <= 0.0) error->one(FLERR,"Invalid density in Atoms section of data file"); return 3; } /* ---------------------------------------------------------------------- unpack one line from Lines section of data file ------------------------------------------------------------------------- */ void AtomVecLine::data_atom_bonus(int m, char **values) { if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom"); if (nlocal_bonus == nmax_bonus) grow_bonus(); double x1 = atof(values[0]); double y1 = atof(values[1]); double x2 = atof(values[2]); double y2 = atof(values[3]); double dx = x2 - x1; double dy = y2 - y1; double length = sqrt(dx*dx + dy*dy); bonus[nlocal_bonus].length = length; if (dy >= 0.0) bonus[nlocal_bonus].theta = acos(dx/length); else bonus[nlocal_bonus].theta = -acos(dx/length); double xc = 0.5*(x1+x2); double yc = 0.5*(y1+y2); dx = xc - x[m][0]; dy = yc - x[m][1]; double delta = sqrt(dx*dx + dy*dy); if (delta/length > EPSILON) error->one(FLERR,"Inconsistent line segment in data file"); x[m][0] = xc; x[m][1] = yc; // reset line mass // previously stored density in rmass rmass[m] *= length; bonus[nlocal_bonus].ilocal = m; line[m] = nlocal_bonus++; } /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ void AtomVecLine::data_vel(int m, char **values) { v[m][0] = atof(values[0]); v[m][1] = atof(values[1]); v[m][2] = atof(values[2]); omega[m][0] = atof(values[3]); omega[m][1] = atof(values[4]); omega[m][2] = atof(values[5]); } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Velocities section of data file ------------------------------------------------------------------------- */ int AtomVecLine::data_vel_hybrid(int m, char **values) { omega[m][0] = atof(values[0]); omega[m][1] = atof(values[1]); omega[m][2] = atof(values[2]); return 3; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecLine::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = molecule[i]; buf[i][2] = type[i]; if (line[i] < 0) buf[i][3] = 0; else buf[i][3] = 1; if (line[i] < 0) buf[i][4] = rmass[i]; else buf[i][4] = rmass[i]/bonus[line[i]].length; buf[i][5] = x[i][0]; buf[i][6] = x[i][1]; buf[i][7] = x[i][2]; buf[i][8] = (image[i] & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][10] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecLine::pack_data_hybrid(int i, double *buf) { buf[0] = molecule[i]; if (line[i] < 0) buf[1] = 0; else buf[1] = 1; if (line[i] < 0) buf[2] = rmass[i]; else buf[2] = rmass[i]/bonus[line[i]].length; return 3; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecLine::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2],(int) buf[i][3], buf[i][4],buf[i][5],buf[i][6],buf[i][7], (int) buf[i][8],(int) buf[i][9],(int) buf[i][10]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecLine::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d %d %-1.16e",(int) buf[0],(int) buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecLine::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = omega[i][0]; buf[i][5] = omega[i][1]; buf[i][6] = omega[i][2]; } } /* ---------------------------------------------------------------------- pack hybrid velocity info for data file ------------------------------------------------------------------------- */ int AtomVecLine::pack_vel_hybrid(int i, double *buf) { buf[0] = omega[i][0]; buf[1] = omega[i][1]; buf[2] = omega[i][2]; return 3; } /* ---------------------------------------------------------------------- write velocity info to data file ------------------------------------------------------------------------- */ void AtomVecLine::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n", (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecLine::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e %-1.16e",buf[0],buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecLine::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("molecule")) bytes += memory->usage(molecule,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3); if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3); if (atom->memcheck("line")) bytes += memory->usage(line,nmax); bytes += nmax_bonus*sizeof(Bonus); return bytes; } /* ---------------------------------------------------------------------- check consistency of internal Bonus data structure n = # of atoms in regular structure to check against ------------------------------------------------------------------------- */ /* void AtomVecLine::consistency_check(int n, char *str) { int iflag = 0; int count = 0; for (int i = 0; i < n; i++) { if (line[i] >= 0) { count++; if (line[i] >= nlocal_bonus) iflag++; if (bonus[line[i]].ilocal != i) iflag++; //if (comm->me == 1 && update->ntimestep == 873) // printf("CCHK %s: %d %d: %d %d: %d %d\n", // str,i,n,line[i],nlocal_bonus,bonus[line[i]].ilocal,iflag); } } if (iflag) { printf("BAD vecline ptrs: %s: %d %d: %d\n",str,comm->me, update->ntimestep,iflag); MPI_Abort(world,1); } if (count != nlocal_bonus) { char msg[128]; printf("BAD vecline count: %s: %d %d: %d %d\n", str,comm->me,update->ntimestep,count,nlocal_bonus); MPI_Abort(world,1); } } */ diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index 2c5e02a2e..ea09b8e4b 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -1,1192 +1,1191 @@ /* ---------------------------------------------------------------------- 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_sphere.h" #include "atom.h" #include "comm.h" #include "domain.h" #include "modify.h" #include "force.h" #include "fix.h" #include "fix_adapt.h" #include "math_const.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; using namespace MathConst; #define DELTA 10000 /* ---------------------------------------------------------------------- */ AtomVecSphere::AtomVecSphere(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; comm_x_only = 1; comm_f_only = 0; size_forward = 3; size_reverse = 6; size_border = 8; size_velocity = 6; size_data_atom = 7; size_data_vel = 7; xcol_data = 5; atom->sphere_flag = 1; atom->radius_flag = atom->rmass_flag = atom->omega_flag = atom->torque_flag = 1; } /* ---------------------------------------------------------------------- */ void AtomVecSphere::init() { AtomVec::init(); // set radvary if particle diameters are time-varying due to fix adapt radvary = 0; comm_x_only = 1; size_forward = 3; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"adapt") == 0) { FixAdapt *fix = (FixAdapt *) modify->fix[i]; if (fix->diamflag) { radvary = 1; comm_x_only = 0; size_forward = 5; } } } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecSphere::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"); radius = memory->grow(atom->radius,nmax,"atom:radius"); rmass = memory->grow(atom->rmass,nmax,"atom:rmass"); omega = memory->grow(atom->omega,nmax,3,"atom:omega"); torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque"); 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 AtomVecSphere::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; radius = atom->radius; rmass = atom->rmass; omega = atom->omega; torque = atom->torque; } /* ---------------------------------------------------------------------- copy atom I info to atom J ------------------------------------------------------------------------- */ void AtomVecSphere::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]; radius[j] = radius[i]; rmass[j] = rmass[i]; omega[j][0] = omega[i][0]; omega[j][1] = omega[i][1]; omega[j][2] = omega[i][2]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- */ int AtomVecSphere::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; if (radvary == 0) { 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]; } } 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; } } } else { 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++] = radius[j]; buf[m++] = rmass[j]; } } 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; buf[m++] = radius[j]; buf[m++] = rmass[j]; } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecSphere::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; if (radvary == 0) { 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++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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 (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++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } } } else { 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++] = radius[j]; buf[m++] = rmass[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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; buf[m++] = radius[j]; buf[m++] = rmass[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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++] = radius[j]; buf[m++] = rmass[j]; 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++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecSphere::pack_comm_hybrid(int n, int *list, double *buf) { int i,j,m; if (radvary == 0) return 0; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = radius[j]; buf[m++] = rmass[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecSphere::unpack_comm(int n, int first, double *buf) { int i,m,last; if (radvary == 0) { 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++]; } } else { 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++]; radius[i] = buf[m++]; rmass[i] = buf[m++]; } } } /* ---------------------------------------------------------------------- */ void AtomVecSphere::unpack_comm_vel(int n, int first, double *buf) { int i,m,last; if (radvary == 0) { 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++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; omega[i][0] = buf[m++]; omega[i][1] = buf[m++]; omega[i][2] = buf[m++]; } } else { 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++]; radius[i] = buf[m++]; rmass[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; omega[i][0] = buf[m++]; omega[i][1] = buf[m++]; omega[i][2] = buf[m++]; } } } /* ---------------------------------------------------------------------- */ int AtomVecSphere::unpack_comm_hybrid(int n, int first, double *buf) { int i,m,last; if (radvary == 0) return 0; m = 0; last = first + n; for (i = first; i < last; i++) { radius[i] = buf[m++]; rmass[i] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecSphere::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 AtomVecSphere::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 AtomVecSphere::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 AtomVecSphere::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 AtomVecSphere::pack_border(int n, int *list, double *buf, - int pbc_flag, int *pbc) + int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz; 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]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; buf[m++] = radius[j]; buf[m++] = rmass[j]; } } 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]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; buf[m++] = radius[j]; buf[m++] = rmass[j]; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecSphere::pack_border_vel(int n, int *list, double *buf, - int pbc_flag, int *pbc) + int pbc_flag, int *pbc) { int i,j,m; double dx,dy,dz,dvx,dvy,dvz; 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]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; buf[m++] = radius[j]; buf[m++] = rmass[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; buf[m++] = radius[j]; buf[m++] = rmass[j]; buf[m++] = v[j][0]; buf[m++] = v[j][1]; buf[m++] = v[j][2]; buf[m++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } 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]; + buf[m++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; buf[m++] = radius[j]; buf[m++] = rmass[j]; 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++] = omega[j][0]; buf[m++] = omega[j][1]; buf[m++] = omega[j][2]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecSphere::pack_border_hybrid(int n, int *list, double *buf) { int i,j,m; m = 0; for (i = 0; i < n; i++) { j = list[i]; buf[m++] = radius[j]; buf[m++] = rmass[j]; } return m; } /* ---------------------------------------------------------------------- */ void AtomVecSphere::unpack_border(int n, int first, double *buf) { int i,m,last; 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++]); + tag[i] = (int) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; radius[i] = buf[m++]; rmass[i] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecSphere::unpack_border_vel(int n, int first, double *buf) { int i,m,last; 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++]); + tag[i] = (int) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; radius[i] = buf[m++]; rmass[i] = buf[m++]; v[i][0] = buf[m++]; v[i][1] = buf[m++]; v[i][2] = buf[m++]; omega[i][0] = buf[m++]; omega[i][1] = buf[m++]; omega[i][2] = buf[m++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecSphere::unpack_border_hybrid(int n, int first, double *buf) { int i,m,last; m = 0; last = first + n; for (i = first; i < last; i++) { radius[i] = buf[m++]; rmass[i] = buf[m++]; } 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 AtomVecSphere::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]; - buf[m] = 0.0; // for valgrind - *((tagint *) &buf[m++]) = image[i]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; buf[m++] = radius[i]; buf[m++] = rmass[i]; buf[m++] = omega[i][0]; buf[m++] = omega[i][1]; buf[m++] = omega[i][2]; 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 AtomVecSphere::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++]); + tag[nlocal] = (int) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (tagint) ubuf(buf[m++]).i; radius[nlocal] = buf[m++]; rmass[nlocal] = buf[m++]; omega[nlocal][0] = buf[m++]; omega[nlocal][1] = buf[m++]; omega[nlocal][2] = buf[m++]; 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 AtomVecSphere::size_restart() { int i; int nlocal = atom->nlocal; int n = 16 * nlocal; 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 AtomVecSphere::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]; - buf[m] = 0.0; // for valgrind - *((tagint *) &buf[m++]) = image[i]; + buf[m++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = radius[i]; buf[m++] = rmass[i]; buf[m++] = omega[i][0]; buf[m++] = omega[i][1]; buf[m++] = omega[i][2]; 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 AtomVecSphere::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++]); + tag[nlocal] = (int) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (tagint) ubuf(buf[m++]).i; v[nlocal][0] = buf[m++]; v[nlocal][1] = buf[m++]; v[nlocal][2] = buf[m++]; radius[nlocal] = buf[m++]; rmass[nlocal] = buf[m++]; omega[nlocal][0] = buf[m++]; omega[nlocal][1] = buf[m++]; omega[nlocal][2] = buf[m++]; 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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecSphere::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; radius[nlocal] = 0.5; rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal]; omega[nlocal][0] = 0.0; omega[nlocal][1] = 0.0; omega[nlocal][2] = 0.0; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecSphere::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"); radius[nlocal] = 0.5 * atof(values[2]); if (radius[nlocal] < 0.0) error->one(FLERR,"Invalid radius in Atoms section of data file"); double density = atof(values[3]); if (density <= 0.0) error->one(FLERR,"Invalid density in Atoms section of data file"); if (radius[nlocal] == 0.0) rmass[nlocal] = density; else rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal] * density; 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; omega[nlocal][0] = 0.0; omega[nlocal][1] = 0.0; omega[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 AtomVecSphere::data_atom_hybrid(int nlocal, char **values) { radius[nlocal] = 0.5 * atof(values[0]); if (radius[nlocal] < 0.0) error->one(FLERR,"Invalid radius in Atoms section of data file"); double density = atof(values[1]); if (density <= 0.0) error->one(FLERR,"Invalid density in Atoms section of data file"); if (radius[nlocal] == 0.0) rmass[nlocal] = density; else rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[nlocal] * density; return 2; } /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ void AtomVecSphere::data_vel(int m, char **values) { v[m][0] = atof(values[0]); v[m][1] = atof(values[1]); v[m][2] = atof(values[2]); omega[m][0] = atof(values[3]); omega[m][1] = atof(values[4]); omega[m][2] = atof(values[5]); } /* ---------------------------------------------------------------------- unpack hybrid quantities from one line in Velocities section of data file ------------------------------------------------------------------------- */ int AtomVecSphere::data_vel_hybrid(int m, char **values) { omega[m][0] = atof(values[0]); omega[m][1] = atof(values[1]); omega[m][2] = atof(values[2]); return 3; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecSphere::pack_data(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { - buf[i][0] = tag[i]; - buf[i][1] = type[i]; + buf[i][0] = ubuf(tag[i]).d; + buf[i][1] = ubuf(type[i]).d; buf[i][2] = 2.0*radius[i]; if (radius[i] == 0.0) buf[i][3] = rmass[i]; else buf[i][3] = rmass[i] / (4.0*MY_PI/3.0 * radius[i]*radius[i]*radius[i]); buf[i][4] = x[i][0]; buf[i][5] = x[i][1]; buf[i][6] = x[i][2]; - buf[i][7] = (image[i] & IMGMASK) - IMGMAX; - buf[i][8] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; - buf[i][9] = (image[i] >> IMG2BITS) - IMGMAX; + buf[i][7] = ubuf((image[i] & IMGMASK) - IMGMAX).d; + buf[i][8] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; + buf[i][9] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecSphere::pack_data_hybrid(int i, double *buf) { buf[0] = 2.0*radius[i]; if (radius[i] == 0.0) buf[1] = rmass[i]; else buf[1] = rmass[i] / (4.0*MY_PI/3.0 * radius[i]*radius[i]*radius[i]); return 2; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecSphere::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", - (int) buf[i][0],(int) buf[i][1], + (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6], - (int) buf[i][7],(int) buf[i][8],(int) buf[i][9]); + (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i, + (int) ubuf(buf[i][9]).i); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecSphere::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e",buf[0],buf[1]); return 2; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecSphere::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { - buf[i][0] = tag[i]; + buf[i][0] = ubuf(tag[i]).d; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = omega[i][0]; buf[i][5] = omega[i][1]; buf[i][6] = omega[i][2]; } } /* ---------------------------------------------------------------------- pack hybrid velocity info for data file ------------------------------------------------------------------------- */ int AtomVecSphere::pack_vel_hybrid(int i, double *buf) { buf[0] = omega[i][0]; buf[1] = omega[i][1]; buf[2] = omega[i][2]; return 3; } /* ---------------------------------------------------------------------- write velocity info to data file ------------------------------------------------------------------------- */ void AtomVecSphere::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n", - (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3], + (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecSphere::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e %-1.16e",buf[0],buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecSphere::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("radius")) bytes += memory->usage(radius,nmax); if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax); if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3); if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3); return bytes; } diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp index b8202e82e..85a86aca8 100644 --- a/src/atom_vec_tri.cpp +++ b/src/atom_vec_tri.cpp @@ -1,1717 +1,1715 @@ /* ---------------------------------------------------------------------- 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_tri.h" #include "math_extra.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 #define EPSILON 0.001 /* ---------------------------------------------------------------------- */ AtomVecTri::AtomVecTri(LAMMPS *lmp) : AtomVec(lmp) { molecular = 0; comm_x_only = comm_f_only = 0; size_forward = 7; size_reverse = 6; size_border = 24; size_velocity = 6; size_data_atom = 8; size_data_vel = 7; size_data_bonus = 10; xcol_data = 6; atom->tri_flag = 1; atom->molecule_flag = atom->rmass_flag = 1; atom->angmom_flag = atom->torque_flag = 1; nlocal_bonus = nghost_bonus = nmax_bonus = 0; bonus = NULL; } /* ---------------------------------------------------------------------- */ AtomVecTri::~AtomVecTri() { memory->sfree(bonus); } /* ---------------------------------------------------------------------- */ void AtomVecTri::init() { AtomVec::init(); if (domain->dimension != 3) error->all(FLERR,"Atom_style tri can only be used in 3d simulations"); } /* ---------------------------------------------------------------------- grow atom arrays n = 0 grows arrays by DELTA n > 0 allocates arrays to size n ------------------------------------------------------------------------- */ void AtomVecTri::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"); molecule = memory->grow(atom->molecule,nmax,"atom:molecule"); 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"); tri = memory->grow(atom->tri,nmax,"atom:tri"); 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 AtomVecTri::grow_reset() { tag = atom->tag; type = atom->type; mask = atom->mask; image = atom->image; x = atom->x; v = atom->v; f = atom->f; molecule = atom->molecule; rmass = atom->rmass; angmom = atom->angmom; torque = atom->torque; tri = atom->tri; } /* ---------------------------------------------------------------------- grow bonus data structure ------------------------------------------------------------------------- */ void AtomVecTri::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 AtomVecTri::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]; molecule[j] = molecule[i]; 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 && tri[j] >= 0) { copy_bonus(nlocal_bonus-1,tri[j]); nlocal_bonus--; } // if atom I has bonus data, reset I's bonus.ilocal to loc J // do NOT do this if self-copy (I=J) since I's bonus data is already deleted if (tri[i] >= 0 && i != j) bonus[tri[i]].ilocal = j; tri[j] = tri[i]; if (atom->nextra_grow) for (int iextra = 0; iextra < atom->nextra_grow; iextra++) modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j,delflag); } /* ---------------------------------------------------------------------- copy bonus data from I to J, effectively deleting the J entry also reset tri that points to I to now point to J ------------------------------------------------------------------------- */ void AtomVecTri::copy_bonus(int i, int j) { tri[bonus[i].ilocal] = j; memcpy(&bonus[j],&bonus[i],sizeof(Bonus)); } /* ---------------------------------------------------------------------- clear ghost info in bonus data called before ghosts are recommunicated in comm and irregular ------------------------------------------------------------------------- */ void AtomVecTri::clear_bonus() { nghost_bonus = 0; } /* ---------------------------------------------------------------------- set equilateral tri of size in bonus data for particle I oriented symmetrically in xy plane this may create or delete entry in bonus data ------------------------------------------------------------------------- */ void AtomVecTri::set_equilateral(int i, double size) { if (tri[i] < 0) { if (size == 0.0) return; if (nlocal_bonus == nmax_bonus) grow_bonus(); double *quat = bonus[nlocal_bonus].quat; double *c1 = bonus[nlocal_bonus].c1; double *c2 = bonus[nlocal_bonus].c2; double *c3 = bonus[nlocal_bonus].c3; double *inertia = bonus[nlocal_bonus].inertia; quat[0] = 1.0; quat[1] = 0.0; quat[2] = 0.0; quat[3] = 0.0; c1[0] = -size/2.0; c1[1] = -sqrt(3.0)/2.0 * size / 3.0; c1[2] = 0.0; c2[0] = size/2.0; c2[1] = -sqrt(3.0)/2.0 * size / 3.0; c2[2] = 0.0; c3[0] = 0.0; c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0; c3[2] = 0.0; inertia[0] = sqrt(3.0)/96.0 * size*size*size*size; inertia[1] = sqrt(3.0)/96.0 * size*size*size*size; inertia[2] = sqrt(3.0)/48.0 * size*size*size*size; bonus[nlocal_bonus].ilocal = i; tri[i] = nlocal_bonus++; } else if (size == 0.0) { copy_bonus(nlocal_bonus-1,tri[i]); nlocal_bonus--; tri[i] = -1; } else { double *c1 = bonus[tri[i]].c1; double *c2 = bonus[tri[i]].c2; double *c3 = bonus[tri[i]].c3; double *inertia = bonus[tri[i]].inertia; c1[0] = -size/2.0; c1[1] = -sqrt(3.0)/2.0 * size / 3.0; c1[2] = 0.0; c2[0] = size/2.0; c2[1] = -sqrt(3.0)/2.0 * size / 3.0; c2[2] = 0.0; c3[0] = 0.0; c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0; c3[2] = 0.0; inertia[0] = sqrt(3.0)/96.0 * size*size*size*size; inertia[1] = sqrt(3.0)/96.0 * size*size*size*size; inertia[2] = sqrt(3.0)/48.0 * size*size*size*size; } } /* ---------------------------------------------------------------------- */ int AtomVecTri::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 (tri[j] >= 0) { quat = bonus[tri[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } } 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 (tri[j] >= 0) { quat = bonus[tri[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } } return m; } /* ---------------------------------------------------------------------- */ int AtomVecTri::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 (tri[j] >= 0) { quat = bonus[tri[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 (tri[j] >= 0) { quat = bonus[tri[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 (tri[j] >= 0) { quat = bonus[tri[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } 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 AtomVecTri::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 (tri[j] >= 0) { quat = bonus[tri[j]].quat; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecTri::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 (tri[i] >= 0) { quat = bonus[tri[i]].quat; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; } } } /* ---------------------------------------------------------------------- */ void AtomVecTri::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 (tri[i] >= 0) { quat = bonus[tri[i]].quat; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = 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 AtomVecTri::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 (tri[i] >= 0) { quat = bonus[tri[i]].quat; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; } return m; } /* ---------------------------------------------------------------------- */ int AtomVecTri::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 AtomVecTri::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 AtomVecTri::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 AtomVecTri::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 AtomVecTri::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]; buf[m++] = molecule[j]; if (tri[j] < 0) buf[m++] = 0; else { buf[m++] = 1; quat = bonus[tri[j]].quat; c1 = bonus[tri[j]].c1; c2 = bonus[tri[j]].c2; c3 = bonus[tri[j]].c3; inertia = bonus[tri[j]].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[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]; } 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]; buf[m++] = molecule[j]; if (tri[j] < 0) buf[m++] = 0; else { buf[m++] = 1; quat = bonus[tri[j]].quat; c1 = bonus[tri[j]].c1; c2 = bonus[tri[j]].c2; c3 = bonus[tri[j]].c3; inertia = bonus[tri[j]].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecTri::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]; buf[m++] = molecule[j]; if (tri[j] < 0) buf[m++] = 0; else { buf[m++] = 1; quat = bonus[tri[j]].quat; c1 = bonus[tri[j]].c1; c2 = bonus[tri[j]].c2; c3 = bonus[tri[j]].c3; inertia = bonus[tri[j]].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } 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]; buf[m++] = molecule[j]; if (tri[j] < 0) buf[m++] = 0; else { buf[m++] = 1; quat = bonus[tri[j]].quat; c1 = bonus[tri[j]].c1; c2 = bonus[tri[j]].c2; c3 = bonus[tri[j]].c3; inertia = bonus[tri[j]].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } 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]; buf[m++] = molecule[j]; if (tri[j] < 0) buf[m++] = 0; else { buf[m++] = 1; quat = bonus[tri[j]].quat; c1 = bonus[tri[j]].c1; c2 = bonus[tri[j]].c2; c3 = bonus[tri[j]].c3; inertia = bonus[tri[j]].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } 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]; } } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]->pack_border(n,list,&buf[m]); return m; } /* ---------------------------------------------------------------------- */ int AtomVecTri::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]; buf[m++] = molecule[j]; if (tri[j] < 0) buf[m++] = 0; else { buf[m++] = 1; quat = bonus[tri[j]].quat; c1 = bonus[tri[j]].c1; c2 = bonus[tri[j]].c2; c3 = bonus[tri[j]].c3; inertia = bonus[tri[j]].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } } return m; } /* ---------------------------------------------------------------------- */ void AtomVecTri::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++]); molecule[i] = static_cast (buf[m++]); tri[i] = static_cast (buf[m++]); if (tri[i] == 0) tri[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); quat = bonus[j].quat; c1 = bonus[j].c1; c2 = bonus[j].c2; c3 = bonus[j].c3; inertia = bonus[j].inertia; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; c1[0] = buf[m++]; c1[1] = buf[m++]; c1[2] = buf[m++]; c2[0] = buf[m++]; c2[1] = buf[m++]; c2[2] = buf[m++]; c3[0] = buf[m++]; c3[1] = buf[m++]; c3[2] = buf[m++]; inertia[0] = buf[m++]; inertia[1] = buf[m++]; inertia[2] = buf[m++]; bonus[j].ilocal = i; tri[i] = j; nghost_bonus++; } } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ void AtomVecTri::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++]); molecule[i] = static_cast (buf[m++]); tri[i] = static_cast (buf[m++]); if (tri[i] == 0) tri[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); quat = bonus[j].quat; c1 = bonus[j].c1; c2 = bonus[j].c2; c3 = bonus[j].c3; inertia = bonus[j].inertia; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; c1[0] = buf[m++]; c1[1] = buf[m++]; c1[2] = buf[m++]; c2[0] = buf[m++]; c2[1] = buf[m++]; c2[2] = buf[m++]; c3[0] = buf[m++]; c3[1] = buf[m++]; c3[2] = buf[m++]; inertia[0] = buf[m++]; inertia[1] = buf[m++]; inertia[2] = buf[m++]; bonus[j].ilocal = i; tri[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++]; } if (atom->nextra_border) for (int iextra = 0; iextra < atom->nextra_border; iextra++) m += modify->fix[atom->extra_border[iextra]]-> unpack_border(n,first,&buf[m]); } /* ---------------------------------------------------------------------- */ int AtomVecTri::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++) { molecule[i] = static_cast (buf[m++]); tri[i] = static_cast (buf[m++]); if (tri[i] == 0) tri[i] = -1; else { j = nlocal_bonus + nghost_bonus; if (j == nmax_bonus) grow_bonus(); quat = bonus[j].quat; c1 = bonus[j].c1; c2 = bonus[j].c2; c3 = bonus[j].c3; inertia = bonus[j].inertia; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; c1[0] = buf[m++]; c1[1] = buf[m++]; c1[2] = buf[m++]; c2[0] = buf[m++]; c2[1] = buf[m++]; c2[2] = buf[m++]; c3[0] = buf[m++]; c3[1] = buf[m++]; c3[2] = buf[m++]; inertia[0] = buf[m++]; inertia[1] = buf[m++]; inertia[2] = buf[m++]; bonus[j].ilocal = i; tri[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 AtomVecTri::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = molecule[i]; buf[m++] = rmass[i]; buf[m++] = angmom[i][0]; buf[m++] = angmom[i][1]; buf[m++] = angmom[i][2]; if (tri[i] < 0) buf[m++] = 0; else { buf[m++] = 1; int j = tri[i]; double *quat = bonus[j].quat; double *c1 = bonus[j].c1; double *c2 = bonus[j].c2; double *c3 = bonus[j].c3; double *inertia = bonus[j].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } 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 AtomVecTri::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++]); molecule[nlocal] = static_cast (buf[m++]); rmass[nlocal] = buf[m++]; angmom[nlocal][0] = buf[m++]; angmom[nlocal][1] = buf[m++]; angmom[nlocal][2] = buf[m++]; tri[nlocal] = static_cast (buf[m++]); if (tri[nlocal] == 0) tri[nlocal] = -1; else { if (nlocal_bonus == nmax_bonus) grow_bonus(); double *quat = bonus[nlocal_bonus].quat; double *c1 = bonus[nlocal_bonus].c1; double *c2 = bonus[nlocal_bonus].c2; double *c3 = bonus[nlocal_bonus].c3; double *inertia = bonus[nlocal_bonus].inertia; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; c1[0] = buf[m++]; c1[1] = buf[m++]; c1[2] = buf[m++]; c2[0] = buf[m++]; c2[1] = buf[m++]; c2[2] = buf[m++]; c3[0] = buf[m++]; c3[1] = buf[m++]; c3[2] = buf[m++]; inertia[0] = buf[m++]; inertia[1] = buf[m++]; inertia[2] = buf[m++]; bonus[nlocal_bonus].ilocal = nlocal; tri[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 AtomVecTri::size_restart() { int i; int n = 0; int nlocal = atom->nlocal; for (i = 0; i < nlocal; i++) if (tri[i] >= 0) n += 33; else n += 17; 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 AtomVecTri::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]; - buf[m] = 0.0; // for valgrind *((tagint *) &buf[m++]) = image[i]; buf[m++] = v[i][0]; buf[m++] = v[i][1]; buf[m++] = v[i][2]; buf[m++] = molecule[i]; buf[m++] = rmass[i]; buf[m++] = angmom[i][0]; buf[m++] = angmom[i][1]; buf[m++] = angmom[i][2]; if (tri[i] < 0) buf[m++] = 0; else { buf[m++] = 1; int j = tri[i]; double *quat = bonus[j].quat; double *c1 = bonus[j].c1; double *c2 = bonus[j].c2; double *c3 = bonus[j].c3; double *inertia = bonus[j].inertia; buf[m++] = quat[0]; buf[m++] = quat[1]; buf[m++] = quat[2]; buf[m++] = quat[3]; buf[m++] = c1[0]; buf[m++] = c1[1]; buf[m++] = c1[2]; buf[m++] = c2[0]; buf[m++] = c2[1]; buf[m++] = c2[2]; buf[m++] = c3[0]; buf[m++] = c3[1]; buf[m++] = c3[2]; buf[m++] = inertia[0]; buf[m++] = inertia[1]; buf[m++] = inertia[2]; } 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 AtomVecTri::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++]; molecule[nlocal] = static_cast (buf[m++]); rmass[nlocal] = buf[m++]; angmom[nlocal][0] = buf[m++]; angmom[nlocal][1] = buf[m++]; angmom[nlocal][2] = buf[m++]; tri[nlocal] = static_cast (buf[m++]); if (tri[nlocal] == 0) tri[nlocal] = -1; else { if (nlocal_bonus == nmax_bonus) grow_bonus(); double *quat = bonus[nlocal_bonus].quat; double *c1 = bonus[nlocal_bonus].c1; double *c2 = bonus[nlocal_bonus].c2; double *c3 = bonus[nlocal_bonus].c3; double *inertia = bonus[nlocal_bonus].inertia; quat[0] = buf[m++]; quat[1] = buf[m++]; quat[2] = buf[m++]; quat[3] = buf[m++]; c1[0] = buf[m++]; c1[1] = buf[m++]; c1[2] = buf[m++]; c2[0] = buf[m++]; c2[1] = buf[m++]; c2[2] = buf[m++]; c3[0] = buf[m++]; c3[1] = buf[m++]; c3[2] = buf[m++]; inertia[0] = buf[m++]; inertia[1] = buf[m++]; inertia[2] = buf[m++]; bonus[nlocal_bonus].ilocal = nlocal; tri[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; } /* ---------------------------------------------------------------------- create one atom of itype at coord set other values to defaults ------------------------------------------------------------------------- */ void AtomVecTri::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; molecule[nlocal] = 0; rmass[nlocal] = 1.0; angmom[nlocal][0] = 0.0; angmom[nlocal][1] = 0.0; angmom[nlocal][2] = 0.0; tri[nlocal] = -1; atom->nlocal++; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecTri::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"); molecule[nlocal] = atoi(values[1]); type[nlocal] = atoi(values[2]); if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) error->one(FLERR,"Invalid atom type in Atoms section of data file"); tri[nlocal] = atoi(values[3]); if (tri[nlocal] == 0) tri[nlocal] = -1; else if (tri[nlocal] == 1) tri[nlocal] = 0; else error->one(FLERR,"Invalid atom type in Atoms section of data file"); rmass[nlocal] = atof(values[4]); 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 tri in Atoms section of data file initialize other atom quantities for this sub-style ------------------------------------------------------------------------- */ int AtomVecTri::data_atom_hybrid(int nlocal, char **values) { molecule[nlocal] = atoi(values[0]); tri[nlocal] = atoi(values[1]); if (tri[nlocal] == 0) tri[nlocal] = -1; else if (tri[nlocal] == 1) tri[nlocal] = 0; else error->one(FLERR,"Invalid atom type in Atoms section of data file"); rmass[nlocal] = atof(values[2]); if (rmass[nlocal] <= 0.0) error->one(FLERR,"Invalid density in Atoms section of data file"); return 3; } /* ---------------------------------------------------------------------- unpack one line from Tris section of data file ------------------------------------------------------------------------- */ void AtomVecTri::data_atom_bonus(int m, char **values) { if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom"); if (nlocal_bonus == nmax_bonus) grow_bonus(); double c1[3],c2[3],c3[3]; c1[0] = atof(values[0]); c1[1] = atof(values[1]); c1[2] = atof(values[2]); c2[0] = atof(values[3]); c2[1] = atof(values[4]); c2[2] = atof(values[5]); c3[0] = atof(values[6]); c3[1] = atof(values[7]); c3[2] = atof(values[8]); // check for duplicate points if (c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2]) error->one(FLERR,"Invalid shape in Triangles section of data file"); if (c1[0] == c3[0] && c1[1] == c3[1] && c1[2] == c3[2]) error->one(FLERR,"Invalid shape in Triangles section of data file"); if (c2[0] == c3[0] && c2[1] == c3[1] && c2[2] == c3[2]) error->one(FLERR,"Invalid shape in Triangles section of data file"); // size = length of one edge double c2mc1[2],c3mc1[3]; MathExtra::sub3(c2,c1,c2mc1); MathExtra::sub3(c3,c1,c3mc1); double size = MAX(MathExtra::len3(c2mc1),MathExtra::len3(c3mc1)); // centroid = 1/3 of sum of vertices double centroid[3]; centroid[0] = (c1[0]+c2[0]+c3[0]) / 3.0; centroid[1] = (c1[1]+c2[1]+c3[1]) / 3.0; centroid[2] = (c1[2]+c2[2]+c3[2]) / 3.0; double dx = centroid[0] - x[m][0]; double dy = centroid[1] - x[m][1]; double dz = centroid[2] - x[m][2]; double delta = sqrt(dx*dx + dy*dy + dz*dz); if (delta/size > EPSILON) error->one(FLERR,"Inconsistent triangle in data file"); x[m][0] = centroid[0]; x[m][1] = centroid[1]; x[m][2] = centroid[2]; // reset tri mass // previously stored density in rmass // tri area = 0.5 len(U x V), where U,V are edge vectors from one vertex double norm[3]; MathExtra::cross3(c2mc1,c3mc1,norm); double area = 0.5 * MathExtra::len3(norm); rmass[m] *= area; // inertia = inertia tensor of triangle as 6-vector in Voigt notation double inertia[6]; MathExtra::inertia_triangle(c1,c2,c3,rmass[m],inertia); // diagonalize inertia tensor via Jacobi rotations // bonus[].inertia = 3 eigenvalues = principal moments of inertia // evectors and exzy_space = 3 evectors = principal axes of triangle double tensor[3][3],evectors[3][3]; tensor[0][0] = inertia[0]; tensor[1][1] = inertia[1]; tensor[2][2] = inertia[2]; tensor[1][2] = tensor[2][1] = inertia[3]; tensor[0][2] = tensor[2][0] = inertia[4]; tensor[0][1] = tensor[1][0] = inertia[5]; int ierror = MathExtra::jacobi(tensor,bonus[nlocal_bonus].inertia,evectors); if (ierror) error->one(FLERR,"Insufficient Jacobi rotations for triangle"); double ex_space[3],ey_space[3],ez_space[3]; ex_space[0] = evectors[0][0]; ex_space[1] = evectors[1][0]; ex_space[2] = evectors[2][0]; ey_space[0] = evectors[0][1]; ey_space[1] = evectors[1][1]; ey_space[2] = evectors[2][1]; ez_space[0] = evectors[0][2]; ez_space[1] = evectors[1][2]; ez_space[2] = evectors[2][2]; // enforce 3 orthogonal vectors as a right-handed coordinate system // flip 3rd vector if needed MathExtra::cross3(ex_space,ey_space,norm); if (MathExtra::dot3(norm,ez_space) < 0.0) MathExtra::negate3(ez_space); // create initial quaternion MathExtra::exyz_to_q(ex_space,ey_space,ez_space,bonus[nlocal_bonus].quat); // bonus c1,c2,c3 = displacement of c1,c2,c3 from centroid // in basis of principal axes double disp[3]; MathExtra::sub3(c1,centroid,disp); MathExtra::transpose_matvec(ex_space,ey_space,ez_space, disp,bonus[nlocal_bonus].c1); MathExtra::sub3(c2,centroid,disp); MathExtra::transpose_matvec(ex_space,ey_space,ez_space, disp,bonus[nlocal_bonus].c2); MathExtra::sub3(c3,centroid,disp); MathExtra::transpose_matvec(ex_space,ey_space,ez_space, disp,bonus[nlocal_bonus].c3); bonus[nlocal_bonus].ilocal = m; tri[m] = nlocal_bonus++; } /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ void AtomVecTri::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 tri in Velocities section of data file ------------------------------------------------------------------------- */ int AtomVecTri::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; } /* ---------------------------------------------------------------------- pack atom info for data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecTri::pack_data(double **buf) { double c2mc1[2],c3mc1[3],norm[3]; double area; int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = molecule[i]; buf[i][2] = type[i]; if (tri[i] < 0) buf[i][3] = 0; else buf[i][3] = 1; if (tri[i] < 0) buf[i][4] = rmass[i]; else { MathExtra::sub3(bonus[tri[i]].c2,bonus[tri[i]].c1,c2mc1); MathExtra::sub3(bonus[tri[i]].c3,bonus[tri[i]].c1,c3mc1); MathExtra::cross3(c2mc1,c3mc1,norm); area = 0.5 * MathExtra::len3(norm); buf[i][4] = rmass[i]/area; } buf[i][5] = x[i][0]; buf[i][6] = x[i][1]; buf[i][7] = x[i][2]; buf[i][8] = (image[i] & IMGMASK) - IMGMAX; buf[i][9] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX; buf[i][10] = (image[i] >> IMG2BITS) - IMGMAX; } } /* ---------------------------------------------------------------------- pack hybrid atom info for data file ------------------------------------------------------------------------- */ int AtomVecTri::pack_data_hybrid(int i, double *buf) { buf[0] = molecule[i]; if (tri[i] < 0) buf[1] = 0; else buf[1] = 1; if (tri[i] < 0) buf[2] = rmass[i]; else { double c2mc1[2],c3mc1[3],norm[3]; MathExtra::sub3(bonus[tri[i]].c2,bonus[tri[i]].c1,c2mc1); MathExtra::sub3(bonus[tri[i]].c3,bonus[tri[i]].c1,c3mc1); MathExtra::cross3(c2mc1,c3mc1,norm); double area = 0.5 * MathExtra::len3(norm); buf[2] = rmass[i]/area; } return 3; } /* ---------------------------------------------------------------------- write atom info to data file including 3 image flags ------------------------------------------------------------------------- */ void AtomVecTri::write_data(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", (int) buf[i][0],(int) buf[i][1],(int) buf[i][2],(int) buf[i][3], buf[i][4],buf[i][5],buf[i][6],buf[i][7], (int) buf[i][8],(int) buf[i][9],(int) buf[i][10]); } /* ---------------------------------------------------------------------- write hybrid atom info to data file ------------------------------------------------------------------------- */ int AtomVecTri::write_data_hybrid(FILE *fp, double *buf) { fprintf(fp," %d %d %-1.16e",(int) buf[0],(int) buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- pack velocity info for data file ------------------------------------------------------------------------- */ void AtomVecTri::pack_vel(double **buf) { int nlocal = atom->nlocal; for (int i = 0; i < nlocal; i++) { buf[i][0] = tag[i]; buf[i][1] = v[i][0]; buf[i][2] = v[i][1]; buf[i][3] = v[i][2]; buf[i][4] = angmom[i][0]; buf[i][5] = angmom[i][1]; buf[i][6] = angmom[i][2]; } } /* ---------------------------------------------------------------------- pack hybrid velocity info for data file ------------------------------------------------------------------------- */ int AtomVecTri::pack_vel_hybrid(int i, double *buf) { buf[0] = angmom[i][0]; buf[1] = angmom[i][1]; buf[2] = angmom[i][2]; return 3; } /* ---------------------------------------------------------------------- write velocity info to data file ------------------------------------------------------------------------- */ void AtomVecTri::write_vel(FILE *fp, int n, double **buf) { for (int i = 0; i < n; i++) fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n", (int) buf[i][0],buf[i][1],buf[i][2],buf[i][3], buf[i][4],buf[i][5],buf[i][6]); } /* ---------------------------------------------------------------------- write hybrid velocity info to data file ------------------------------------------------------------------------- */ int AtomVecTri::write_vel_hybrid(FILE *fp, double *buf) { fprintf(fp," %-1.16e %-1.16e %-1.16e",buf[0],buf[1],buf[2]); return 3; } /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ bigint AtomVecTri::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("molecule")) bytes += memory->usage(molecule,nmax); 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("tri")) bytes += memory->usage(tri,nmax); bytes += nmax_bonus*sizeof(Bonus); return bytes; }