diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp index 0b6a27888f..dc3279227d 100644 --- a/src/DIPOLE/atom_vec_dipole.cpp +++ b/src/DIPOLE/atom_vec_dipole.cpp @@ -31,880 +31,40 @@ 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 a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecDipole::grow(int n) -{ - if (n == 0) grow_nmax(); - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).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++]; - } - - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).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++]; - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - 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++] = 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++] = 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) "q mu"; + fields_copy = (char *) "q mu"; + fields_comm = (char *) "mu3"; + fields_comm_vel = (char *) "mu3"; + fields_reverse = NULL; + fields_border = (char *) "q mu"; + fields_border_vel = (char *) "q mu"; + fields_exchange = (char *) "q mu"; + fields_restart = (char *) "q mu"; + fields_create = (char *) "q mu"; + fields_data_atom = (char *) "id type q x mu3"; + fields_data_vel = NULL; + + setup_fields(); } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what the default AtomVec::data_atom() just initialized ------------------------------------------------------------------------- */ void AtomVecDipole::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp); - if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one(FLERR,"Invalid atom type in Atoms section of data file"); - - q[nlocal] = utils::numeric(FLERR,values[2],true,lmp); - - x[nlocal][0] = coord[0]; - x[nlocal][1] = coord[1]; - x[nlocal][2] = coord[2]; - - mu[nlocal][0] = utils::numeric(FLERR,values[6],true,lmp); - mu[nlocal][1] = utils::numeric(FLERR,values[7],true,lmp); - mu[nlocal][2] = utils::numeric(FLERR,values[8],true,lmp); - 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++; + int ilocal = atom->nlocal-1; + double mu = atom->mu[ilocal]; + mu[3] = sqrt(mu[0]*mu[0] + mu[1]*mu[1] + mu[2]*mu[2]); } -/* ---------------------------------------------------------------------- - 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] = utils::numeric(FLERR,values[0],true,lmp); - mu[nlocal][0] = utils::numeric(FLERR,values[1],true,lmp); - mu[nlocal][1] = utils::numeric(FLERR,values[2],true,lmp); - mu[nlocal][2] = utils::numeric(FLERR,values[3],true,lmp); - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(type[i]).d; - 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] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][10] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][11] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - 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,TAGINT_FORMAT \ - " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e " - "%-1.16e %d %d %d\n", - (tagint) 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],buf[i][7],buf[i][8], - (int) ubuf(buf[i][9]).i,(int) ubuf(buf[i][10]).i, - (int) ubuf(buf[i][11]).i); -} - -/* ---------------------------------------------------------------------- - 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/DIPOLE/atom_vec_dipole.h b/src/DIPOLE/atom_vec_dipole.h index c6ee23def1..6abcb4e2ea 100644 --- a/src/DIPOLE/atom_vec_dipole.h +++ b/src/DIPOLE/atom_vec_dipole.h @@ -27,43 +27,7 @@ namespace LAMMPS_NS { class AtomVecDipole : public AtomVec { public: AtomVecDipole(class LAMMPS *); - void grow(int); - void grow_reset(); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - int pack_comm_hybrid(int, int *, double *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int unpack_comm_hybrid(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); - void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - - private: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - double *q,**mu; }; } @@ -73,13 +37,4 @@ class AtomVecDipole : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp index 4eba471b8f..79f5a7853e 100644 --- a/src/MOLECULE/atom_vec_angle.cpp +++ b/src/MOLECULE/atom_vec_angle.cpp @@ -13,13 +13,6 @@ #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" -#include "utils.h" using namespace LAMMPS_NS; @@ -31,895 +24,140 @@ AtomVecAngle::AtomVecAngle(LAMMPS *lmp) : AtomVec(lmp) 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; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 nspecial special"; + fields_copy = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 nspecial special"; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = (char *) "molecule"; + fields_border_vel = (char *) "molecule"; + fields_exchange = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 nspecial special"; + fields_restart = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3"; + fields_create = (char *) "molecule num_bond num_angle nspecial"; + fields_data_atom = (char *) "id molecule type x"; + fields_data_vel = NULL; + + setup_fields(); + + bond_per_atom = angle_per_atom = 0; + bond_negative = angle_negative = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecAngle::~AtomVecAngle() +{ + delete [] bond_negative; + delete [] angle_negative; } /* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n + pack atom I's data for restart file + modify/unmodify values for default AtomVec::pack_restart() to pack ------------------------------------------------------------------------- */ -void AtomVecAngle::grow(int n) +int AtomVecAngle::pack_restart(int i, double *buf) { - if (n == 0) grow_nmax(); - else nmax = n; - atom->nmax = nmax; - if (nmax < 0 || nmax > MAXSMALLINT) - error->one(FLERR,"Per-processor system is too big"); + // insure negative vectors are needed length - 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]; + if (bond_per_atom < atom->bond_per_atom) { + delete [] bond_negative; + bond_per_atom = atom->bond_per_atom; + bond_negative = new int[bond_per_atom]; + } + if (angle_per_atom < atom->angle_per_atom) { + delete [] angle_negative; + angle_per_atom = atom->angle_per_atom; + angle_negative = new int[angle_per_atom]; } - 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]; + // flip any negative types to positive and flag which ones + + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + int *num_angle = atom->num_angle; + int **angle_type = atom->angle_type; + + int any_bond_negative = 0; + for (int m = 0; m < num_bond[i]; m++) { + if (bond_type[i][m] < 0) { + bond_negative[m] = 1; + bond_type[i][m] = -bond_type[i][m]; + any_bond_negative = 1; + } else bond_negative[m] = 0; } - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - } - } 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - } + int any_angle_negative = 0; + for (int m = 0; m < num_angle[i]; m++) { + if (angle_type[i][m] < 0) { + angle_negative[m] = 1; + angle_type[i][m] = -angle_type[i][m]; + any_angle_negative = 1; + } else angle_negative[m] = 0; } - 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]); + // perform the pack with adjusted values - return m; -} + int n = AtomVec::pack_restart(i,buf); -/* ---------------------------------------------------------------------- */ + // restore the flagged types to their negative values -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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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 (any_bond_negative) { + for (int m = 0; m < num_bond[i]; m++) + if (bond_negative[m]) bond_type[i][m] = -bond_type[i][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 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++] = ubuf(molecule[j]).d; + if (any_angle_negative) { + for (int m = 0; m < num_angle[i]; m++) + if (angle_negative[m]) angle_type[i][m] = -angle_type[i][m]; } - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - } - - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - 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] = (tagint) ubuf(buf[m++]).i; - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - buf[m++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(bond_type[i][k]).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(num_angle[i]).d; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = ubuf(angle_type[i][k]).d; - buf[m++] = ubuf(angle_atom1[i][k]).d; - buf[m++] = ubuf(angle_atom2[i][k]).d; - buf[m++] = ubuf(angle_atom3[i][k]).d; - } - - buf[m++] = ubuf(nspecial[i][0]).d; - buf[m++] = ubuf(nspecial[i][1]).d; - buf[m++] = ubuf(nspecial[i][2]).d; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = ubuf(special[i][k]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_angle[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = (int) ubuf(buf[m++]).i; - angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - nspecial[nlocal][0] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][1] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][2] = (int) ubuf(buf[m++]).i; - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = (tagint) ubuf(buf[m++]).i; - - 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++] = 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++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(MAX(bond_type[i][k],-bond_type[i][k])).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(num_angle[i]).d; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = ubuf(MAX(angle_type[i][k],-angle_type[i][k])).d; - buf[m++] = ubuf(angle_atom1[i][k]).d; - buf[m++] = ubuf(angle_atom2[i][k]).d; - buf[m++] = ubuf(angle_atom3[i][k]).d; - } - - 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 + initialize other atom quantities ------------------------------------------------------------------------- */ int AtomVecAngle::unpack_restart(double *buf) { - int k; + AtomVec::unpack_restart(buf); + int ilocal = atom->nlocal-1; - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_angle[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = (int) ubuf(buf[m++]).i; - angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecAngle::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - molecule[nlocal] = utils::tnumeric(FLERR,values[1],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[2],true,lmp); - 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] = utils::tnumeric(FLERR,values[0],true,lmp); - - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(molecule[i]).d; - buf[i][2] = ubuf(type[i]).d; - buf[i][3] = x[i][0]; - buf[i][4] = x[i][1]; - buf[i][5] = x[i][2]; - buf[i][6] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - pack hybrid atom info for data file -------------------------------------------------------------------------- */ - -int AtomVecAngle::pack_data_hybrid(int i, double *buf) -{ - buf[0] = ubuf(molecule[i]).d; - 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,TAGINT_FORMAT " " TAGINT_FORMAT - " %d %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(tagint) ubuf(buf[i][1]).i, - (int) ubuf(buf[i][2]).i, - buf[i][3],buf[i][4],buf[i][5], - (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, - (int) ubuf(buf[i][8]).i); -} - -/* ---------------------------------------------------------------------- - write hybrid atom info to data file -------------------------------------------------------------------------- */ - -int AtomVecAngle::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," " TAGINT_FORMAT,(tagint) ubuf(buf[0]).i); - 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; + atom->num_bond[ilocal] = 0; + atom->num_angle[ilocal] = 0; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } diff --git a/src/MOLECULE/atom_vec_angle.h b/src/MOLECULE/atom_vec_angle.h index 9030cce0d8..6511b517ee 100644 --- a/src/MOLECULE/atom_vec_angle.h +++ b/src/MOLECULE/atom_vec_angle.h @@ -27,50 +27,14 @@ namespace LAMMPS_NS { class AtomVecAngle : public AtomVec { public: AtomVecAngle(class LAMMPS *); - virtual ~AtomVecAngle() {} - void grow(int); - void grow_reset(); - void copy(int, int, int); - virtual int pack_comm(int, int *, double *, int, int *); - virtual int pack_comm_vel(int, int *, double *, int, int *); - virtual void unpack_comm(int, int, double *); - virtual void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - virtual int pack_border(int, int *, double *, int, int *); - virtual int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - virtual void unpack_border(int, int, double *); - virtual void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - virtual int pack_exchange(int, double *); - virtual int unpack_exchange(double *); - int size_restart(); + ~AtomVecAngle(); int pack_restart(int, double *); int unpack_restart(double *); - void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - protected: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - tagint *molecule; - int **nspecial; - tagint **special; - int *num_bond; - int **bond_type; - tagint **bond_atom; - int *num_angle; - int **angle_type; - tagint **angle_atom1,**angle_atom2,**angle_atom3; + private: + int bond_per_atom,angle_per_atom; + int *bond_negative,*angle_negative; }; } @@ -80,13 +44,4 @@ class AtomVecAngle : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp index 0bcd614f94..20cdfdd65a 100644 --- a/src/MOLECULE/atom_vec_bond.cpp +++ b/src/MOLECULE/atom_vec_bond.cpp @@ -13,13 +13,6 @@ #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" -#include "utils.h" using namespace LAMMPS_NS; @@ -31,829 +24,113 @@ AtomVecBond::AtomVecBond(LAMMPS *lmp) : AtomVec(lmp) 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; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) + "molecule num_bond bond_type bond_atom nspecial special"; + fields_copy = (char *) + "molecule num_bond bond_type bond_atom nspecial special"; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = (char *) "molecule"; + fields_border_vel = (char *) "molecule"; + fields_exchange = (char *) + "molecule num_bond bond_type bond_atom nspecial special"; + fields_restart = (char *) "molecule num_bond bond_type bond_atom"; + fields_create = (char *) "molecule num_bond nspecial"; + fields_data_atom = (char *) "id molecule type x"; + fields_data_vel = NULL; + + setup_fields(); + + bond_per_atom = 0; + bond_negative = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecBond::~AtomVecBond() +{ + delete [] bond_negative; } /* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n + pack atom I's data for restart file + modify/unmodify values for default AtomVec::pack_restart() to pack ------------------------------------------------------------------------- */ -void AtomVecBond::grow(int n) +int AtomVecBond::pack_restart(int i, double *buf) { - if (n == 0) grow_nmax(); - else nmax = n; - atom->nmax = nmax; - if (nmax < 0 || nmax > MAXSMALLINT) - error->one(FLERR,"Per-processor system is too big"); + // insure bond_negative vector is needed length - 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]; + if (bond_per_atom < atom->bond_per_atom) { + delete [] bond_negative; + bond_per_atom = atom->bond_per_atom; + bond_negative = new int[bond_per_atom]; } - 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]; + // flip any negative types to positive and flag which ones - 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 *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; -/* ---------------------------------------------------------------------- */ - -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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - } - } 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - } + int any_bond_negative = 0; + for (int m = 0; m < num_bond[i]; m++) { + if (bond_type[i][m] < 0) { + bond_negative[m] = 1; + bond_type[i][m] = -bond_type[i][m]; + any_bond_negative = 1; + } else bond_negative[m] = 0; } - 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]); + // perform the pack with adjusted values - return m; -} + int n = AtomVec::pack_restart(i,buf); -/* ---------------------------------------------------------------------- */ + // restore the flagged types to their negative values -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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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 (any_bond_negative) { + for (int m = 0; m < num_bond[i]; m++) + if (bond_negative[m]) bond_type[i][m] = -bond_type[i][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 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++] = ubuf(molecule[j]).d; - } - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - } - - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - 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] = (tagint) ubuf(buf[m++]).i; - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - buf[m++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(bond_type[i][k]).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(nspecial[i][0]).d; - buf[m++] = ubuf(nspecial[i][1]).d; - buf[m++] = ubuf(nspecial[i][2]).d; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = ubuf(special[i][k]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - nspecial[nlocal][0] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][1] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][2] = (int) ubuf(buf[m++]).i; - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = (tagint) ubuf(buf[m++]).i; - - 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++] = 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++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(MAX(bond_type[i][k],-bond_type[i][k])).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - 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 + initialize other atom quantities ------------------------------------------------------------------------- */ int AtomVecBond::unpack_restart(double *buf) { - int k; + AtomVec::unpack_restart(buf); + int ilocal = atom->nlocal-1; - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecBond::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - molecule[nlocal] = utils::tnumeric(FLERR,values[1],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[2],true,lmp); - 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] = utils::tnumeric(FLERR,values[0],true,lmp); - - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(molecule[i]).d; - buf[i][2] = ubuf(type[i]).d; - buf[i][3] = x[i][0]; - buf[i][4] = x[i][1]; - buf[i][5] = x[i][2]; - buf[i][6] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - pack hybrid atom info for data file -------------------------------------------------------------------------- */ - -int AtomVecBond::pack_data_hybrid(int i, double *buf) -{ - buf[0] = ubuf(molecule[i]).d; - 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,TAGINT_FORMAT " " TAGINT_FORMAT - " %d %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(tagint) ubuf(buf[i][1]).i, - (int) ubuf(buf[i][2]).i, - buf[i][3],buf[i][4],buf[i][5], - (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, - (int) ubuf(buf[i][8]).i); -} - -/* ---------------------------------------------------------------------- - write hybrid atom info to data file -------------------------------------------------------------------------- */ - -int AtomVecBond::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," " TAGINT_FORMAT,(tagint) ubuf(buf[0]).i); - 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; + atom->num_bond[ilocal] = 0; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } diff --git a/src/MOLECULE/atom_vec_bond.h b/src/MOLECULE/atom_vec_bond.h index d7370d4659..9245bc317a 100644 --- a/src/MOLECULE/atom_vec_bond.h +++ b/src/MOLECULE/atom_vec_bond.h @@ -27,46 +27,14 @@ namespace LAMMPS_NS { class AtomVecBond : public AtomVec { public: AtomVecBond(class LAMMPS *); - void grow(int); - void grow_reset(); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); + ~AtomVecBond(); int pack_restart(int, double *); int unpack_restart(double *); - void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); private: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - tagint *molecule; - int **nspecial; - tagint **special; - int *num_bond; - int **bond_type; - tagint **bond_atom; + int bond_per_atom; + int *bond_negative; }; } @@ -76,13 +44,4 @@ class AtomVecBond : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp index 76c60ba121..826d5fea4e 100644 --- a/src/MOLECULE/atom_vec_full.cpp +++ b/src/MOLECULE/atom_vec_full.cpp @@ -13,13 +13,6 @@ #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" -#include "utils.h" using namespace LAMMPS_NS; @@ -31,1078 +24,204 @@ AtomVecFull::AtomVecFull(LAMMPS *lmp) : AtomVec(lmp) 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; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) + "q molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4 " + "nspecial special"; + fields_copy = (char *) + "q molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4 " + "nspecial special"; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = (char *) "q molecule"; + fields_border_vel = (char *) "q molecule"; + fields_exchange = (char *) + "q molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4 " + "nspecial special"; + fields_restart = (char *) + "q molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4"; + fields_create = (char *) + "q molecule num_bond num_angle num_dihedral num_improper nspecial"; + fields_data_atom = (char *) "id molecule type q x"; + fields_data_vel = NULL; + + setup_fields(); + + bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0; + bond_negative = angle_negative = dihedral_negative = improper_negative = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecFull::~AtomVecFull() +{ + delete [] bond_negative; + delete [] angle_negative; + delete [] dihedral_negative; + delete [] improper_negative; } /* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n + pack atom I's data for restart file + modify/unmodify values for default AtomVec::pack_restart() to pack ------------------------------------------------------------------------- */ -void AtomVecFull::grow(int n) +int AtomVecFull::pack_restart(int i, double *buf) { - if (n == 0) grow_nmax(); - else nmax = n; - atom->nmax = nmax; - if (nmax < 0 || nmax > MAXSMALLINT) - error->one(FLERR,"Per-processor system is too big"); + // insure negative vectors are needed length - 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]; + if (bond_per_atom < atom->bond_per_atom) { + delete [] bond_negative; + bond_per_atom = atom->bond_per_atom; + bond_negative = new int[bond_per_atom]; + } + if (angle_per_atom < atom->angle_per_atom) { + delete [] angle_negative; + angle_per_atom = atom->angle_per_atom; + angle_negative = new int[angle_per_atom]; + } + if (dihedral_per_atom < atom->dihedral_per_atom) { + delete [] dihedral_negative; + dihedral_per_atom = atom->dihedral_per_atom; + dihedral_negative = new int[dihedral_per_atom]; + } + if (improper_per_atom < atom->improper_per_atom) { + delete [] improper_negative; + improper_per_atom = atom->improper_per_atom; + improper_negative = new int[improper_per_atom]; } - 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]; + // flip any negative types to positive and flag which ones + + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + int *num_angle = atom->num_angle; + int **angle_type = atom->angle_type; + int *num_dihedral = atom->num_dihedral; + int **dihedral_type = atom->dihedral_type; + int *num_improper = atom->num_improper; + int **improper_type = atom->improper_type; + + int any_bond_negative = 0; + for (int m = 0; m < num_bond[i]; m++) { + if (bond_type[i][m] < 0) { + bond_negative[m] = 1; + bond_type[i][m] = -bond_type[i][m]; + any_bond_negative = 1; + } else bond_negative[m] = 0; } - 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]; + int any_angle_negative = 0; + for (int m = 0; m < num_angle[i]; m++) { + if (angle_type[i][m] < 0) { + angle_negative[m] = 1; + angle_type[i][m] = -angle_type[i][m]; + any_angle_negative = 1; + } else angle_negative[m] = 0; } - 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]; + int any_dihedral_negative = 0; + for (int m = 0; m < num_dihedral[i]; m++) { + if (dihedral_type[i][m] < 0) { + dihedral_negative[m] = 1; + dihedral_type[i][m] = -dihedral_type[i][m]; + any_dihedral_negative = 1; + } else dihedral_negative[m] = 0; } - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = q[j]; - buf[m++] = ubuf(molecule[j]).d; - } - } 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = q[j]; - buf[m++] = ubuf(molecule[j]).d; - } + int any_improper_negative = 0; + for (int m = 0; m < num_improper[i]; m++) { + if (improper_type[i][m] < 0) { + improper_negative[m] = 1; + improper_type[i][m] = -improper_type[i][m]; + any_improper_negative = 1; + } else improper_negative[m] = 0; } - 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]); + // perform the pack with adjusted values - return m; -} + int n = AtomVec::pack_restart(i,buf); -/* ---------------------------------------------------------------------- */ + // restore the flagged types to their negative values -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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = q[j]; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = q[j]; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = q[j]; - buf[m++] = ubuf(molecule[j]).d; - 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 (any_bond_negative) { + for (int m = 0; m < num_bond[i]; m++) + if (bond_negative[m]) bond_type[i][m] = -bond_type[i][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 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++] = ubuf(molecule[j]).d; + if (any_angle_negative) { + for (int m = 0; m < num_angle[i]; m++) + if (angle_negative[m]) angle_type[i][m] = -angle_type[i][m]; } - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - q[i] = buf[m++]; - molecule[i] = (tagint) ubuf(buf[m++]).i; + if (any_dihedral_negative) { + for (int m = 0; m < num_dihedral[i]; m++) + if (dihedral_negative[m]) dihedral_type[i][m] = -dihedral_type[i][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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - q[i] = buf[m++]; - molecule[i] = (tagint) ubuf(buf[m++]).i; - v[i][0] = buf[m++]; - v[i][1] = buf[m++]; - v[i][2] = buf[m++]; + if (any_improper_negative) { + for (int m = 0; m < num_improper[i]; m++) + if (improper_negative[m]) improper_type[i][m] = -improper_type[i][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] = (tagint) ubuf(buf[m++]).i; - } - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - buf[m++] = q[i]; - buf[m++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(bond_type[i][k]).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(num_angle[i]).d; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = ubuf(angle_type[i][k]).d; - buf[m++] = ubuf(angle_atom1[i][k]).d; - buf[m++] = ubuf(angle_atom2[i][k]).d; - buf[m++] = ubuf(angle_atom3[i][k]).d; - } - - buf[m++] = ubuf(num_dihedral[i]).d; - for (k = 0; k < num_dihedral[i]; k++) { - buf[m++] = ubuf(dihedral_type[i][k]).d; - buf[m++] = ubuf(dihedral_atom1[i][k]).d; - buf[m++] = ubuf(dihedral_atom2[i][k]).d; - buf[m++] = ubuf(dihedral_atom3[i][k]).d; - buf[m++] = ubuf(dihedral_atom4[i][k]).d; - } - - buf[m++] = ubuf(num_improper[i]).d; - for (k = 0; k < num_improper[i]; k++) { - buf[m++] = ubuf(improper_type[i][k]).d; - buf[m++] = ubuf(improper_atom1[i][k]).d; - buf[m++] = ubuf(improper_atom2[i][k]).d; - buf[m++] = ubuf(improper_atom3[i][k]).d; - buf[m++] = ubuf(improper_atom4[i][k]).d; - } - - buf[m++] = ubuf(nspecial[i][0]).d; - buf[m++] = ubuf(nspecial[i][1]).d; - buf[m++] = ubuf(nspecial[i][2]).d; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = ubuf(special[i][k]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - q[nlocal] = buf[m++]; - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_angle[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = (int) ubuf(buf[m++]).i; - angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_dihedral[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_dihedral[nlocal]; k++) { - dihedral_type[nlocal][k] = (int) ubuf(buf[m++]).i; - dihedral_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_improper[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_improper[nlocal]; k++) { - improper_type[nlocal][k] = (int) ubuf(buf[m++]).i; - improper_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - nspecial[nlocal][0] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][1] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][2] = (int) ubuf(buf[m++]).i; - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = (tagint) ubuf(buf[m++]).i; - - 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++] = 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++] = q[i]; - buf[m++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(MAX(bond_type[i][k],-bond_type[i][k])).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(num_angle[i]).d; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = ubuf(MAX(angle_type[i][k],-angle_type[i][k])).d; - buf[m++] = ubuf(angle_atom1[i][k]).d; - buf[m++] = ubuf(angle_atom2[i][k]).d; - buf[m++] = ubuf(angle_atom3[i][k]).d; - } - - buf[m++] = ubuf(num_dihedral[i]).d; - for (k = 0; k < num_dihedral[i]; k++) { - buf[m++] = ubuf(MAX(dihedral_type[i][k],-dihedral_type[i][k])).d; - buf[m++] = ubuf(dihedral_atom1[i][k]).d; - buf[m++] = ubuf(dihedral_atom2[i][k]).d; - buf[m++] = ubuf(dihedral_atom3[i][k]).d; - buf[m++] = ubuf(dihedral_atom4[i][k]).d; - } - - buf[m++] = ubuf(num_improper[i]).d; - for (k = 0; k < num_improper[i]; k++) { - buf[m++] = ubuf(MAX(improper_type[i][k],-improper_type[i][k])).d; - buf[m++] = ubuf(improper_atom1[i][k]).d; - buf[m++] = ubuf(improper_atom2[i][k]).d; - buf[m++] = ubuf(improper_atom3[i][k]).d; - buf[m++] = ubuf(improper_atom4[i][k]).d; - } - - 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 + initialize other atom quantities ------------------------------------------------------------------------- */ int AtomVecFull::unpack_restart(double *buf) { - int k; + AtomVec::unpack_restart(buf); + int ilocal = atom->nlocal-1; - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - q[nlocal] = buf[m++]; - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_angle[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = (int) ubuf(buf[m++]).i; - angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_dihedral[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_dihedral[nlocal]; k++) { - dihedral_type[nlocal][k] = (int) ubuf(buf[m++]).i; - dihedral_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_improper[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_improper[nlocal]; k++) { - improper_type[nlocal][k] = (int) ubuf(buf[m++]).i; - improper_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecFull::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - molecule[nlocal] = utils::tnumeric(FLERR,values[1],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[2],true,lmp); - if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one(FLERR,"Invalid atom type in Atoms section of data file"); - - q[nlocal] = utils::numeric(FLERR,values[3],true,lmp); - - 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] = utils::tnumeric(FLERR,values[0],true,lmp); - q[nlocal] = utils::numeric(FLERR,values[1],true,lmp); - - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(molecule[i]).d; - buf[i][2] = ubuf(type[i]).d; - 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] = 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 AtomVecFull::pack_data_hybrid(int i, double *buf) -{ - buf[0] = ubuf(molecule[i]).d; - 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,TAGINT_FORMAT " " TAGINT_FORMAT - " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(tagint) ubuf(buf[i][1]).i, - (int) ubuf(buf[i][2]).i, - buf[i][3],buf[i][4],buf[i][5],buf[i][6], - (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 AtomVecFull::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," " TAGINT_FORMAT " %-1.16e",(tagint) ubuf(buf[0]).i,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; + atom->num_bond[ilocal] = 0; + atom->num_angle[ilocal] = 0; + atom->num_dihedral[ilocal] = 0; + atom->num_improper[ilocal] = 0; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } diff --git a/src/MOLECULE/atom_vec_full.h b/src/MOLECULE/atom_vec_full.h index abaf570b17..b194a86994 100644 --- a/src/MOLECULE/atom_vec_full.h +++ b/src/MOLECULE/atom_vec_full.h @@ -27,57 +27,14 @@ namespace LAMMPS_NS { class AtomVecFull : public AtomVec { public: AtomVecFull(class LAMMPS *); - virtual ~AtomVecFull() {} - void grow(int); - void grow_reset(); - void copy(int, int, int); - virtual int pack_comm(int, int *, double *, int, int *); - virtual int pack_comm_vel(int, int *, double *, int, int *); - virtual void unpack_comm(int, int, double *); - virtual void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - virtual int pack_border(int, int *, double *, int, int *); - virtual int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - virtual void unpack_border(int, int, double *); - virtual void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - virtual int pack_exchange(int, double *); - virtual int unpack_exchange(double *); - int size_restart(); + ~AtomVecFull(); int pack_restart(int, double *); int unpack_restart(double *); - void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - protected: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - double *q; - tagint *molecule; - int **nspecial; - tagint **special; - int *num_bond; - int **bond_type; - tagint **bond_atom; - int *num_angle; - int **angle_type; - tagint **angle_atom1,**angle_atom2,**angle_atom3; - int *num_dihedral; - int **dihedral_type; - tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4; - int *num_improper; - int **improper_type; - tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4; + private: + int bond_per_atom,angle_per_atom,dihedral_per_atom,improper_per_atom; + int *bond_negative,*angle_negative,*dihedral_negative,*improper_negative; }; } @@ -87,13 +44,4 @@ class AtomVecFull : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp index 73cec70456..dad7c5cea6 100644 --- a/src/MOLECULE/atom_vec_molecular.cpp +++ b/src/MOLECULE/atom_vec_molecular.cpp @@ -13,13 +13,6 @@ #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" -#include "utils.h" using namespace LAMMPS_NS; @@ -31,1056 +24,204 @@ AtomVecMolecular::AtomVecMolecular(LAMMPS *lmp) : AtomVec(lmp) 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; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4 " + "nspecial special"; + fields_copy = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4 " + "nspecial special"; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = (char *) "molecule"; + fields_border_vel = (char *) "molecule"; + fields_exchange = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4 " + "nspecial special"; + fields_restart = (char *) + "molecule num_bond bond_type bond_atom " + "num_angle angle_type angle_atom1 angle_atom2 angle_atom3 " + "num_dihedral dihedral_type dihedral_atom1 dihedral_atom2 " + "dihedral_atom3 dihedral_atom4 " + "num_improper improper_type improper_atom1 improper_atom2 " + "improper_atom3 improper_atom4"; + fields_create = (char *) + "molecule num_bond num_angle num_dihedral num_improper nspecial"; + fields_data_atom = (char *) "id molecule type x"; + fields_data_vel = NULL; + + setup_fields(); + + bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0; + bond_negative = angle_negative = dihedral_negative = improper_negative = NULL; +} + +/* ---------------------------------------------------------------------- */ + +AtomVecMolecular::~AtomVecMolecular() +{ + delete [] bond_negative; + delete [] angle_negative; + delete [] dihedral_negative; + delete [] improper_negative; } /* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n + pack atom I's data for restart file + modify/unmodify values for default AtomVec::pack_restart() to pack ------------------------------------------------------------------------- */ -void AtomVecMolecular::grow(int n) +int AtomVecMolecular::pack_restart(int i, double *buf) { - if (n == 0) grow_nmax(); - else nmax = n; - atom->nmax = nmax; - if (nmax < 0 || nmax > MAXSMALLINT) - error->one(FLERR,"Per-processor system is too big"); + // insure negative vectors are needed length - 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]; + if (bond_per_atom < atom->bond_per_atom) { + delete [] bond_negative; + bond_per_atom = atom->bond_per_atom; + bond_negative = new int[bond_per_atom]; + } + if (angle_per_atom < atom->angle_per_atom) { + delete [] angle_negative; + angle_per_atom = atom->angle_per_atom; + angle_negative = new int[angle_per_atom]; + } + if (dihedral_per_atom < atom->dihedral_per_atom) { + delete [] dihedral_negative; + dihedral_per_atom = atom->dihedral_per_atom; + dihedral_negative = new int[dihedral_per_atom]; + } + if (improper_per_atom < atom->improper_per_atom) { + delete [] improper_negative; + improper_per_atom = atom->improper_per_atom; + improper_negative = new int[improper_per_atom]; } - 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]; + // flip any negative types to positive and flag which ones + + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + int *num_angle = atom->num_angle; + int **angle_type = atom->angle_type; + int *num_dihedral = atom->num_dihedral; + int **dihedral_type = atom->dihedral_type; + int *num_improper = atom->num_improper; + int **improper_type = atom->improper_type; + + int any_bond_negative = 0; + for (int m = 0; m < num_bond[i]; m++) { + if (bond_type[i][m] < 0) { + bond_negative[m] = 1; + bond_type[i][m] = -bond_type[i][m]; + any_bond_negative = 1; + } else bond_negative[m] = 0; } - 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]; + int any_angle_negative = 0; + for (int m = 0; m < num_angle[i]; m++) { + if (angle_type[i][m] < 0) { + angle_negative[m] = 1; + angle_type[i][m] = -angle_type[i][m]; + any_angle_negative = 1; + } else angle_negative[m] = 0; } - 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]; + int any_dihedral_negative = 0; + for (int m = 0; m < num_dihedral[i]; m++) { + if (dihedral_type[i][m] < 0) { + dihedral_negative[m] = 1; + dihedral_type[i][m] = -dihedral_type[i][m]; + any_dihedral_negative = 1; + } else dihedral_negative[m] = 0; } - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - } - } 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - } + int any_improper_negative = 0; + for (int m = 0; m < num_improper[i]; m++) { + if (improper_type[i][m] < 0) { + improper_negative[m] = 1; + improper_type[i][m] = -improper_type[i][m]; + any_improper_negative = 1; + } else improper_negative[m] = 0; } - 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]); + // perform the pack with adjusted values - return m; -} + int n = AtomVec::pack_restart(i,buf); -/* ---------------------------------------------------------------------- */ + // restore the flagged types to their negative values -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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - 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 (any_bond_negative) { + for (int m = 0; m < num_bond[i]; m++) + if (bond_negative[m]) bond_type[i][m] = -bond_type[i][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 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++] = ubuf(molecule[j]).d; + if (any_angle_negative) { + for (int m = 0; m < num_angle[i]; m++) + if (angle_negative[m]) angle_type[i][m] = -angle_type[i][m]; } - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; + if (any_dihedral_negative) { + for (int m = 0; m < num_dihedral[i]; m++) + if (dihedral_negative[m]) dihedral_type[i][m] = -dihedral_type[i][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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - v[i][0] = buf[m++]; - v[i][1] = buf[m++]; - v[i][2] = buf[m++]; + if (any_improper_negative) { + for (int m = 0; m < num_improper[i]; m++) + if (improper_negative[m]) improper_type[i][m] = -improper_type[i][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] = (tagint) ubuf(buf[m++]).i; - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - buf[m++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(bond_type[i][k]).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(num_angle[i]).d; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = ubuf(angle_type[i][k]).d; - buf[m++] = ubuf(angle_atom1[i][k]).d; - buf[m++] = ubuf(angle_atom2[i][k]).d; - buf[m++] = ubuf(angle_atom3[i][k]).d; - } - - buf[m++] = ubuf(num_dihedral[i]).d; - for (k = 0; k < num_dihedral[i]; k++) { - buf[m++] = ubuf(dihedral_type[i][k]).d; - buf[m++] = ubuf(dihedral_atom1[i][k]).d; - buf[m++] = ubuf(dihedral_atom2[i][k]).d; - buf[m++] = ubuf(dihedral_atom3[i][k]).d; - buf[m++] = ubuf(dihedral_atom4[i][k]).d; - } - - buf[m++] = ubuf(num_improper[i]).d; - for (k = 0; k < num_improper[i]; k++) { - buf[m++] = ubuf(improper_type[i][k]).d; - buf[m++] = ubuf(improper_atom1[i][k]).d; - buf[m++] = ubuf(improper_atom2[i][k]).d; - buf[m++] = ubuf(improper_atom3[i][k]).d; - buf[m++] = ubuf(improper_atom4[i][k]).d; - } - - buf[m++] = ubuf(nspecial[i][0]).d; - buf[m++] = ubuf(nspecial[i][1]).d; - buf[m++] = ubuf(nspecial[i][2]).d; - for (k = 0; k < nspecial[i][2]; k++) buf[m++] = ubuf(special[i][k]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_angle[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = (int) ubuf(buf[m++]).i; - angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_dihedral[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_dihedral[nlocal]; k++) { - dihedral_type[nlocal][k] = (int) ubuf(buf[m++]).i; - dihedral_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_improper[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_improper[nlocal]; k++) { - improper_type[nlocal][k] = (int) ubuf(buf[m++]).i; - improper_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - nspecial[nlocal][0] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][1] = (int) ubuf(buf[m++]).i; - nspecial[nlocal][2] = (int) ubuf(buf[m++]).i; - for (k = 0; k < nspecial[nlocal][2]; k++) - special[nlocal][k] = (int) ubuf(buf[m++]).i; - - 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++] = 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++] = ubuf(molecule[i]).d; - - buf[m++] = ubuf(num_bond[i]).d; - for (k = 0; k < num_bond[i]; k++) { - buf[m++] = ubuf(MAX(bond_type[i][k],-bond_type[i][k])).d; - buf[m++] = ubuf(bond_atom[i][k]).d; - } - - buf[m++] = ubuf(num_angle[i]).d; - for (k = 0; k < num_angle[i]; k++) { - buf[m++] = ubuf(MAX(angle_type[i][k],-angle_type[i][k])).d; - buf[m++] = ubuf(angle_atom1[i][k]).d; - buf[m++] = ubuf(angle_atom2[i][k]).d; - buf[m++] = ubuf(angle_atom3[i][k]).d; - } - - buf[m++] = ubuf(num_dihedral[i]).d; - for (k = 0; k < num_dihedral[i]; k++) { - buf[m++] = ubuf(MAX(dihedral_type[i][k],-dihedral_type[i][k])).d; - buf[m++] = ubuf(dihedral_atom1[i][k]).d; - buf[m++] = ubuf(dihedral_atom2[i][k]).d; - buf[m++] = ubuf(dihedral_atom3[i][k]).d; - buf[m++] = ubuf(dihedral_atom4[i][k]).d; - } - - buf[m++] = ubuf(num_improper[i]).d; - for (k = 0; k < num_improper[i]; k++) { - buf[m++] = ubuf(MAX(improper_type[i][k],-improper_type[i][k])).d; - buf[m++] = ubuf(improper_atom1[i][k]).d; - buf[m++] = ubuf(improper_atom2[i][k]).d; - buf[m++] = ubuf(improper_atom3[i][k]).d; - buf[m++] = ubuf(improper_atom4[i][k]).d; - } - - 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 + initialize other atom quantities ------------------------------------------------------------------------- */ int AtomVecMolecular::unpack_restart(double *buf) { - int k; + AtomVec::unpack_restart(buf); + int ilocal = atom->nlocal-1; - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - - num_bond[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_bond[nlocal]; k++) { - bond_type[nlocal][k] = (int) ubuf(buf[m++]).i; - bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_angle[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_angle[nlocal]; k++) { - angle_type[nlocal][k] = (int) ubuf(buf[m++]).i; - angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_dihedral[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_dihedral[nlocal]; k++) { - dihedral_type[nlocal][k] = (int) ubuf(buf[m++]).i; - dihedral_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - dihedral_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - num_improper[nlocal] = (int) ubuf(buf[m++]).i; - for (k = 0; k < num_improper[nlocal]; k++) { - improper_type[nlocal][k] = (int) ubuf(buf[m++]).i; - improper_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i; - improper_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i; - } - - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ -void AtomVecMolecular::data_atom(double *coord, imageint imagetmp, - char **values) +void AtomVecMolecular::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - molecule[nlocal] = utils::tnumeric(FLERR,values[1],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[2],true,lmp); - 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] = utils::tnumeric(FLERR,values[0],true,lmp); - - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(molecule[i]).d; - buf[i][2] = ubuf(type[i]).d; - buf[i][3] = x[i][0]; - buf[i][4] = x[i][1]; - buf[i][5] = x[i][2]; - buf[i][6] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - pack hybrid atom info for data file -------------------------------------------------------------------------- */ - -int AtomVecMolecular::pack_data_hybrid(int i, double *buf) -{ - buf[0] = ubuf(molecule[i]).d; - 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,TAGINT_FORMAT " " TAGINT_FORMAT - " %d %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(tagint) ubuf(buf[i][1]).i, - (int) ubuf(buf[i][2]).i, - buf[i][3],buf[i][4],buf[i][5], - (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, - (int) ubuf(buf[i][8]).i); -} - -/* ---------------------------------------------------------------------- - write hybrid atom info to data file -------------------------------------------------------------------------- */ - -int AtomVecMolecular::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," " TAGINT_FORMAT,(tagint) ubuf(buf[0]).i); - 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; + atom->num_bond[ilocal] = 0; + atom->num_angle[ilocal] = 0; + atom->num_dihedral[ilocal] = 0; + atom->num_improper[ilocal] = 0; + atom->nspecial[ilocal][0] = 0; + atom->nspecial[ilocal][1] = 0; + atom->nspecial[ilocal][2] = 0; } diff --git a/src/MOLECULE/atom_vec_molecular.h b/src/MOLECULE/atom_vec_molecular.h index 19104c3987..cba6d1b480 100644 --- a/src/MOLECULE/atom_vec_molecular.h +++ b/src/MOLECULE/atom_vec_molecular.h @@ -27,55 +27,14 @@ namespace LAMMPS_NS { class AtomVecMolecular : public AtomVec { public: AtomVecMolecular(class LAMMPS *); - void grow(int); - void grow_reset(); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); + ~AtomVecMolecular(); int pack_restart(int, double *); int unpack_restart(double *); - void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); private: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - tagint *molecule; - int **nspecial; - tagint **special; - int *num_bond; - int **bond_type; - tagint **bond_atom; - int *num_angle; - int **angle_type; - tagint **angle_atom1,**angle_atom2,**angle_atom3; - int *num_dihedral; - int **dihedral_type; - tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4; - int *num_improper; - int **improper_type; - tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4; + int bond_per_atom,angle_per_atom,dihedral_per_atom,improper_per_atom; + int *bond_negative,*angle_negative,*dihedral_negative,*improper_negative; }; } @@ -85,13 +44,4 @@ class AtomVecMolecular : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/MOLECULE/atom_vec_template.cpp b/src/MOLECULE/atom_vec_template.cpp index c9ccfc6d2b..31d9af4caf 100644 --- a/src/MOLECULE/atom_vec_template.cpp +++ b/src/MOLECULE/atom_vec_template.cpp @@ -31,16 +31,27 @@ AtomVecTemplate::AtomVecTemplate(LAMMPS *lmp) : AtomVec(lmp) molecular = 2; mass_type = 1; - comm_x_only = comm_f_only = 1; - size_forward = 3; - size_reverse = 3; - size_border = 9; - size_velocity = 3; - size_data_atom = 8; - size_data_vel = 4; - xcol_data = 6; - atom->molecule_flag = 1; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) "molecule molindex molatom"; + fields_copy = (char *) "molecule molindex molatom"; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = (char *) "molecule molindex molatom"; + fields_border_vel = (char *) "molecule molindex molatom"; + fields_exchange = (char *) "molecule molindex molatom"; + fields_restart = (char *) "molecule molindex molatom"; + fields_create = (char *) "molecule molindex molatom"; + fields_data_atom = (char *) "id molecule molindex molatom type x"; + fields_data_vel = NULL; + + setup_fields(); } /* ---------------------------------------------------------------------- @@ -85,786 +96,35 @@ void AtomVecTemplate::process_args(int narg, char **arg) } } -/* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecTemplate::grow(int n) -{ - if (n == 0) grow_nmax(); - 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"); - molindex = memory->grow(atom->molindex,nmax,"atom:molindex"); - molatom = memory->grow(atom->molatom,nmax,"atom:molatom"); - - 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 AtomVecTemplate::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; - molindex = atom->molindex; molatom = atom->molatom; -} - -/* ---------------------------------------------------------------------- - copy atom I info to atom J -------------------------------------------------------------------------- */ - -void AtomVecTemplate::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]; - molindex[j] = molindex[i]; - molatom[j] = molatom[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 AtomVecTemplate::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 AtomVecTemplate::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 AtomVecTemplate::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 AtomVecTemplate::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 AtomVecTemplate::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 AtomVecTemplate::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 AtomVecTemplate::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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - buf[m++] = ubuf(molindex[j]).d; - buf[m++] = ubuf(molatom[j]).d; - } - } 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - buf[m++] = ubuf(molindex[j]).d; - buf[m++] = ubuf(molatom[j]).d; - } - } - - 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 AtomVecTemplate::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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - buf[m++] = ubuf(molindex[j]).d; - buf[m++] = ubuf(molatom[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - buf[m++] = ubuf(molindex[j]).d; - buf[m++] = ubuf(molatom[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = ubuf(molecule[j]).d; - buf[m++] = ubuf(molindex[j]).d; - buf[m++] = ubuf(molatom[j]).d; - 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 AtomVecTemplate::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++] = ubuf(molecule[j]).d; - buf[m++] = ubuf(molindex[j]).d; - buf[m++] = ubuf(molatom[j]).d; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecTemplate::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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - molindex[i] = (int) ubuf(buf[m++]).i; - molatom[i] = (int) ubuf(buf[m++]).i; - } - - 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 AtomVecTemplate::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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - molecule[i] = (tagint) ubuf(buf[m++]).i; - molindex[i] = (int) ubuf(buf[m++]).i; - molatom[i] = (int) ubuf(buf[m++]).i; - 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 AtomVecTemplate::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] = (tagint) ubuf(buf[m++]).i; - molindex[i] = (int) ubuf(buf[m++]).i; - molatom[i] = (int) ubuf(buf[m++]).i; - } - 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 AtomVecTemplate::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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - buf[m++] = ubuf(molecule[i]).d; - buf[m++] = ubuf(molindex[i]).d; - buf[m++] = ubuf(molatom[i]).d; - - 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 AtomVecTemplate::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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - molindex[nlocal] = (int) ubuf(buf[m++]).i; - molatom[nlocal] = (int) ubuf(buf[m++]).i; - - 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 AtomVecTemplate::size_restart() -{ - int i; - - int nlocal = atom->nlocal; - int n = 14 * 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 AtomVecTemplate::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++] = 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++] = ubuf(molecule[i]).d; - buf[m++] = ubuf(molindex[i]).d; - buf[m++] = ubuf(molatom[i]).d; - - 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 AtomVecTemplate::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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - molecule[nlocal] = (tagint) ubuf(buf[m++]).i; - molindex[nlocal] = (int) ubuf(buf[m++]).i; - molatom[nlocal] = (int) ubuf(buf[m++]).i; - - 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 + modify what default AtomVec::create_atom() just created ------------------------------------------------------------------------- */ void AtomVecTemplate::create_atom(int itype, double *coord) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::create_atom(itype,coord); - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) IMGMAX << IMGBITS) | IMGMAX; - v[nlocal][0] = 0.0; - v[nlocal][1] = 0.0; - v[nlocal][2] = 0.0; - - molecule[nlocal] = 0; - molindex[nlocal] = -1; - molatom[nlocal] = -1; - - atom->nlocal++; + int ilocal = atom->nlocal-1; + atom->molindex[ilocal] = -1; + atom->molatom[ilocal] = -1; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + error check what default AtomVec::data_atom() just unpacked ------------------------------------------------------------------------- */ void AtomVecTemplate::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - if (tag[nlocal] <= 0) - error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + int ilocal = atom->nlocal-1; + int molindex = atom->molindex[ilocal]; + int molatom = atom->molatom[ilocal]; - molecule[nlocal] = utils::tnumeric(FLERR,values[1],true,lmp); - molindex[nlocal] = utils::inumeric(FLERR,values[2],true,lmp) - 1; - molatom[nlocal] = utils::inumeric(FLERR,values[3],true,lmp) - 1; - - if (molindex[nlocal] < 0 || molindex[nlocal] >= nset) + if (molindex < 0 || molindex >= nset) error->one(FLERR,"Invalid template index in Atoms section of data file"); - if (molatom[nlocal] < 0 || - molatom[nlocal] >= onemols[molindex[nlocal]]->natoms) + if (molatom < 0 || molatom >= onemols[molindex]->natoms) error->one(FLERR,"Invalid template atom in Atoms section of data file"); - - type[nlocal] = utils::inumeric(FLERR,values[4],true,lmp); - 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++; -} - -/* ---------------------------------------------------------------------- - unpack hybrid quantities from one line in Atoms section of data file - initialize other atom quantities for this sub-style -------------------------------------------------------------------------- */ - -int AtomVecTemplate::data_atom_hybrid(int nlocal, char **values) -{ - molecule[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - molindex[nlocal] = utils::inumeric(FLERR,values[1],true,lmp) - 1; - molatom[nlocal] = utils::inumeric(FLERR,values[2],true,lmp) - 1; - return 3; -} - -/* ---------------------------------------------------------------------- - pack atom info for data file including 3 image flags -------------------------------------------------------------------------- */ - -void AtomVecTemplate::pack_data(double **buf) -{ - int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - buf[i][0] = ubuf(tag[i]).d; - buf[i][1] = ubuf(molecule[i]).d; - buf[i][2] = ubuf(molindex[i]+1).d; - buf[i][3] = ubuf(molatom[i]+1).d; - buf[i][4] = ubuf(type[i]).d; - buf[i][5] = x[i][0]; - buf[i][6] = x[i][1]; - buf[i][7] = x[i][2]; - buf[i][8] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][9] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][10] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - pack hybrid atom info for data file -------------------------------------------------------------------------- */ - -int AtomVecTemplate::pack_data_hybrid(int i, double *buf) -{ - buf[0] = ubuf(molecule[i]).d; - buf[1] = ubuf(molindex[i]+1).d; - buf[2] = ubuf(molatom[i]+1).d; - return 3; -} - -/* ---------------------------------------------------------------------- - write atom info to data file including 3 image flags -------------------------------------------------------------------------- */ - -void AtomVecTemplate::write_data(FILE *fp, int n, double **buf) -{ - for (int i = 0; i < n; i++) - fprintf(fp,TAGINT_FORMAT " " TAGINT_FORMAT - " %d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(tagint) ubuf(buf[i][1]).i, - (int) ubuf(buf[i][2]).i,(int) ubuf(buf[i][3]).i, - (int) ubuf(buf[i][4]).i, - buf[i][5],buf[i][6],buf[i][7], - (int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i, - (int) ubuf(buf[i][10]).i); -} - -/* ---------------------------------------------------------------------- - write hybrid atom info to data file -------------------------------------------------------------------------- */ - -int AtomVecTemplate::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," " TAGINT_FORMAT " %d %d", - (tagint) ubuf(buf[0]).i,(int) ubuf(buf[1]).i,(int) ubuf(buf[2]).i); - return 3; -} - -/* ---------------------------------------------------------------------- - return # of bytes of allocated memory -------------------------------------------------------------------------- */ - -bigint AtomVecTemplate::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("molindex")) bytes += memory->usage(molindex,nmax); - if (atom->memcheck("molatom")) bytes += memory->usage(molatom,nmax); - - return bytes; } diff --git a/src/MOLECULE/atom_vec_template.h b/src/MOLECULE/atom_vec_template.h index eee7fa9723..59a1386f2d 100644 --- a/src/MOLECULE/atom_vec_template.h +++ b/src/MOLECULE/atom_vec_template.h @@ -27,44 +27,9 @@ namespace LAMMPS_NS { class AtomVecTemplate : public AtomVec { public: AtomVecTemplate(class LAMMPS *); - virtual ~AtomVecTemplate() {} void process_args(int, char **); - void grow(int); - void grow_reset(); - void copy(int, int, int); - virtual int pack_comm(int, int *, double *, int, int *); - virtual int pack_comm_vel(int, int *, double *, int, int *); - virtual void unpack_comm(int, int, double *); - virtual void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - virtual int pack_border(int, int *, double *, int, int *); - virtual int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - virtual void unpack_border(int, int, double *); - virtual void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - virtual int pack_exchange(int, double *); - virtual int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); void create_atom(int, double *); - void data_atom(double *, tagint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - - protected: - tagint *tag; - int *type,*mask; - tagint *image; - double **x,**v,**f; - tagint *molecule; - int *molindex,*molatom; + void data_atom(double *, imageint, char **); }; } @@ -88,15 +53,6 @@ E: Atom style template molecule must have atom types The defined molecule(s) does not specify atom types. -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom ID in Atoms section of data file - -Atom IDs must be positive integers. - E: Invalid template index in Atoms section of data file The template indices must be between 1 to N, where N is the number of @@ -107,8 +63,4 @@ E: Invalid template atom in Atoms section of data file The atom indices must be between 1 to N, where N is the number of atoms in the template molecule the atom belongs to. -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp index 3e3312bf01..29c4cb0d83 100644 --- a/src/PERI/atom_vec_peri.cpp +++ b/src/PERI/atom_vec_peri.cpp @@ -19,14 +19,9 @@ #include #include #include "atom.h" -#include "comm.h" -#include "domain.h" -#include "modify.h" -#include "fix.h" #include "citeme.h" #include "memory.h" #include "error.h" -#include "utils.h" using namespace LAMMPS_NS; @@ -49,859 +44,67 @@ AtomVecPeri::AtomVecPeri(LAMMPS *lmp) : AtomVec(lmp) molecular = 0; - comm_x_only = 0; - comm_f_only = 1; - size_forward = 4; - size_reverse = 3; - size_border = 12; - size_velocity = 3; - size_data_atom = 7; - size_data_vel = 4; - xcol_data = 5; - + atom->rmass_flag = 1; atom->peri_flag = 1; - atom->vfrac_flag = atom->rmass_flag = 1; -} - -/* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecPeri::grow(int n) -{ - if (n == 0) grow_nmax(); - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = vfrac[j]; - buf[m++] = rmass[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = vfrac[j]; - buf[m++] = rmass[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = vfrac[j]; - buf[m++] = rmass[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = vfrac[j]; - buf[m++] = rmass[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = vfrac[j]; - buf[m++] = rmass[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++] = rmass[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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - 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] = 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - 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] = 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++]; - rmass[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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - 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++] = 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++] = 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - 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; + atom->vfrac_flag = 1; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) "rmass vfrac s0 x0"; + fields_copy = (char *) "rmass vfrac s0 x0"; + fields_comm = (char *) "s0"; + fields_comm_vel = (char *) "s0"; + fields_reverse = NULL; + fields_border = (char *) "rmass vfrac s0 x0"; + fields_border_vel = (char *) "rmass vfrac s0 x0"; + fields_exchange = (char *) "rmass vfrac s0 x0"; + fields_restart = (char *) "rmass vfrac s0 x0"; + fields_create = (char *) "rmass vfrac s0 x0"; + fields_data_atom = (char *) "id type vfrac rmass x"; + fields_data_vel = (char *) "omega"; + + setup_fields(); } /* ---------------------------------------------------------------------- create one atom of itype at coord - set other values to defaults + modify what default AtomVec::create_atom() just created ------------------------------------------------------------------------- */ void AtomVecPeri::create_atom(int itype, double *coord) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::create_atom(itype,coord); + int ilocal = atom->nlocal-1; - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + atom->vfrac[ilocal] = 1.0; + atom->rmass[ilocal] = 1.0; + atom->s0[ilocal] = DBL_MAX; + atom->x0[ilocal][0] = coord[0]; + atom->x0[ilocal][1] = coord[1]; + atom->x0[ilocal][2] = coord[2]; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecPeri::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp); - if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one(FLERR,"Invalid atom type in Atoms section of data file"); + atom->s0[ilocal] = DBL_MAX; + atom->x0[ilocal][0] = coord[0]; + atom->x0[ilocal][1] = coord[1]; + atom->x0[ilocal][2] = coord[2]; - vfrac[nlocal] = utils::numeric(FLERR,values[2],true,lmp); - rmass[nlocal] = utils::numeric(FLERR,values[3],true,lmp); - 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] = utils::numeric(FLERR,values[0],true,lmp); - rmass[nlocal] = utils::numeric(FLERR,values[1],true,lmp); - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(type[i]).d; - 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] = 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 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,TAGINT_FORMAT - " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) 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) 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 AtomVecPeri::write_data_hybrid(FILE *fp, double *buf) -{ - fprintf(fp," %-1.16e %-1.16e",buf[0],buf[1]); - return 2; + if (atom->rmass[ilocal] <= 0.0) + error->one(FLERR,"Invalid mass in Atoms section of data file"); } /* ---------------------------------------------------------------------- @@ -929,12 +132,14 @@ void AtomVecPeri::pack_property_atom(int index, double *buf, int n = 0; if (index == 0) { + double *vfrac = atom->vfrac; for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) buf[n] = vfrac[i]; else buf[n] = 0.0; n += nvalues; } } else if (index == 1) { + double *s0 = atom->s0; for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) buf[n] = s0[i]; else buf[n] = 0.0; @@ -942,27 +147,3 @@ void AtomVecPeri::pack_property_atom(int index, double *buf, } } } - -/* ---------------------------------------------------------------------- - 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/PERI/atom_vec_peri.h b/src/PERI/atom_vec_peri.h index 0fc30d6dc2..12ef650348 100644 --- a/src/PERI/atom_vec_peri.h +++ b/src/PERI/atom_vec_peri.h @@ -27,45 +27,10 @@ namespace LAMMPS_NS { class AtomVecPeri : public AtomVec { public: AtomVecPeri(class LAMMPS *); - void grow(int); - void grow_reset(); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - int pack_comm_hybrid(int, int *, double *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int unpack_comm_hybrid(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); int property_atom(char *); void pack_property_atom(int, double *, int, int); - bigint memory_usage(); - - private: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - double *vfrac,*rmass,*s0,**x0; }; } @@ -75,17 +40,4 @@ class AtomVecPeri : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - -E: Invalid mass value - -Self-explanatory. - */ diff --git a/src/SPIN/atom_vec_spin.cpp b/src/SPIN/atom_vec_spin.cpp index ad1384ffd2..135f8936a1 100644 --- a/src/SPIN/atom_vec_spin.cpp +++ b/src/SPIN/atom_vec_spin.cpp @@ -27,13 +27,6 @@ #include #include #include "atom.h" -#include "comm.h" -#include "domain.h" -#include "error.h" -#include "fix.h" -#include "memory.h" -#include "modify.h" -#include "utils.h" using namespace LAMMPS_NS; @@ -45,908 +38,45 @@ AtomVecSpin::AtomVecSpin(LAMMPS *lmp) : AtomVec(lmp) mass_type = 1; forceclearflag = 1; - comm_x_only = 0; - comm_f_only = 0; - size_forward = 7; - size_reverse = 9; - size_border = 10; - size_velocity = 3; - size_data_atom = 9; - size_data_vel = 4; - xcol_data = 4; - atom->sp_flag = 1; -} -/* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecSpin::grow(int n) -{ - if (n == 0) grow_nmax(); - 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"); - - // allocating mech. quantities - - 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"); - - // allocating mag. quantities - - sp = memory->grow(atom->sp,nmax,4,"atom:sp"); - fm = memory->grow(atom->fm,nmax*comm->nthreads,3,"atom:fm"); - fm_long = memory->grow(atom->fm_long,nmax*comm->nthreads,3,"atom:fm_long"); - - 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 AtomVecSpin::grow_reset() -{ - tag = atom->tag; type = atom->type; - mask = atom->mask; image = atom->image; - x = atom->x; v = atom->v; f = atom->f; - sp = atom->sp; fm = atom->fm; fm_long = atom->fm_long; -} - -/* ---------------------------------------------------------------------- - copy atom I info to atom J -------------------------------------------------------------------------- */ - -void AtomVecSpin::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]; - - sp[j][0] = sp[i][0]; - sp[j][1] = sp[i][1]; - sp[j][2] = sp[i][2]; - sp[j][3] = sp[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 AtomVecSpin::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++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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]*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++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[j][3]; - } - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecSpin::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++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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]*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++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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]; - } - } - } - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecSpin::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++] = sp[j][3]; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecSpin::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++]; - sp[i][0] = buf[m++]; - sp[i][1] = buf[m++]; - sp[i][2] = buf[m++]; - sp[i][3] = buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecSpin::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++]; - sp[i][0] = buf[m++]; - sp[i][1] = buf[m++]; - sp[i][2] = buf[m++]; - sp[i][3] = buf[m++]; - v[i][0] = buf[m++]; - v[i][1] = buf[m++]; - v[i][2] = buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecSpin::unpack_comm_hybrid(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - sp[i][3] = buf[m++]; - sp[i][0] = buf[m++]; - sp[i][1] = buf[m++]; - sp[i][2] = buf[m++]; - } - return m; -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecSpin::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++] = fm[i][0]; - buf[m++] = fm[i][1]; - buf[m++] = fm[i][2]; - buf[m++] = fm_long[i][0]; - buf[m++] = fm_long[i][1]; - buf[m++] = fm_long[i][2]; - } - - return m; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecSpin::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++]; - fm[j][0] += buf[m++]; - fm[j][1] += buf[m++]; - fm[j][2] += buf[m++]; - fm_long[j][0] += buf[m++]; - fm_long[j][1] += buf[m++]; - fm_long[j][2] += buf[m++]; - } -} - -/* ---------------------------------------------------------------------- */ - -int AtomVecSpin::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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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 AtomVecSpin::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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - buf[m++] = sp[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 AtomVecSpin::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++] = sp[j][3]; - buf[m++] = sp[j][0]; - buf[m++] = sp[j][1]; - buf[m++] = sp[j][2]; - } - - return m; -} - -/* ---------------------------------------------------------------------- */ - -void AtomVecSpin::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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - sp[i][0] = buf[m++]; - sp[i][1] = buf[m++]; - sp[i][2] = buf[m++]; - sp[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 AtomVecSpin::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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - sp[i][0] = buf[m++]; - sp[i][1] = buf[m++]; - sp[i][2] = buf[m++]; - sp[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 AtomVecSpin::unpack_border_hybrid(int n, int first, double *buf) -{ - int i,m,last; - - m = 0; - last = first + n; - for (i = first; i < last; i++) { - sp[i][3] = buf[m++]; - sp[i][0] = buf[m++]; - sp[i][1] = buf[m++]; - sp[i][2] = 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 AtomVecSpin::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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - buf[m++] = sp[i][0]; - buf[m++] = sp[i][1]; - buf[m++] = sp[i][2]; - buf[m++] = sp[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 AtomVecSpin::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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - sp[nlocal][0] = buf[m++]; - sp[nlocal][1] = buf[m++]; - sp[nlocal][2] = buf[m++]; - sp[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 AtomVecSpin::size_restart() -{ - int i; - - int nlocal = atom->nlocal; - int n = 15 * 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 AtomVecSpin::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++] = 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++] = sp[i][0]; - buf[m++] = sp[i][1]; - buf[m++] = sp[i][2]; - buf[m++] = sp[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 AtomVecSpin::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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - v[nlocal][0] = buf[m++]; - v[nlocal][1] = buf[m++]; - v[nlocal][2] = buf[m++]; - - sp[nlocal][0] = buf[m++]; - sp[nlocal][1] = buf[m++]; - sp[nlocal][2] = buf[m++]; - sp[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 AtomVecSpin::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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) IMGMAX << IMGBITS) | IMGMAX; - v[nlocal][0] = 0.0; - v[nlocal][1] = 0.0; - v[nlocal][2] = 0.0; - - sp[nlocal][0] = 0.0; - sp[nlocal][1] = 0.0; - sp[nlocal][2] = 0.0; - sp[nlocal][3] = 0.0; - - atom->nlocal++; + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) "sp fm fm_long"; + fields_copy = (char *) "sp"; + fields_comm = (char *) "sp"; + fields_comm_vel = (char *) "sp"; + fields_reverse = (char *) "fm fm_long"; + fields_border = (char *) "sp"; + fields_border_vel = (char *) "sp"; + fields_exchange = (char *) "sp"; + fields_restart = (char *) "sp"; + fields_create = (char *) "sp"; + fields_data_atom = (char *) "id type x sp"; + fields_data_vel = (char *) "omega"; + + setup_fields(); } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecSpin::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp); - 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]; - - sp[nlocal][3] = utils::numeric(FLERR,values[2],true,lmp); - sp[nlocal][0] = utils::numeric(FLERR,values[6],true,lmp); - sp[nlocal][1] = utils::numeric(FLERR,values[7],true,lmp); - sp[nlocal][2] = utils::numeric(FLERR,values[8],true,lmp); - double inorm = 1.0/sqrt(sp[nlocal][0]*sp[nlocal][0] + - sp[nlocal][1]*sp[nlocal][1] + - sp[nlocal][2]*sp[nlocal][2]); - sp[nlocal][0] *= inorm; - sp[nlocal][1] *= inorm; - sp[nlocal][2] *= inorm; - - 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 AtomVecSpin::data_atom_hybrid(int nlocal, char **values) -{ - - sp[nlocal][0] = utils::numeric(FLERR,values[0],true,lmp); - sp[nlocal][1] = utils::numeric(FLERR,values[1],true,lmp); - sp[nlocal][2] = utils::numeric(FLERR,values[2],true,lmp); - double inorm = 1.0/sqrt(sp[nlocal][0]*sp[nlocal][0] + - sp[nlocal][1]*sp[nlocal][1] + - sp[nlocal][2]*sp[nlocal][2]); - sp[nlocal][0] *= inorm; - sp[nlocal][1] *= inorm; - sp[nlocal][2] *= inorm; - sp[nlocal][3] = utils::numeric(FLERR,values[3],true,lmp); - - return 4; -} - -/* ---------------------------------------------------------------------- - pack atom info for data file including 3 image flags -------------------------------------------------------------------------- */ - -void AtomVecSpin::pack_data(double **buf) -{ - int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { - buf[i][0] = ubuf(tag[i]).d; - buf[i][1] = ubuf(type[i]).d; - buf[i][2] = sp[i][3]; - buf[i][3] = x[i][0]; - buf[i][4] = x[i][1]; - buf[i][5] = x[i][2]; - buf[i][6] = sp[i][0]; - buf[i][7] = sp[i][1]; - buf[i][8] = sp[i][2]; - buf[i][9] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][10] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][11] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - pack hybrid atom info for data file -------------------------------------------------------------------------- */ - -int AtomVecSpin::pack_data_hybrid(int i, double *buf) -{ - buf[0] = sp[i][3]; - buf[1] = sp[i][0]; - buf[2] = sp[i][1]; - buf[3] = sp[i][2]; - return 4; -} - -/* ---------------------------------------------------------------------- - write atom info to data file including 3 image flags -------------------------------------------------------------------------- */ - -void AtomVecSpin::write_data(FILE *fp, int n, double **buf) -{ - for (int i = 0; i < n; i++) - fprintf(fp,TAGINT_FORMAT \ - " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e " - "%-1.16e %d %d %d\n", - (tagint) 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],buf[i][7],buf[i][8], - (int) ubuf(buf[i][9]).i,(int) ubuf(buf[i][10]).i, - (int) ubuf(buf[i][11]).i); -} - -/* ---------------------------------------------------------------------- - write hybrid atom info to data file -------------------------------------------------------------------------- */ - -int AtomVecSpin::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 AtomVecSpin::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("sp")) bytes += memory->usage(sp,nmax,4); - if (atom->memcheck("fm")) bytes += memory->usage(fm,nmax*comm->nthreads,3); - if (atom->memcheck("fm_long")) bytes += memory->usage(fm_long,nmax*comm->nthreads,3); - - return bytes; + double *sp = atom->sp[ilocal]; + double inorm = 1.0/sqrt(sp[0]*sp[0] + sp[1]*sp[1] + sp[2]*sp[2]); + sp[0] *= inorm; + sp[1] *= inorm; + sp[2] *= inorm; } /* ---------------------------------------------------------------------- @@ -959,5 +89,3 @@ void AtomVecSpin::force_clear(int /*n*/, size_t nbytes) memset(&atom->fm[0][0],0,3*nbytes); memset(&atom->fm_long[0][0],0,3*nbytes); } - - diff --git a/src/SPIN/atom_vec_spin.h b/src/SPIN/atom_vec_spin.h index 6ce2c9dc7d..ca92cccc2e 100644 --- a/src/SPIN/atom_vec_spin.h +++ b/src/SPIN/atom_vec_spin.h @@ -27,53 +27,8 @@ namespace LAMMPS_NS { class AtomVecSpin : public AtomVec { public: AtomVecSpin(class LAMMPS *); - void grow(int); - void grow_reset(); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - int pack_comm_hybrid(int, int *, double *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int unpack_comm_hybrid(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); - void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - - // clear magnetic and mechanic forces - void force_clear(int, size_t); - - - private: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; // lattice quantities - - // spin quantities - double **sp; // sp[i][0-2] direction of the spin i - // sp[i][3] atomic magnetic moment of the spin i - double **fm; // fm[i][0-2] direction of magnetic precession - double **fm_long; // storage of long-range spin prec. components }; } @@ -83,13 +38,4 @@ class AtomVecSpin : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/atom.cpp b/src/atom.cpp index de5d30930a..7f1a5a6022 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -44,9 +44,11 @@ using namespace LAMMPS_NS; using namespace MathConst; #define DELTA 1 -#define DELTA_MEMSTR 1024 +#define DELTA_PERATOM 64 #define EPSILON 1.0e-6 +enum{DOUBLE,INT,BIGINT}; + /* ---------------------------------------------------------------------- */ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) @@ -66,6 +68,11 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) binhead = NULL; next = permute = NULL; + // data structure with info on per-atom vectors/arrays + + nperatom = maxperatom = 0; + peratom = NULL; + // initialize atom arrays // customize by adding new array @@ -193,6 +200,10 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp) pdscale = 1.0; + // initialize peratom data structure + + peratom_create(); + // ntype-length arrays mass = NULL; @@ -245,6 +256,12 @@ Atom::~Atom() memory->destroy(next); memory->destroy(permute); + // delete peratom data struct + + for (int i = 0; i < nperatom; i++) + delete [] peratom[i].name; + memory->sfree(peratom); + // delete atom arrays // customize by adding new array @@ -403,6 +420,175 @@ void Atom::settings(Atom *old) } } +/* ---------------------------------------------------------------------- + one-time creation of peratom data structure +------------------------------------------------------------------------- */ + +void Atom::peratom_create() +{ + for (int i = 0; i < nperatom; i++) + delete [] peratom[i].name; + memory->sfree(peratom); + + peratom = NULL; + nperatom = maxperatom = 0; + + // customize: add new peratom variables here, order does not matter + // register tagint & imageint variables as INT or BIGINT + + int tagintsize = INT; + if (sizeof(tagint) == 8) tagintsize = BIGINT; + int imageintsize = INT; + if (sizeof(imageint) == 8) imageintsize = BIGINT; + + add_peratom("id",&tag,tagintsize,0); + add_peratom("type",&type,INT,0); + add_peratom("mask",&mask,INT,0); + add_peratom("image",&image,imageintsize,0); + + add_peratom("x",&x,DOUBLE,3); + add_peratom("v",&v,DOUBLE,3); + add_peratom("f",&f,DOUBLE,3,1); // set per-thread flag + + add_peratom("rmass",&rmass,DOUBLE,0); + add_peratom("q",&q,DOUBLE,0); + add_peratom("mu",&mu,DOUBLE,4); + add_peratom("mu3",&mu,DOUBLE,3); // just first 3 values of mu[4] + + // finite size particles + + add_peratom("radius",&radius,DOUBLE,0); + add_peratom("omega",&omega,DOUBLE,3); + add_peratom("amgmom",&angmom,DOUBLE,3); + add_peratom("torque",&torque,DOUBLE,3,1); // set per-thread flag + + add_peratom("ellipsoid",&ellipsoid,INT,0); + add_peratom("line",&line,INT,0); + add_peratom("tri",&tri,INT,0); + add_peratom("body",&body,INT,0); + + // MOLECULE package + + add_peratom("molecule",&molecule,tagintsize,0); + add_peratom("molindex",&molindex,INT,0); + add_peratom("molatom",&molatom,INT,0); + + add_peratom("nspecial",&nspecial,INT,3); + add_peratom_vary("special",&special,tagintsize,&maxspecial,&nspecial,3); + + add_peratom("num_bond",&num_bond,INT,0); + add_peratom_vary("bond_type",&bond_type,INT,&bond_per_atom,&num_bond); + add_peratom_vary("bond_atom",&bond_atom,tagintsize,&bond_per_atom,&num_bond); + + add_peratom("num_angle",&num_angle,INT,0); + add_peratom_vary("angle_type",&angle_type,INT,&angle_per_atom,&num_angle); + add_peratom_vary("angle_atom1",&angle_atom1,tagintsize, + &angle_per_atom,&num_angle); + add_peratom_vary("angle_atom2",&angle_atom2,tagintsize, + &angle_per_atom,&num_angle); + add_peratom_vary("angle_atom3",&angle_atom3,tagintsize, + &angle_per_atom,&num_angle); + + add_peratom("num_dihedral",&num_dihedral,INT,0); + add_peratom_vary("dihedral_type",&dihedral_type,INT, + &dihedral_per_atom,&num_dihedral); + add_peratom_vary("dihedral_atom1",&dihedral_atom1,tagintsize, + &dihedral_per_atom,&num_dihedral); + add_peratom_vary("dihedral_atom2",&dihedral_atom2,tagintsize, + &dihedral_per_atom,&num_dihedral); + add_peratom_vary("dihedral_atom3",&dihedral_atom3,tagintsize, + &dihedral_per_atom,&num_dihedral); + add_peratom_vary("dihedral_atom4",&dihedral_atom4,tagintsize, + &dihedral_per_atom,&num_dihedral); + + add_peratom("num_improper",&num_improper,INT,0); + add_peratom_vary("improper_type",&improper_type,INT, + &improper_per_atom,&num_improper); + add_peratom_vary("improper_atom1",&improper_atom1,tagintsize, + &improper_per_atom,&num_improper); + add_peratom_vary("improper_atom2",&improper_atom2,tagintsize, + &improper_per_atom,&num_improper); + add_peratom_vary("improper_atom3",&improper_atom3,tagintsize, + &improper_per_atom,&num_improper); + add_peratom_vary("improper_atom4",&improper_atom4,tagintsize, + &improper_per_atom,&num_improper); + + // PERI package + + add_peratom("vfrac",&vfrac,DOUBLE,0); + add_peratom("s0",&s0,DOUBLE,0); + add_peratom("x0",&x0,DOUBLE,3); + + // SPIN package + + add_peratom("sp",&sp,DOUBLE,4); + add_peratom("fm",&fm,DOUBLE,3,1); + add_peratom("fm_long",&fm_long,DOUBLE,3,1); +} + +/* ---------------------------------------------------------------------- + add info for a single per-atom vector/array to PerAtom data struct + cols = 0: per-atom vector + cols = N: static per-atom array with N columns + use add_peratom_vary() when column count varies per atom +------------------------------------------------------------------------- */ + +void Atom::add_peratom(const char *name, void *address, + int datatype, int cols, int threadflag) +{ + if (nperatom == maxperatom) { + maxperatom += DELTA_PERATOM; + peratom = (PerAtom *) + memory->srealloc(peratom,maxperatom*sizeof(PerAtom),"atom:peratom"); + } + + int n = strlen(name) + 1; + peratom[nperatom].name = new char[n]; + strcpy(peratom[nperatom].name,name); + peratom[nperatom].address = address; + peratom[nperatom].datatype = datatype; + peratom[nperatom].cols = cols; + peratom[nperatom].threadflag = threadflag; + peratom[nperatom].address_length = NULL; + + nperatom++; +} + +/* ---------------------------------------------------------------------- + add info for a single per-atom array to PerAtom data struct + cols = address of int variable with max columns per atom + for collength = 0: + length = address of peratom vector with column count per atom + e.g. num_bond + for collength = N: + length = address of peratom array with column count per atom + collength = index of column (1 to N) in peratom array with count + e.g. nspecial +------------------------------------------------------------------------- */ + +void Atom::add_peratom_vary(const char *name, void *address, + int datatype, int *cols, void *length, int collength) +{ + if (nperatom == maxperatom) { + maxperatom += DELTA_PERATOM; + peratom = (PerAtom *) + memory->srealloc(peratom,maxperatom*sizeof(PerAtom),"atom:peratom"); + } + + int n = strlen(name) + 1; + peratom[nperatom].name = new char[n]; + strcpy(peratom[nperatom].name,name); + peratom[nperatom].address = address; + peratom[nperatom].datatype = datatype; + peratom[nperatom].cols = -1; + peratom[nperatom].threadflag = 0; + peratom[nperatom].address_maxcols = cols; + peratom[nperatom].address_length = length; + peratom[nperatom].collength = collength; + + nperatom++; +} + /* ---------------------------------------------------------------------- create an AtomVec style called from lammps.cpp, input script, restart file, replicate @@ -2296,11 +2482,7 @@ void *Atom::extract(char *name) bigint Atom::memory_usage() { - memlength = DELTA_MEMSTR; - memory->create(memstr,memlength,"atom:memstr"); - memstr[0] = '\0'; bigint bytes = avec->memory_usage(); - memory->destroy(memstr); bytes += max_same*sizeof(int); if (map_style == 1) @@ -2316,31 +2498,3 @@ bigint Atom::memory_usage() return bytes; } - -/* ---------------------------------------------------------------------- - accumulate per-atom vec names in memstr, padded by spaces - return 1 if padded str is not already in memlist, else 0 -------------------------------------------------------------------------- */ - -int Atom::memcheck(const char *str) -{ - int n = strlen(str) + 3; - char *padded = new char[n]; - strcpy(padded," "); - strcat(padded,str); - strcat(padded," "); - - if (strstr(memstr,padded)) { - delete [] padded; - return 0; - } - - if ((int)strlen(memstr) + n >= memlength) { - memlength += DELTA_MEMSTR; - memory->grow(memstr,memlength,"atom:memstr"); - } - - strcat(memstr,padded); - delete [] padded; - return 1; -} diff --git a/src/atom.h b/src/atom.h index 81f643c007..6cc5dff72a 100644 --- a/src/atom.h +++ b/src/atom.h @@ -38,6 +38,8 @@ class Atom : protected Pointers { bigint nlines; // number of lines bigint ntris; // number of triangles bigint nbodies; // number of bodies + + // system properties bigint nbonds,nangles,ndihedrals,nimpropers; int ntypes,nbondtypes,nangletypes,ndihedraltypes,nimpropertypes; @@ -49,69 +51,28 @@ class Atom : protected Pointers { int nfirst; // # of atoms in first group on this proc char *firstgroupname; // group-ID to store first, NULL if unset - // per-atom arrays - // customize by adding new array + // -------------------------------------------------------------------- + // 1st customization section: customize by adding new per-atom variable + // per-atom vectors and arrays tagint *tag; int *type,*mask; imageint *image; double **x,**v,**f; - tagint *molecule; - int *molindex,*molatom; - + double *rmass; double *q,**mu; + + // finite-size particles + + double *radius; double **omega,**angmom,**torque; - double *radius,*rmass; int *ellipsoid,*line,*tri,*body; - // SPIN package + // MOLECULE package - double **sp; - double **fm; - double **fm_long; - - // PERI package - - double *vfrac,*s0; - double **x0; - - // USER-EFF and USER-AWPMD packages - - int *spin; - double *eradius,*ervel,*erforce,*ervelforce; - double *cs,*csforce,*vforce; - int *etag; - - // USER-SPH package - - double *rho,*drho,*e,*de,*cv; - double **vest; - - // USER-SMD package - - double *contact_radius; - double **smd_data_9; - double **smd_stress; - double *eff_plastic_strain; - double *eff_plastic_strain_rate; - double *damage; - - // USER-DPD package - - double *uCond,*uMech,*uChem,*uCGnew,*uCG; - double *duChem; - double *dpdTheta; - int nspecies_dpd; - - // USER-MESO package - - double **cc, **cc_flux; // cc = chemical concentration - double *edpd_temp,*edpd_flux; // temperature and heat flux - double *edpd_cv; // heat capacity - int cc_species; - - // molecular info + tagint *molecule; + int *molindex,*molatom; int **nspecial; // 0,1,2 = cumulative # of 1-2,1-3,1-4 neighs tagint **special; // IDs of 1-2,1-3,1-4 neighs of each atom @@ -133,15 +94,56 @@ class Atom : protected Pointers { int **improper_type; tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4; - // custom arrays used by fix property/atom + // PERI package - int **ivector; - double **dvector; - char **iname,**dname; - int nivector,ndvector; + double *vfrac,*s0; + double **x0; - // atom style and per-atom array existence flags - // customize by adding new flag + // SPIN package + + double **sp; + double **fm; + double **fm_long; + + // USER-AWPMD and USER_EFF packages + + int *spin; + double *eradius,*ervel,*erforce,*ervelforce; + double *cs,*csforce,*vforce; + int *etag; + + // USER-DPD package + + double *uCond,*uMech,*uChem,*uCGnew,*uCG; + double *duChem; + double *dpdTheta; + int nspecies_dpd; + + // USER-MESO package + + double **cc, **cc_flux; // cc = chemical concentration + double *edpd_temp,*edpd_flux; // temperature and heat flux + double *edpd_cv; // heat capacity + int cc_species; + + // USER-SMD package + + double *contact_radius; + double **smd_data_9; + double **smd_stress; + double *eff_plastic_strain; + double *eff_plastic_strain_rate; + double *damage; + + // USER-SPH package + + double *rho,*drho,*e,*de,*cv; + double **vest; + + // -------------------------------------------------------------------- + // 1st customization section: customize by adding new flag + // existence flags for per-atom vectors and arrays + // 1 if variable is used, 0 if not int sphere_flag,ellipsoid_flag,line_flag,tri_flag,body_flag; int peri_flag,electron_flag; @@ -156,7 +158,7 @@ class Atom : protected Pointers { int rho_flag,e_flag,cv_flag,vest_flag; int dpd_flag,edpd_flag,tdpd_flag; - //USER-SPIN package + // USER-SPIN package int sp_flag; @@ -175,6 +177,32 @@ class Atom : protected Pointers { double pdscale; + // end of 2 customization sections + // -------------------------------------------------------------------- + + // per-atom data struct describing all per-atom vectors/arrays + + struct PerAtom { + char *name; + void *address; + void *address_length; + int *address_maxcols; + int datatype; + int cols; + int collength; + int threadflag; + }; + + PerAtom *peratom; + int nperatom,maxperatom; + + // custom arrays used by fix property/atom + + int **ivector; + double **dvector; + char **iname,**dname; + int nivector,ndvector; + // molecule templates // each template can be a set of consecutive molecules // each with same ID (stored in molecules) @@ -221,12 +249,17 @@ class Atom : protected Pointers { typedef std::map AtomVecCreatorMap; AtomVecCreatorMap *avec_map; + // -------------------------------------------------------------------- // functions Atom(class LAMMPS *); ~Atom(); void settings(class Atom *); + void peratom_create(); + void add_peratom(const char *, void *, int, int, int threadflag=0); + void add_peratom_vary(const char *, void *, int, int *, + void *, int collength=0); void create_avec(const char *, int, char **, int); virtual class AtomVec *new_avec(const char *, int, int &); void init(); @@ -289,8 +322,10 @@ class Atom : protected Pointers { inline int get_map_size() {return map_tag_max+1;}; inline int get_map_maxarray() {return map_maxarray+1;}; + // NOTE: placeholder method until AtomVec is refactored + int memcheck(const char *) {return 1;} + bigint memory_usage(); - int memcheck(const char *); // functions for global to local ID mapping // map lookup function inlined for efficiency @@ -343,9 +378,6 @@ class Atom : protected Pointers { double bininvx,bininvy,bininvz; // inverse actual bin sizes double bboxlo[3],bboxhi[3]; // bounding box of my sub-domain - int memlength; // allocated size of memstr - char *memstr; // string of array names already counted - void setup_sort_bins(); int next_prime(int); diff --git a/src/atom_vec.cpp b/src/atom_vec.cpp index bc94e36e7a..428117f0db 100644 --- a/src/atom_vec.cpp +++ b/src/atom_vec.cpp @@ -12,18 +12,27 @@ ------------------------------------------------------------------------- */ #include "atom_vec.h" +#include #include #include "atom.h" -#include "force.h" +#include "comm.h" #include "domain.h" +#include "force.h" +#include "modify.h" +#include "fix.h" +#include "math_const.h" +#include "memory.h" #include "error.h" #include "utils.h" using namespace LAMMPS_NS; +using namespace MathConst; #define DELTA 16384 #define DELTA_BONUS 8192 +enum{DOUBLE,INT,BIGINT}; + /* ---------------------------------------------------------------------- */ AtomVec::AtomVec(LAMMPS *lmp) : Pointers(lmp) @@ -39,6 +48,40 @@ AtomVec::AtomVec(LAMMPS *lmp) : Pointers(lmp) nargcopy = 0; argcopy = NULL; + + nthreads = comm->nthreads; + + // peratom variables auto-included in corresponding child style fields string + // these fields cannot be specified in the fields string + // leading/trailing whitespace just facilitates matching in process_args() + + default_grow = " id type mask image x v f "; + default_copy = " id type mask image x v "; + default_comm = " x "; + default_comm_vel = " x v "; + default_reverse = " f "; + default_border = " id type mask x "; + default_border_vel = " id type mask x v "; + default_exchange = " id type mask image x v "; + default_restart = " id type mask image x v "; + default_create = " id type mask image x v "; + default_data_atom = ""; + default_data_vel = " v "; + + // initializations + + init_method(&mgrow); + init_method(&mcopy); + init_method(&mcomm); + init_method(&mcomm_vel); + init_method(&mreverse); + init_method(&mborder); + init_method(&mborder_vel); + init_method(&mexchange); + init_method(&mrestart); + init_method(&mcreate); + init_method(&mdata_atom); + init_method(&mdata_vel); } /* ---------------------------------------------------------------------- */ @@ -47,6 +90,21 @@ AtomVec::~AtomVec() { for (int i = 0; i < nargcopy; i++) delete [] argcopy[i]; delete [] argcopy; + + destroy_method(&mgrow); + destroy_method(&mcopy); + destroy_method(&mcomm); + destroy_method(&mcomm_vel); + destroy_method(&mreverse); + destroy_method(&mborder); + destroy_method(&mborder_vel); + destroy_method(&mexchange); + destroy_method(&mrestart); + destroy_method(&mcreate); + destroy_method(&mdata_atom); + destroy_method(&mdata_vel); + + delete [] threads; } /* ---------------------------------------------------------------------- @@ -87,6 +145,223 @@ void AtomVec::init() error->all(FLERR,"KOKKOS package requires a kokkos enabled atom_style"); } +/* ---------------------------------------------------------------------- + process field strings to initialize data structs for all other methods +------------------------------------------------------------------------- */ + +void AtomVec::setup_fields() +{ + int n,cols; + + if (!fields_data_atom) + error->all(FLERR,"Atom style requires fields_data_atom"); + + // process field strings + // return # of fields and matching index into atom->peratom (in Method struct) + + ngrow = process_fields(fields_grow,default_grow,&mgrow); + ncopy = process_fields(fields_copy,default_copy,&mcopy); + ncomm = process_fields(fields_comm,default_comm,&mcomm); + ncomm_vel = process_fields(fields_comm_vel,default_comm_vel,&mcomm_vel); + nreverse = process_fields(fields_reverse,default_reverse,&mreverse); + nborder = process_fields(fields_border,default_border,&mborder); + nborder_vel = process_fields(fields_border_vel,default_border_vel,&mborder_vel); + nexchange = process_fields(fields_exchange,default_exchange,&mexchange); + nrestart = process_fields(fields_restart,default_restart,&mrestart); + ncreate = process_fields(fields_create,default_create,&mcreate); + ndata_atom = process_fields(fields_data_atom,default_data_atom,&mdata_atom); + ndata_vel = process_fields(fields_data_vel,default_data_vel,&mdata_vel); + + // populate field-based data struct for each method to use + + create_method(ngrow,&mgrow); + create_method(ncopy,&mcopy); + create_method(ncomm,&mcomm); + create_method(ncomm_vel,&mcomm_vel); + create_method(nreverse,&mreverse); + create_method(nborder,&mborder); + create_method(nborder_vel,&mborder_vel); + create_method(nexchange,&mexchange); + create_method(nrestart,&mrestart); + create_method(ncreate,&mcreate); + create_method(ndata_atom,&mdata_atom); + create_method(ndata_vel,&mdata_vel); + + // create threads data struct for grow and memory_usage to use + + threads = new int[ngrow]; + for (int i = 0; i < ngrow; i++) { + Atom::PerAtom *field = &atom->peratom[mgrow.index[i]]; + if (field->threadflag) threads[i] = nthreads; + else threads[i] = 1; + } + + // set style-specific variables + // NOTE: check for others vars in atom_vec.cpp/h ?? + + if (ncomm == 0) comm_x_only = 1; + else comm_x_only = 0; + + if (nreverse == 0) comm_f_only = 1; + else comm_f_only = 0; + + size_forward = 3; + for (n = 0; n < ncomm; n++) { + cols = mcomm.cols[n]; + if (cols == 0) size_forward++; + else size_forward += cols; + } + + size_reverse = 3; + for (n = 0; n < nreverse; n++) { + cols = mreverse.cols[n]; + if (cols == 0) size_reverse++; + else size_reverse += cols; + } + + size_border = 6; + for (n = 0; n < nborder; n++) { + cols = mborder.cols[n]; + if (cols == 0) size_border++; + else size_border += cols; + } + + size_velocity = 3; + for (n = 0; n < ncomm_vel; n++) { + cols = mcomm_vel.cols[n]; + if (cols == 0) size_velocity++; + else size_velocity += cols; + } + + size_data_atom = 0; + for (n = 0; n < ndata_atom; n++) { + cols = mdata_atom.cols[n]; + if (strcmp(atom->peratom[mdata_atom.index[n]].name,"x") == 0) + xcol_data = size_data_atom + 1; + if (cols == 0) size_data_atom++; + else size_data_atom += cols; + } + + size_data_vel = 4; + for (n = 0; n < ndata_vel; n++) { + cols = mdata_vel.cols[n]; + if (cols == 0) size_data_vel++; + else size_data_vel += cols; + } +} + +/* ---------------------------------------------------------------------- + process a single field string +------------------------------------------------------------------------- */ + +int AtomVec::process_fields(char *list, const char *default_list, Method *method) +{ + int i,n; + char match[128]; + + if (list == NULL) { + method->index = NULL; + return 0; + } + + // make copy of list of fields so can tokenize it + + n = strlen(list) + 1; + char *copy = new char[n]; + strcpy(copy,list); + + int nfield = atom->count_words(copy); + int *index = new int[nfield]; + + Atom::PerAtom *peratom = atom->peratom; + int nperatom = atom->nperatom; + + nfield = 0; + char *field = strtok(copy," "); + while (field) { + + // find field in master Atom::peratom list + + for (i = 0; i < nperatom; i++) + if (strcmp(field,peratom[i].name) == 0) break; + if (i == nperatom) error->all(FLERR,"Atom_style unrecognized peratom field"); + index[nfield++] = i; + + // error if field is in default list or appears multiple times + + sprintf(match," %s ",field); + if (strstr(default_list,match)) + error->all(FLERR,"Atom_style repeat of default peratom field"); + + for (i = 0; i < nfield-1; i++) + if (index[i] == index[nfield-1]) + error->all(FLERR,"Atom_style duplicated peratom field"); + + field = strtok(NULL," "); + } + + delete [] copy; + + method->index = index; + return nfield; +} + +/* ---------------------------------------------------------------------- + create a method data structs for processing fields +------------------------------------------------------------------------- */ + +void AtomVec::create_method(int nfield, Method *method) +{ + method->pdata = new void*[nfield]; + method->datatype = new int[nfield]; + method->cols = new int[nfield]; + method->maxcols = new int*[nfield]; + method->collength = new int[nfield]; + method->plength = new void*[nfield]; + + for (int i = 0; i < nfield; i++) { + Atom::PerAtom *field = &atom->peratom[method->index[i]]; + method->pdata[i] = (void *) field->address; + method->datatype[i] = field->datatype; + method->cols[i] = field->cols; + if (method->cols[i] < 0) { + method->maxcols[i] = field->address_maxcols; + method->collength[i] = field->collength; + method->plength[i] = field->address_length; + } + } +} + +/* ---------------------------------------------------------------------- + free memory in a method data structs +------------------------------------------------------------------------- */ + +void AtomVec::init_method(Method *method) +{ + method->pdata = NULL; + method->datatype = NULL; + method->cols = NULL; + method->maxcols = NULL; + method->collength = NULL; + method->plength = NULL; + method->index = NULL; +} + +/* ---------------------------------------------------------------------- + free memory in a method data structs +------------------------------------------------------------------------- */ + +void AtomVec::destroy_method(Method *method) +{ + delete [] method->pdata; + delete [] method->datatype; + delete [] method->cols; + delete [] method->maxcols; + delete [] method->collength; + delete [] method->plength; + delete [] method->index; +} + /* ---------------------------------------------------------------------- grow nmax so it is a multiple of DELTA ------------------------------------------------------------------------- */ @@ -108,16 +383,1700 @@ int AtomVec::grow_nmax_bonus(int nmax_bonus) return nmax_bonus; } +/* ---------------------------------------------------------------------- + grow atom arrays + n = 0 grows arrays by a chunk + n > 0 allocates arrays to size n +------------------------------------------------------------------------- */ + +void AtomVec::grow(int n) +{ + int i,datatype,cols,maxcols; + void *pdata,*plength; + + if (n == 0) grow_nmax(); + 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*nthreads,3,"atom:f"); + + for (i = 0; i < ngrow; i++) { + pdata = mgrow.pdata[i]; + datatype = mgrow.datatype[i]; + cols = mgrow.cols[i]; + if (datatype == DOUBLE) { + if (cols == 0) + memory->grow(*((double **) pdata),nmax*threads[i],"atom:dvec"); + else if (cols > 0) + memory->grow(*((double ***) pdata),nmax*threads[i],cols,"atom:darray"); + else { + maxcols = *(mgrow.maxcols[i]); + memory->grow(*((double ***) pdata),nmax*threads[i],maxcols,"atom:darray"); + } + } else if (datatype == INT) { + if (cols == 0) + memory->grow(*((int **) pdata),nmax*threads[i],"atom:ivec"); + else if (cols > 0) + memory->grow(*((int ***) pdata),nmax*threads[i],cols,"atom:iarray"); + else { + maxcols = *(mgrow.maxcols[i]); + memory->grow(*((int ***) pdata),nmax*threads[i],maxcols,"atom:iarray"); + } + } else if (datatype == BIGINT) { + if (cols == 0) + memory->grow(*((bigint **) pdata),nmax*threads[i],"atom:bvec"); + else if (cols > 0) + memory->grow(*((bigint ***) pdata),nmax*threads[i],cols,"atom:barray"); + else { + maxcols = *(mgrow.maxcols[i]); + memory->grow(*((int ***) pdata),nmax*threads[i],maxcols,"atom:barray"); + } + } + } + + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) + modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax); +} + +/* ---------------------------------------------------------------------- + reset local array ptrs +------------------------------------------------------------------------- */ + +void AtomVec::grow_reset() +{ + // NOTE: is this method needed anymore + 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 AtomVec::copy(int i, int j, int delflag) +{ + int m,n,datatype,cols,collength,ncols; + void *pdata,*plength; + + 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 (ncopy) { + for (n = 0; n < ncopy; n++) { + pdata = mcopy.pdata[n]; + datatype = mcopy.datatype[n]; + cols = mcopy.cols[n]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + vec[j] = vec[i]; + } else if (cols > 0) { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + array[j][m] = array[i][m]; + } else { + double **array = *((double ***) pdata); + collength = mcopy.collength[n]; + plength = mcopy.plength[n]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (m = 0; m < ncols; m++) + array[j][m] = array[i][m]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + vec[j] = vec[i]; + } else if (cols > 0) { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + array[j][m] = array[i][m]; + } else { + int **array = *((int ***) pdata); + collength = mcopy.collength[n]; + plength = mcopy.plength[n]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (m = 0; m < ncols; m++) + array[j][m] = array[i][m]; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + vec[j] = vec[i]; + } else if (cols > 0) { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + array[j][m] = array[i][m]; + } else { + bigint **array = *((bigint ***) pdata); + collength = mcopy.collength[n]; + plength = mcopy.plength[n]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (m = 0; m < ncols; m++) + array[j][m] = array[i][m]; + } + } + } + } + + 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 AtomVec::pack_comm(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m,mm,nn,datatype,cols; + double dx,dy,dz; + void *pdata; + + 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; + } + } + + if (comm) { + for (nn = 0; nn < ncomm; nn++) { + pdata = mcomm.pdata[nn]; + datatype = mcomm.datatype[nn]; + cols = mcomm.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = vec[j]; + } + } else { + double **array = *((double ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = array[j][mm]; + } + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + int **array = *((int ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + bigint **array = *((bigint ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +int AtomVec::pack_comm_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m,mm,nn,datatype,cols; + double dx,dy,dz,dvx,dvy,dvz; + void *pdata; + + 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]; + } + } + } + } + + if (ncomm_vel) { + for (nn = 0; nn < ncomm_vel; nn++) { + pdata = mcomm_vel.pdata[nn]; + datatype = mcomm_vel.datatype[nn]; + cols = mcomm_vel.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = vec[j]; + } + } else { + double **array = *((double ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = array[j][mm]; + } + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + int **array = *((int ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + bigint **array = *((bigint ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVec::unpack_comm(int n, int first, double *buf) +{ + int i,m,last,mm,nn,datatype,cols; + void *pdata; + + 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 (ncomm) { + for (nn = 0; nn < ncomm; nn++) { + pdata = mcomm.pdata[nn]; + datatype = mcomm.datatype[nn]; + cols = mcomm.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = first; i < last; i++) + vec[i] = buf[m++]; + } else { + double **array = *((double ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = buf[m++]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = first; i < last; i++) + vec[i] = ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (int) ubuf(buf[m++]).i; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = first; i < last; i++) + vec[i] = (bigint) ubuf(buf[m++]).i; + } else { + bigint **array = *((bigint ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (bigint) ubuf(buf[m++]).i; + } + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +void AtomVec::unpack_comm_vel(int n, int first, double *buf) +{ + int i,m,last,mm,nn,datatype,cols; + void *pdata; + + 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++]; + } + + if (ncomm_vel) { + for (nn = 0; nn < ncomm_vel; nn++) { + pdata = mcomm_vel.pdata[nn]; + datatype = mcomm_vel.datatype[nn]; + cols = mcomm_vel.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = first; i < last; i++) + vec[i] = buf[m++]; + } else { + double **array = *((double ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = buf[m++]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = first; i < last; i++) + vec[i] = ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (int) ubuf(buf[m++]).i; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = first; i < last; i++) + vec[i] = (bigint) ubuf(buf[m++]).i; + } else { + bigint **array = *((bigint ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (bigint) ubuf(buf[m++]).i; + } + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVec::pack_reverse(int n, int first, double *buf) +{ + int i,m,last,mm,nn,datatype,cols; + void *pdata; + + 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]; + } + + if (nreverse) { + for (nn = 0; nn < nreverse; nn++) { + pdata = mreverse.pdata[nn]; + datatype = mreverse.datatype[nn]; + cols = mreverse.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = first; i < last; i++) { + buf[m++] = vec[i]; + } + } else { + double **array = *((double ***) pdata); + for (i = first; i < last; i++) { + for (mm = 0; mm < cols; mm++) + buf[m++] = array[i][mm]; + } + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = first; i < last; i++) { + buf[m++] = ubuf(vec[i]).d; + } + } else { + int **array = *((int ***) pdata); + for (i = first; i < last; i++) { + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = first; i < last; i++) { + buf[m++] = ubuf(vec[i]).d; + } + } else { + bigint **array = *((bigint ***) pdata); + for (i = first; i < last; i++) { + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } + } + } + } + } + + return m; +} + +/* ---------------------------------------------------------------------- */ + +void AtomVec::unpack_reverse(int n, int *list, double *buf) +{ + int i,j,m,mm,nn,datatype,cols; + void *pdata; + + 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++]; + } + + if (nreverse) { + for (nn = 0; nn < nreverse; nn++) { + pdata = mreverse.pdata[nn]; + datatype = mreverse.datatype[nn]; + cols = mreverse.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + vec[j] += buf[m++]; + } + } else { + double **array = *((double ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + array[j][mm] += buf[m++]; + } + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + vec[j] += buf[m++]; + } + } else { + int **array = *((int ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + array[j][mm] += buf[m++]; + } + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + vec[j] += buf[m++]; + } + } else { + bigint **array = *((bigint ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + array[j][mm] += buf[m++]; + } + } + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +int AtomVec::pack_border(int n, int *list, double *buf, int pbc_flag, int *pbc) +{ + int i,j,m,mm,nn,datatype,cols; + double dx,dy,dz; + void *pdata; + + 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++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + } + } 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++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + } + } + + if (nborder) { + for (nn = 0; nn < nborder; nn++) { + pdata = mborder.pdata[nn]; + datatype = mborder.datatype[nn]; + cols = mborder.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = vec[j]; + } + } else { + double **array = *((double ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = array[j][mm]; + } + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + int **array = *((int ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + bigint **array = *((bigint ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } + } + } + + 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 AtomVec::pack_border_vel(int n, int *list, double *buf, + int pbc_flag, int *pbc) +{ + int i,j,m,mm,nn,datatype,cols; + double dx,dy,dz,dvx,dvy,dvz; + void *pdata; + + 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++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + 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++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + 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++] = ubuf(tag[j]).d; + buf[m++] = ubuf(type[j]).d; + buf[m++] = ubuf(mask[j]).d; + 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 (nborder_vel) { + for (nn = 0; nn < nborder_vel; nn++) { + pdata = mborder_vel.pdata[nn]; + datatype = mborder_vel.datatype[nn]; + cols = mborder_vel.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = vec[j]; + } + } else { + double **array = *((double ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = array[j][mm]; + } + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + int **array = *((int ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + buf[m++] = ubuf(vec[j]).d; + } + } else { + bigint **array = *((bigint ***) pdata); + for (i = 0; i < n; i++) { + j = list[i]; + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[j][mm]).d; + } + } + } + } + } + + 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 AtomVec::unpack_border(int n, int first, double *buf) +{ + int i,m,last,mm,nn,datatype,cols; + void *pdata; + + 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] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + } + + if (nborder) { + for (nn = 0; nn < nborder; nn++) { + pdata = mborder.pdata[nn]; + datatype = mborder.datatype[nn]; + cols = mborder.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = first; i < last; i++) + vec[i] = buf[m++]; + } else { + double **array = *((double ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = buf[m++]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = first; i < last; i++) + vec[i] = ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (int) ubuf(buf[m++]).i; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = first; i < last; i++) + vec[i] = (bigint) ubuf(buf[m++]).i; + } else { + bigint **array = *((bigint ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (bigint) ubuf(buf[m++]).i; + } + } + } + } + + 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 AtomVec::unpack_border_vel(int n, int first, double *buf) +{ + int i,m,last,mm,nn,datatype,cols; + void *pdata; + + 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] = (tagint) ubuf(buf[m++]).i; + type[i] = (int) ubuf(buf[m++]).i; + mask[i] = (int) ubuf(buf[m++]).i; + v[i][0] = buf[m++]; + v[i][1] = buf[m++]; + v[i][2] = buf[m++]; + } + + if (nborder_vel) { + for (nn = 0; nn < nborder_vel; nn++) { + pdata = mborder_vel.pdata[nn]; + datatype = mborder_vel.datatype[nn]; + cols = mborder_vel.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + for (i = first; i < last; i++) + vec[i] = buf[m++]; + } else { + double **array = *((double ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = buf[m++]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + for (i = first; i < last; i++) + vec[i] = ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (int) ubuf(buf[m++]).i; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + for (i = first; i < last; i++) + vec[i] = (bigint) ubuf(buf[m++]).i; + } else { + bigint **array = *((bigint ***) pdata); + for (i = first; i < last; i++) + for (mm = 0; mm < cols; mm++) + array[i][mm] = (bigint) ubuf(buf[m++]).i; + } + } + } + } + + 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 AtomVec::pack_exchange(int i, double *buf) +{ + int mm,nn,datatype,cols,collength,ncols; + void *pdata,*plength; + + 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++] = ubuf(tag[i]).d; + buf[m++] = ubuf(type[i]).d; + buf[m++] = ubuf(mask[i]).d; + buf[m++] = ubuf(image[i]).d; + + if (nexchange) { + for (nn = 0; nn < nexchange; nn++) { + pdata = mexchange.pdata[nn]; + datatype = mexchange.datatype[nn]; + cols = mexchange.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + buf[m++] = vec[i]; + } else if (cols > 0) { + double **array = *((double ***) pdata); + for (mm = 0; mm < cols; mm++) + buf[m++] = array[i][mm]; + } else { + double **array = *((double ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (mm = 0; mm < ncols; mm++) + buf[m++] = array[i][mm]; + } + } if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + buf[m++] = ubuf(vec[i]).d; + } else if (cols > 0) { + int **array = *((int ***) pdata); + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } else { + int **array = *((int ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (mm = 0; mm < ncols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } + } if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + buf[m++] = ubuf(vec[i]).d; + } else if (cols > 0) { + bigint **array = *((bigint ***) pdata); + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } else { + bigint **array = *((bigint ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (mm = 0; mm < ncols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } + } + } + } + + 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 AtomVec::unpack_exchange(double *buf) +{ + int mm,nn,datatype,cols,collength,ncols; + void *pdata,*plength; + + 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] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + + if (nexchange) { + for (nn = 0; nn < nexchange; nn++) { + pdata = mexchange.pdata[nn]; + datatype = mexchange.datatype[nn]; + cols = mexchange.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + vec[nlocal] = buf[m++]; + } else if (cols > 0) { + double **array = *((double ***) pdata); + for (mm = 0; mm < cols; mm++) + array[nlocal][mm] = buf[m++]; + } else { + double **array = *((double ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + for (mm = 0; mm < ncols; mm++) + array[nlocal][mm] = buf[m++]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + vec[nlocal] = ubuf(buf[m++]).i; + } else if (cols > 0) { + int **array = *((int ***) pdata); + for (mm = 0; mm < cols; mm++) + array[nlocal][mm] = (int) ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + for (mm = 0; mm < ncols; mm++) + array[nlocal][mm] = (int) ubuf(buf[m++]).i; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + vec[nlocal] = (bigint) ubuf(buf[m++]).i; + } else if (cols > 0) { + bigint **array = *((bigint ***) pdata); + for (mm = 0; mm < cols; mm++) + array[nlocal][mm] = (bigint) ubuf(buf[m++]).i; + } else { + bigint **array = *((bigint ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + for (mm = 0; mm < ncols; mm++) + array[nlocal][mm] = (bigint) ubuf(buf[m++]).i; + } + } + } + } + + 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 AtomVec::size_restart() +{ + int i,nn,cols,collength,ncols; + void *plength; + + // NOTE: need to worry about overflow of returned int ?? + + int nlocal = atom->nlocal; + + // 11 = length storage + id,type,mask,image,x,v + + int n = 11 * nlocal; + + if (nrestart) { + for (nn = 0; nn < nrestart; nn++) { + cols = mrestart.cols[i]; + if (cols == 0) n += nlocal; + else if (cols > 0) n += cols*nlocal; + else { + collength = mrestart.collength[nn]; + plength = mrestart.plength[nn]; + for (i = 0; i < nlocal; i++) { + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + n += ncols; + } + } + } + } + + 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 AtomVec::pack_restart(int i, double *buf) +{ + int mm,nn,datatype,cols,collength,ncols; + void *pdata,*plength; + + int m = 1; + buf[m++] = x[i][0]; + buf[m++] = x[i][1]; + buf[m++] = x[i][2]; + 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]; + + for (nn = 0; nn < nrestart; nn++) { + pdata = mrestart.pdata[nn]; + datatype = mrestart.datatype[nn]; + cols = mrestart.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + buf[m++] = vec[i]; + } else if (ncols > 0) { + double **array = *((double ***) pdata); + for (mm = 0; mm < cols; mm++) + buf[m++] = array[i][mm]; + } else { + double **array = *((double ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (mm = 0; mm < ncols; mm++) + buf[m++] = array[i][mm]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + buf[m++] = ubuf(vec[i]).d; + } else if (cols > 0) { + int **array = *((int ***) pdata); + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } else { + int **array = *((int ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (mm = 0; mm < ncols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + buf[m++] = ubuf(vec[i]).d; + } else if (ncols > 0) { + bigint **array = *((bigint ***) pdata); + for (mm = 0; mm < cols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } else { + bigint **array = *((bigint ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[i][collength-1]; + else ncols = (*((int **) plength))[i]; + for (mm = 0; mm < ncols; mm++) + buf[m++] = ubuf(array[i][mm]).d; + } + } + } + + 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 AtomVec::unpack_restart(double *buf) +{ + int mm,nn,datatype,cols,collength,ncols; + void *pdata,*plength; + + 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] = (tagint) ubuf(buf[m++]).i; + type[nlocal] = (int) ubuf(buf[m++]).i; + mask[nlocal] = (int) ubuf(buf[m++]).i; + image[nlocal] = (imageint) ubuf(buf[m++]).i; + v[nlocal][0] = buf[m++]; + v[nlocal][1] = buf[m++]; + v[nlocal][2] = buf[m++]; + + for (nn = 0; nn < nrestart; nn++) { + pdata = mrestart.pdata[nn]; + datatype = mrestart.datatype[nn]; + cols = mrestart.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + vec[nlocal] = buf[m++]; + } else if (cols > 0) { + double **array = *((double ***) pdata); + for (mm = 0; mm < cols; mm++) + array[nlocal][mm] = buf[m++]; + } else { + double **array = *((double ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + for (mm = 0; mm < ncols; mm++) + array[nlocal][mm] = buf[m++]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + vec[nlocal] = ubuf(buf[m++]).i; + } else if (cols > 0) { + int **array = *((int ***) pdata); + for (mm = 0; mm < cols; mm++) + array[nlocal][mm] = (int) ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + for (mm = 0; mm < ncols; mm++) + array[nlocal][mm] = (int) ubuf(buf[m++]).i; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + vec[nlocal] = (bigint) ubuf(buf[m++]).i; + } else if (cols > 0) { + bigint **array = *((bigint ***) pdata); + for (mm = 0; mm < cols; mm++) + array[nlocal][mm] = (bigint) ubuf(buf[m++]).i; + } else { + int **array = *((int ***) pdata); + collength = mexchange.collength[nn]; + plength = mexchange.plength[nn]; + if (collength) ncols = (*((int ***) plength))[nlocal][collength-1]; + else ncols = (*((int **) plength))[nlocal]; + for (mm = 0; mm < ncols; mm++) + array[nlocal][mm] = (bigint) ubuf(buf[m++]).i; + } + } + } + + 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 AtomVec::create_atom(int itype, double *coord) +{ + int m,n,datatype,cols; + void *pdata; + + 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] = ((imageint) IMGMAX << IMG2BITS) | + ((imageint) IMGMAX << IMGBITS) | IMGMAX; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + // special-case initialization for some fields + + for (n = 0; n < ncreate; n++) { + pdata = mcreate.pdata[n]; + datatype = mcreate.datatype[n]; + cols = mcreate.cols[n]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + vec[nlocal] = 0.0; + } else { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + array[nlocal][m] = 0.0; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + vec[nlocal] = 0; + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + array[nlocal][m] = 0; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + vec[nlocal] = 0; + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + array[nlocal][m] = 0; + } + } + } + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + unpack one line from Atoms section of data file + initialize other atom quantities +------------------------------------------------------------------------- */ + +void AtomVec::data_atom(double *coord, imageint imagetmp, char **values) +{ + int m,n,datatype,cols; + void *pdata; + + int nlocal = atom->nlocal; + if (nlocal == nmax) grow(0); + + x[nlocal][0] = coord[0]; + x[nlocal][1] = coord[1]; + x[nlocal][2] = coord[2]; + mask[nlocal] = 1; + image[nlocal] = imagetmp; + v[nlocal][0] = 0.0; + v[nlocal][1] = 0.0; + v[nlocal][2] = 0.0; + + int ivalue = 0; + for (n = 0; n < ndata_atom; n++) { + pdata = mdata_atom.pdata[n]; + datatype = mdata_atom.datatype[n]; + cols = mdata_atom.cols[n]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + vec[nlocal] = utils::numeric(FLERR,values[ivalue++],true,lmp); + } else { + double **array = *((double ***) pdata); + if (array == atom->x) { // already set by coord arg + ivalue += cols; + continue; + } + for (m = 0; m < cols; m++) + array[nlocal][m] = utils::numeric(FLERR,values[ivalue++],true,lmp); + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + vec[nlocal] = utils::inumeric(FLERR,values[ivalue++],true,lmp); + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + array[nlocal][m] = utils::inumeric(FLERR,values[ivalue++],true,lmp); + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + vec[nlocal] = utils::bnumeric(FLERR,values[ivalue++],true,lmp); + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + array[nlocal][m] = utils::bnumeric(FLERR,values[ivalue++],true,lmp); + } + } + } + + // error checks applicable to all styles + + if (atom->tag[nlocal] <= 0) + error->one(FLERR,"Invalid atom ID in Atoms section of data file"); + if (atom->type[nlocal] <= 0 || atom->type[nlocal] > atom->ntypes) + error->one(FLERR,"Invalid atom type in Atoms section of data file"); + + atom->nlocal++; +} + +/* ---------------------------------------------------------------------- + pack atom info for data file including 3 image flags +------------------------------------------------------------------------- */ + +void AtomVec::pack_data(double **buf) +{ + int i,j,m,n,datatype,cols; + void *pdata; + + int nlocal = atom->nlocal; + for (int i = 0; i < nlocal; i++) { + j = 0; + for (n = 0; n < ndata_atom; n++) { + pdata = mdata_atom.pdata[n]; + datatype = mdata_atom.datatype[n]; + cols = mdata_atom.cols[n]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + buf[i][j++] = vec[i]; + } else { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + buf[i][j++] = array[i][m]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + buf[i][j++] = ubuf(vec[i]).d; + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + buf[i][j++] = ubuf(array[i][m]).d; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + buf[i][j++] = ubuf(vec[i]).d; + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + buf[i][j++] = ubuf(array[i][m]).d; + } + } + } + + buf[i][j++] = ubuf((image[i] & IMGMASK) - IMGMAX).d; + buf[i][j++] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; + buf[i][j++] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; + } +} + +/* ---------------------------------------------------------------------- + write atom info to data file + id is first field, 3 image flags are final fields +------------------------------------------------------------------------- */ + +void AtomVec::write_data(FILE *fp, int n, double **buf) +{ + int i,j,m,nn,datatype,cols; + void *pdata; + + for (i = 0; i < n; i++) { + fprintf(fp,TAGINT_FORMAT,(tagint) ubuf(buf[i][0]).i); + + j = 1; + for (nn = 1; nn < ndata_atom; nn++) { + pdata = mdata_atom.pdata[nn]; + datatype = mdata_atom.datatype[nn]; + cols = mdata_atom.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + fprintf(fp," %-1.16e",buf[i][j++]); + } else { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + fprintf(fp," %-1.16e",buf[i][j++]); + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + fprintf(fp," %d",(int) ubuf(buf[i][j++]).i); + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + fprintf(fp," %d",(int) ubuf(buf[i][j++]).i); + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + fprintf(fp," " BIGINT_FORMAT,(bigint) ubuf(buf[i][j++]).i); + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + fprintf(fp," " BIGINT_FORMAT,(bigint) ubuf(buf[i][j++]).i); + } + } + } + + fprintf(fp," %d %d %d\n", + (int) ubuf(buf[i][j]).i, + (int) ubuf(buf[i][j+1]).i, + (int) ubuf(buf[i][j+2]).i); + } +} + /* ---------------------------------------------------------------------- unpack one line from Velocities section of data file ------------------------------------------------------------------------- */ -void AtomVec::data_vel(int m, char **values) +void AtomVec::data_vel(int ilocal, char **values) { + int m,n,datatype,cols; + void *pdata; + double **v = atom->v; - v[m][0] = utils::numeric(FLERR,values[0],true,lmp); - v[m][1] = utils::numeric(FLERR,values[1],true,lmp); - v[m][2] = utils::numeric(FLERR,values[2],true,lmp); + v[ilocal][0] = utils::numeric(FLERR,values[0],true,lmp); + v[ilocal][1] = utils::numeric(FLERR,values[1],true,lmp); + v[ilocal][2] = utils::numeric(FLERR,values[2],true,lmp); + + int ivalue = 3; + for (n = 0; n < ndata_vel; n++) { + pdata = mdata_vel.pdata[n]; + datatype = mdata_vel.datatype[n]; + cols = mdata_vel.cols[n]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + vec[ilocal] = utils::numeric(FLERR,values[ivalue++],true,lmp); + } else { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + array[ilocal][m] = utils::numeric(FLERR,values[ivalue++],true,lmp); + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + vec[ilocal] = utils::inumeric(FLERR,values[ivalue++],true,lmp); + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + array[ilocal][m] = utils::inumeric(FLERR,values[ivalue++],true,lmp); + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + vec[ilocal] = utils::bnumeric(FLERR,values[ivalue++],true,lmp); + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + array[ilocal][m] = utils::bnumeric(FLERR,values[ivalue++],true,lmp); + } + } + } } /* ---------------------------------------------------------------------- @@ -126,27 +2085,109 @@ void AtomVec::data_vel(int m, char **values) void AtomVec::pack_vel(double **buf) { + int i,j,m,n,datatype,cols; + void *pdata; + double **v = atom->v; tagint *tag = atom->tag; int nlocal = atom->nlocal; - for (int i = 0; i < nlocal; i++) { + for (i = 0; i < nlocal; 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]; + + j = 4; + if (ndata_vel) { + for (n = 0; n < ndata_vel; n++) { + pdata = mdata_vel.pdata[n]; + datatype = mdata_vel.datatype[n]; + cols = mdata_vel.cols[n]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + buf[i][j++] = vec[i]; + } else { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + buf[i][j++] = array[i][m]; + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + buf[i][j++] = ubuf(vec[i]).d; + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + buf[i][j++] = ubuf(array[i][m]).d; + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + buf[i][j++] = ubuf(vec[i]).d; + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + buf[i][j++] = ubuf(array[i][m]).d; + } + } + } + } } } /* ---------------------------------------------------------------------- write velocity info to data file + id and velocity vector are first 4 fields ------------------------------------------------------------------------- */ void AtomVec::write_vel(FILE *fp, int n, double **buf) { - for (int i = 0; i < n; i++) + int i,j,m,nn,datatype,cols; + void *pdata; + + for (i = 0; i < n; i++) { fprintf(fp,TAGINT_FORMAT " %-1.16e %-1.16e %-1.16e\n", (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3]); + + j = 4; + for (nn = 0; nn < ndata_vel; nn++) { + pdata = mdata_vel.pdata[nn]; + datatype = mdata_vel.datatype[nn]; + cols = mdata_vel.cols[nn]; + if (datatype == DOUBLE) { + if (cols == 0) { + double *vec = *((double **) pdata); + fprintf(fp," %-1.16e",buf[i][j++]); + } else { + double **array = *((double ***) pdata); + for (m = 0; m < cols; m++) + fprintf(fp," %-1.16e",buf[i][j++]); + } + } else if (datatype == INT) { + if (cols == 0) { + int *vec = *((int **) pdata); + fprintf(fp," %d",(int) ubuf(buf[i][j++]).i); + } else { + int **array = *((int ***) pdata); + for (m = 0; m < cols; m++) + fprintf(fp," %d",(int) ubuf(buf[i][j++]).i); + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bigint *vec = *((bigint **) pdata); + fprintf(fp," " BIGINT_FORMAT,(bigint) ubuf(buf[i][j++]).i); + } else { + bigint **array = *((bigint ***) pdata); + for (m = 0; m < cols; m++) + fprintf(fp," " BIGINT_FORMAT,(bigint) ubuf(buf[i][j++]).i); + } + } + } + + fprintf(fp,"\n"); + } } /* ---------------------------------------------------------------------- @@ -395,3 +2436,60 @@ void AtomVec::write_improper(FILE *fp, int n, tagint **buf, int index) index++; } } + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint AtomVec::memory_usage() +{ + int datatype,cols,index,maxcols; + void *pdata; + + bigint bytes = 0; + + bytes += memory->usage(tag,nmax); + bytes += memory->usage(type,nmax); + bytes += memory->usage(mask,nmax); + bytes += memory->usage(image,nmax); + bytes += memory->usage(x,nmax,3); + bytes += memory->usage(v,nmax,3); + bytes += memory->usage(f,nmax*nthreads,3); + + for (int i = 0; i < ngrow; i++) { + pdata = mgrow.pdata[i]; + datatype = mgrow.datatype[i]; + cols = mgrow.cols[i]; + index = mgrow.index[i]; + if (datatype == DOUBLE) { + if (cols == 0) { + bytes += memory->usage(*((double **) pdata),nmax*threads[i]); + } else if (cols > 0) { + bytes += memory->usage(*((double ***) pdata),nmax*threads[i],cols); + } else { + maxcols = *(mgrow.maxcols[i]); + bytes += memory->usage(*((double ***) pdata),nmax*threads[i],maxcols); + } + } else if (datatype == INT) { + if (cols == 0) { + bytes += memory->usage(*((int **) pdata),nmax*threads[i]); + } else if (cols > 0) { + bytes += memory->usage(*((int ***) pdata),nmax*threads[i],cols); + } else { + maxcols = *(mgrow.maxcols[i]); + bytes += memory->usage(*((int ***) pdata),nmax*threads[i],maxcols); + } + } else if (datatype == BIGINT) { + if (cols == 0) { + bytes += memory->usage(*((bigint **) pdata),nmax*threads[i]); + } else if (cols > 0) { + bytes += memory->usage(*((bigint ***) pdata),nmax*threads[i],cols); + } else { + maxcols = *(mgrow.maxcols[i]); + bytes += memory->usage(*((bigint ***) pdata),nmax*threads[i],maxcols); + } + } + } + + return bytes; +} diff --git a/src/atom_vec.h b/src/atom_vec.h index 2b57238c3b..c3551b541d 100644 --- a/src/atom_vec.h +++ b/src/atom_vec.h @@ -55,54 +55,54 @@ class AtomVec : protected Pointers { virtual void process_args(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 void force_clear(int, size_t) {} + void grow(int); + void grow_reset(); + void copy(int, int, int); + void clear_bonus() {} + void force_clear(int, size_t) {} - 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;} + int pack_comm(int, int *, double *, int, int *); + int pack_comm_vel(int, int *, double *, int, int *); + int pack_comm_hybrid(int, int *, double *) {return 0;} + void unpack_comm(int, int, double *); + void unpack_comm_vel(int, int, double *); + 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;} + int pack_reverse(int, int, double *); + int pack_reverse_hybrid(int, int, double *) {return 0;} + void unpack_reverse(int, int *, double *); + 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;} + int pack_border(int, int *, double *, int, int *); + int pack_border_vel(int, int *, double *, int, int *); + int pack_border_hybrid(int, int *, double *) {return 0;} + void unpack_border(int, int, double *); + void unpack_border_vel(int, int, double *); + int unpack_border_hybrid(int, int, double *) {return 0;} - virtual int pack_exchange(int, double *) = 0; - virtual int unpack_exchange(double *) = 0; + int pack_exchange(int, double *); + int unpack_exchange(double *); - virtual int size_restart() = 0; - virtual int pack_restart(int, double *) = 0; - virtual int unpack_restart(double *) = 0; + int size_restart(); + virtual int pack_restart(int, double *); + virtual int unpack_restart(double *); - virtual void create_atom(int, double *) = 0; + virtual void create_atom(int, double *); - virtual void data_atom(double *, imageint, 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 data_atom(double *, imageint, char **); + void data_atom_bonus(int, char **) {} + int data_atom_hybrid(int, char **) {return 0;} + void data_vel(int, char **); + 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;} + void pack_data(double **); + int pack_data_hybrid(int, double *) {return 0;} + void write_data(FILE *, int, double **); + int write_data_hybrid(FILE *, double *) {return 0;} + void pack_vel(double **); + int pack_vel_hybrid(int, double *) {return 0;} + void write_vel(FILE *, int, double **); + int write_vel_hybrid(FILE *, double *) {return 0;} int pack_bond(tagint **); void write_bond(FILE *, int, tagint **, int); @@ -113,10 +113,10 @@ class AtomVec : protected Pointers { int pack_improper(tagint **); void write_improper(FILE *, int, tagint **, int); - virtual int property_atom(char *) {return -1;} - virtual void pack_property_atom(int, double *, int, int) {} + int property_atom(char *) {return -1;} + void pack_property_atom(int, double *, int, int) {} - virtual bigint memory_usage() = 0; + bigint memory_usage(); protected: int nmax; // local copy of atom->nmax @@ -124,6 +124,47 @@ class AtomVec : protected Pointers { int deform_groupbit; double *h_rate; + tagint *tag; // peratom fields common to all styles + int *type,*mask; + imageint *image; + double **x,**v,**f; + + const char *default_grow,*default_copy; + const char *default_comm,*default_comm_vel,*default_reverse; + const char *default_border,*default_border_vel; + const char *default_exchange,*default_restart; + const char *default_create,*default_data_atom,*default_data_vel; + + char *fields_grow,*fields_copy; + char *fields_comm,*fields_comm_vel,*fields_reverse; + char *fields_border,*fields_border_vel; + char *fields_exchange,*fields_restart; + char *fields_create,*fields_data_atom,*fields_data_vel; + + struct Method { + void **pdata; + int *datatype; + int *cols; + int **maxcols; + int *collength; + void **plength; + int *index; + }; + + Method mgrow,mcopy; + Method mcomm,mcomm_vel,mreverse,mborder,mborder_vel,mexchange,mrestart; + Method mcreate,mdata_atom,mdata_vel; + + int ngrow,ncopy; + int ncomm,ncomm_vel,nreverse,nborder,nborder_vel,nexchange,nrestart; + int ncreate,ndata_atom,ndata_vel; + + // thread info for fields that are duplicated over threads + // used by fields in grow() and memory_usage() + + int nthreads; + int *threads; + // union data struct for packing 32-bit and 64-bit ints into double bufs // this avoids aliasing issues by having 2 pointers (double,int) // to same buf memory @@ -143,8 +184,15 @@ class AtomVec : protected Pointers { ubuf(int arg) : i(arg) {} }; + // local methods + void grow_nmax(); int grow_nmax_bonus(int); + void setup_fields(); + int process_fields(char *, const char *, Method *); + void create_method(int, Method *); + void init_method(Method *); + void destroy_method(Method *); }; } @@ -161,4 +209,13 @@ E: KOKKOS package requires a kokkos enabled atom_style Self-explanatory. +E: Per-processor system is too big + +The number of owned atoms plus ghost atoms on a single +processor must fit in 32-bit integer. + +E: Invalid atom type in Atoms section of data file + +Atom types must range from 1 to specified # of types. + */ diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp index 25a28f1668..a283e99081 100644 --- a/src/atom_vec_atomic.cpp +++ b/src/atom_vec_atomic.cpp @@ -12,14 +12,6 @@ ------------------------------------------------------------------------- */ #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" -#include "utils.h" using namespace LAMMPS_NS; @@ -30,654 +22,23 @@ 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 a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecAtomic::grow(int n) -{ - if (n == 0) grow_nmax(); - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - } - } 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - } - } - - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - } - - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - 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++] = 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]; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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, imageint imagetmp, char **values) -{ - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); - - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp); - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(type[i]).d; - buf[i][2] = x[i][0]; - buf[i][3] = x[i][1]; - buf[i][4] = x[i][2]; - buf[i][5] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][6] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][7] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - 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,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, - buf[i][2],buf[i][3],buf[i][4], - (int) ubuf(buf[i][5]).i,(int) ubuf(buf[i][6]).i, - (int) ubuf(buf[i][7]).i); -} - -/* ---------------------------------------------------------------------- - 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; + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = NULL; + fields_copy = NULL; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = NULL; + fields_border_vel = NULL; + fields_exchange = NULL; + fields_restart = NULL; + fields_create = NULL; + fields_data_atom = (char *) "id type x"; + fields_data_vel = NULL; + + setup_fields(); } diff --git a/src/atom_vec_atomic.h b/src/atom_vec_atomic.h index afcede89b1..3caf1a5a94 100644 --- a/src/atom_vec_atomic.h +++ b/src/atom_vec_atomic.h @@ -27,36 +27,7 @@ namespace LAMMPS_NS { class AtomVecAtomic : public AtomVec { public: AtomVecAtomic(class LAMMPS *); - virtual ~AtomVecAtomic() {} - void grow(int); - void grow_reset(); - void copy(int, int, int); - virtual int pack_comm(int, int *, double *, int, int *); - virtual int pack_comm_vel(int, int *, double *, int, int *); - virtual void unpack_comm(int, int, double *); - virtual void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - virtual int pack_border(int, int *, double *, int, int *); - virtual int pack_border_vel(int, int *, double *, int, int *); - virtual void unpack_border(int, int, double *); - virtual void unpack_border_vel(int, int, double *); - virtual int pack_exchange(int, double *); - virtual int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); - void create_atom(int, double *); - void data_atom(double *, imageint, char **); - void pack_data(double **); - void write_data(FILE *, int, double **); - bigint memory_usage(); - - protected: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; + ~AtomVecAtomic() {} }; } @@ -66,13 +37,4 @@ class AtomVecAtomic : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp index 9f35d16ff0..9c8f18a846 100644 --- a/src/atom_vec_charge.cpp +++ b/src/atom_vec_charge.cpp @@ -13,13 +13,6 @@ #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" -#include "utils.h" using namespace LAMMPS_NS; @@ -30,742 +23,25 @@ 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 a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecCharge::grow(int n) -{ - if (n == 0) grow_nmax(); - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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++] = ubuf(tag[j]).d; - buf[m++] = ubuf(type[j]).d; - buf[m++] = ubuf(mask[j]).d; - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - 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] = (tagint) ubuf(buf[m++]).i; - type[i] = (int) ubuf(buf[m++]).i; - mask[i] = (int) ubuf(buf[m++]).i; - 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++] = ubuf(tag[i]).d; - buf[m++] = ubuf(type[i]).d; - buf[m++] = ubuf(mask[i]).d; - buf[m++] = ubuf(image[i]).d; - - 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - - 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++] = 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++] = 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) ubuf(buf[m++]).i; - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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, imageint imagetmp, char **values) -{ - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); - - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp); - if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one(FLERR,"Invalid atom type in Atoms section of data file"); - - q[nlocal] = utils::numeric(FLERR,values[2],true,lmp); - - 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] = utils::numeric(FLERR,values[0],true,lmp); - - 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] = ubuf(tag[i]).d; - buf[i][1] = ubuf(type[i]).d; - 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] = ubuf((image[i] & IMGMASK) - IMGMAX).d; - buf[i][7] = ubuf((image[i] >> IMGBITS & IMGMASK) - IMGMAX).d; - buf[i][8] = ubuf((image[i] >> IMG2BITS) - IMGMAX).d; - } -} - -/* ---------------------------------------------------------------------- - 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,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i, - buf[i][2],buf[i][3],buf[i][4],buf[i][5], - (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i, - (int) ubuf(buf[i][8]).i); -} - -/* ---------------------------------------------------------------------- - 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; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) "q"; + fields_copy = (char *) "q"; + fields_comm = NULL; + fields_comm_vel = NULL; + fields_reverse = NULL; + fields_border = (char *) "q"; + fields_border_vel = (char *) "q"; + fields_exchange = (char *) "q"; + fields_restart = (char *) "q"; + fields_create = (char *) "q"; + fields_data_atom = (char *) "id type q x"; + fields_data_vel = NULL; + + setup_fields(); } diff --git a/src/atom_vec_charge.h b/src/atom_vec_charge.h index 10f1d8d141..d52b4a068a 100644 --- a/src/atom_vec_charge.h +++ b/src/atom_vec_charge.h @@ -27,42 +27,6 @@ namespace LAMMPS_NS { class AtomVecCharge : public AtomVec { public: AtomVecCharge(class LAMMPS *); - virtual ~AtomVecCharge() {} - void grow(int); - void grow_reset(); - void copy(int, int, int); - virtual int pack_comm(int, int *, double *, int, int *); - virtual int pack_comm_vel(int, int *, double *, int, int *); - virtual void unpack_comm(int, int, double *); - virtual void unpack_comm_vel(int, int, double *); - int pack_reverse(int, int, double *); - void unpack_reverse(int, int *, double *); - virtual int pack_border(int, int *, double *, int, int *); - virtual int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - virtual void unpack_border(int, int, double *); - virtual void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - virtual int pack_exchange(int, double *); - virtual int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); - void create_atom(int, double *); - void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - bigint memory_usage(); - - protected: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - double *q; }; } @@ -72,13 +36,4 @@ class AtomVecCharge : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - */ diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp index 75136503ea..7a14ea26e6 100644 --- a/src/atom_vec_sphere.cpp +++ b/src/atom_vec_sphere.cpp @@ -5,7 +5,7 @@ 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 + certain rights in this software. This software is distributead under the GNU General Public License. See the README file in the top-level LAMMPS directory. @@ -14,15 +14,11 @@ #include "atom_vec_sphere.h" #include #include "atom.h" -#include "comm.h" -#include "domain.h" #include "modify.h" #include "fix.h" #include "fix_adapt.h" #include "math_const.h" -#include "memory.h" #include "error.h" -#include "utils.h" using namespace LAMMPS_NS; using namespace MathConst; @@ -33,19 +29,29 @@ 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; + + // strings with peratom variables to include in each AtomVec method + // strings cannot contain fields in corresponding AtomVec default strings + // order of fields in the string does not matter + // except fields_data_atom and fields_data_vel which must match data file + + fields_grow = (char *) "radius rmass omega torque"; + fields_copy = (char *) "radius rmass omega"; + fields_comm = NULL; + fields_comm_vel = (char *) "omega"; + fields_reverse = (char *) "torque"; + fields_border = (char *) "radius rmass"; + fields_border_vel = (char *) "radius rmass omega"; + fields_exchange = (char *) "radius rmass omega"; + fields_restart = (char *) "radius rmass omega"; + fields_create = (char *) "radius rmass omega"; + fields_data_atom = (char *) "id type radius rmass x"; + fields_data_vel = (char *) "omega"; + + setup_fields(); } /* ---------------------------------------------------------------------- */ @@ -55,10 +61,11 @@ void AtomVecSphere::init() AtomVec::init(); // set radvary if particle diameters are time-varying due to fix adapt + // NOTE: change this to a atom_style sphere optional arg radvary = 0; - comm_x_only = 1; - size_forward = 3; + //comm_x_only = 1; + //size_forward = 3; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"adapt") == 0) { @@ -69,1118 +76,42 @@ void AtomVecSphere::init() size_forward = 5; } } -} -/* ---------------------------------------------------------------------- - grow atom arrays - n = 0 grows arrays by a chunk - n > 0 allocates arrays to size n -------------------------------------------------------------------------- */ - -void AtomVecSphere::grow(int n) -{ - if (n == 0) grow_nmax(); - 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 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++] = 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++] = 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 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++] = 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++] = 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++] = 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] = (tagint) 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] = (tagint) 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++] = 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) 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++] = 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] = (tagint) ubuf(buf[m++]).i; - type[nlocal] = (int) ubuf(buf[m++]).i; - mask[nlocal] = (int) ubuf(buf[m++]).i; - image[nlocal] = (imageint) 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; + //fields_comm = (char *) "radius rmass"; + //fields_comm_vel = (char *) "radius rmass"; } /* ---------------------------------------------------------------------- create one atom of itype at coord - set other values to defaults + modify what default AtomVec::create_atom() just created ------------------------------------------------------------------------- */ void AtomVecSphere::create_atom(int itype, double *coord) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::create_atom(itype,coord); + int ilocal = atom->nlocal-1; - 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] = ((imageint) IMGMAX << IMG2BITS) | - ((imageint) 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++; + atom->radius[ilocal] = 0.5; + atom->rmass[ilocal] = 4.0*MY_PI/3.0 * 0.5*0.5*0.5; } /* ---------------------------------------------------------------------- unpack one line from Atoms section of data file - initialize other atom quantities + modify what default AtomVec::data_atom() just unpacked + or initialize other atom quantities ------------------------------------------------------------------------- */ void AtomVecSphere::data_atom(double *coord, imageint imagetmp, char **values) { - int nlocal = atom->nlocal; - if (nlocal == nmax) grow(0); + AtomVec::data_atom(coord,imagetmp,values); + int ilocal = atom->nlocal-1; - tag[nlocal] = utils::tnumeric(FLERR,values[0],true,lmp); - type[nlocal] = utils::inumeric(FLERR,values[1],true,lmp); - if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes) - error->one(FLERR,"Invalid atom type in Atoms section of data file"); + double radius = 0.5 * atom->radius[ilocal]; + atom->radius[ilocal] = radius; + if (radius > 0.0) + atom->rmass[ilocal] = + 4.0*MY_PI/3.0 * radius*radius*radius * atom->rmass[ilocal]; - radius[nlocal] = 0.5 * utils::numeric(FLERR,values[2],true,lmp); - if (radius[nlocal] < 0.0) - error->one(FLERR,"Invalid radius in Atoms section of data file"); - - double density = utils::numeric(FLERR,values[3],true,lmp); - 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 * utils::numeric(FLERR,values[0],true,lmp); - if (radius[nlocal] < 0.0) - error->one(FLERR,"Invalid radius in Atoms section of data file"); - - double density = utils::numeric(FLERR,values[1],true,lmp); - 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] = utils::numeric(FLERR,values[0],true,lmp); - v[m][1] = utils::numeric(FLERR,values[1],true,lmp); - v[m][2] = utils::numeric(FLERR,values[2],true,lmp); - omega[m][0] = utils::numeric(FLERR,values[3],true,lmp); - omega[m][1] = utils::numeric(FLERR,values[4],true,lmp); - omega[m][2] = utils::numeric(FLERR,values[5],true,lmp); -} - -/* ---------------------------------------------------------------------- - unpack hybrid quantities from one line in Velocities section of data file -------------------------------------------------------------------------- */ - -int AtomVecSphere::data_vel_hybrid(int m, char **values) -{ - omega[m][0] = utils::numeric(FLERR,values[0],true,lmp); - omega[m][1] = utils::numeric(FLERR,values[1],true,lmp); - omega[m][2] = utils::numeric(FLERR,values[2],true,lmp); - 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] = 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] = 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,TAGINT_FORMAT - " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n", - (tagint) 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) 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] = 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,TAGINT_FORMAT - " %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n", - (tagint) 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; + if (atom->rmass[ilocal] <= 0.0) + error->one(FLERR,"Invalid mass in Atoms section of data file"); } diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h index 28b1198d59..98762dba49 100644 --- a/src/atom_vec_sphere.h +++ b/src/atom_vec_sphere.h @@ -27,54 +27,11 @@ namespace LAMMPS_NS { class AtomVecSphere : public AtomVec { public: AtomVecSphere(class LAMMPS *); - ~AtomVecSphere() {} void init(); - void grow(int); - void grow_reset(); - void copy(int, int, int); - int pack_comm(int, int *, double *, int, int *); - int pack_comm_vel(int, int *, double *, int, int *); - int pack_comm_hybrid(int, int *, double *); - void unpack_comm(int, int, double *); - void unpack_comm_vel(int, int, double *); - int unpack_comm_hybrid(int, int, double *); - int pack_reverse(int, int, double *); - int pack_reverse_hybrid(int, int, double *); - void unpack_reverse(int, int *, double *); - int unpack_reverse_hybrid(int, int *, double *); - int pack_border(int, int *, double *, int, int *); - int pack_border_vel(int, int *, double *, int, int *); - int pack_border_hybrid(int, int *, double *); - void unpack_border(int, int, double *); - void unpack_border_vel(int, int, double *); - int unpack_border_hybrid(int, int, double *); - int pack_exchange(int, double *); - int unpack_exchange(double *); - int size_restart(); - int pack_restart(int, double *); - int unpack_restart(double *); void create_atom(int, double *); void data_atom(double *, imageint, char **); - int data_atom_hybrid(int, char **); - void data_vel(int, char **); - int data_vel_hybrid(int, char **); - void pack_data(double **); - int pack_data_hybrid(int, double *); - void write_data(FILE *, int, double **); - int write_data_hybrid(FILE *, double *); - void pack_vel(double **); - int pack_vel_hybrid(int, double *); - void write_vel(FILE *, int, double **); - int write_vel_hybrid(FILE *, double *); - bigint memory_usage(); private: - tagint *tag; - int *type,*mask; - imageint *image; - double **x,**v,**f; - double *radius,*rmass; - double **omega,**torque; int radvary; }; @@ -85,15 +42,6 @@ class AtomVecSphere : public AtomVec { /* ERROR/WARNING messages: -E: Per-processor system is too big - -The number of owned atoms plus ghost atoms on a single -processor must fit in 32-bit integer. - -E: Invalid atom type in Atoms section of data file - -Atom types must range from 1 to specified # of types. - E: Invalid radius in Atoms section of data file Radius must be >= 0.0.