Merge conflicts
This commit is contained in:
153
src/atom.cpp
153
src/atom.cpp
@ -48,9 +48,9 @@
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
|
||||
#define DELTA 1
|
||||
#define EPSILON 1.0e-6
|
||||
#define MAXLINE 256
|
||||
static constexpr int DELTA = 1;
|
||||
static constexpr double EPSILON = 1.0e-6;
|
||||
static constexpr double EPS_ZCOORD = 1.0e-12;
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
one instance per AtomVec style in style_atom.h
|
||||
@ -242,6 +242,7 @@ Atom::Atom(LAMMPS *_lmp) : Pointers(_lmp), atom_style(nullptr), avec(nullptr), a
|
||||
darray = nullptr;
|
||||
icols = dcols = nullptr;
|
||||
ivname = dvname = ianame = daname = nullptr;
|
||||
ivghost = dvghost = iaghost = daghost = nullptr;
|
||||
|
||||
// initialize atom style and array existence flags
|
||||
|
||||
@ -341,6 +342,10 @@ Atom::~Atom()
|
||||
memory->sfree(darray);
|
||||
memory->sfree(icols);
|
||||
memory->sfree(dcols);
|
||||
memory->destroy(ivghost);
|
||||
memory->destroy(dvghost);
|
||||
memory->destroy(iaghost);
|
||||
memory->destroy(daghost);
|
||||
|
||||
// delete user-defined molecules
|
||||
|
||||
@ -633,7 +638,7 @@ void Atom::set_atomflag_defaults()
|
||||
// identical list as 2nd customization in atom.h
|
||||
|
||||
labelmapflag = 0;
|
||||
sphere_flag = ellipsoid_flag = line_flag = tri_flag = body_flag = 0;
|
||||
ellipsoid_flag = line_flag = tri_flag = body_flag = 0;
|
||||
quat_flag = 0;
|
||||
peri_flag = electron_flag = 0;
|
||||
wavepacket_flag = sph_flag = 0;
|
||||
@ -1050,12 +1055,13 @@ void Atom::deallocate_topology()
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
unpack N lines from Atom section of data file
|
||||
call style-specific routine to parse line
|
||||
call atom-style specific method to parse each line
|
||||
triclinic_general = 1 if data file defines a general triclinic box
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
int type_offset, int shiftflag, double *shift,
|
||||
int labelflag, int *ilabel)
|
||||
int labelflag, int *ilabel, int triclinic_general)
|
||||
{
|
||||
int xptr,iptr;
|
||||
imageint imagedata;
|
||||
@ -1066,6 +1072,7 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
auto location = "Atoms section of data file";
|
||||
|
||||
// use the first line to detect and validate the number of words/tokens per line
|
||||
|
||||
next = strchr(buf,'\n');
|
||||
if (!next) error->all(FLERR, "Missing data in {}", location);
|
||||
*next = '\0';
|
||||
@ -1079,13 +1086,16 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
}
|
||||
|
||||
if ((nwords != avec->size_data_atom) && (nwords != avec->size_data_atom + 3))
|
||||
error->all(FLERR,"Incorrect format in {}: {}", location, utils::trim(buf));
|
||||
error->all(FLERR,"Incorrect format in {}: {}{}", location,
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
|
||||
*next = '\n';
|
||||
|
||||
// set bounds for my proc
|
||||
// if periodic and I am lo/hi proc, adjust bounds by EPSILON
|
||||
// ensures all data atoms will be owned even with round-off
|
||||
|
||||
int dimension = domain->dimension;
|
||||
int triclinic = domain->triclinic;
|
||||
|
||||
double epsilon[3];
|
||||
@ -1156,18 +1166,27 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
*next = '\0';
|
||||
auto values = Tokenizer(buf).as_vector();
|
||||
int nvalues = values.size();
|
||||
if ((nvalues == 0) || (utils::strmatch(values[0],"^#.*"))) {
|
||||
// skip over empty or comment lines
|
||||
|
||||
// skip comment lines
|
||||
|
||||
if ((nvalues == 0) || (utils::strmatch(values[0],"^#.*"))) {
|
||||
|
||||
// check that line has correct # of words
|
||||
|
||||
} else if ((nvalues < nwords) ||
|
||||
((nvalues > nwords) && (!utils::strmatch(values[nwords],"^#")))) {
|
||||
error->all(FLERR, "Incorrect format in {}: {}", location, utils::trim(buf));
|
||||
error->all(FLERR, "Incorrect format in {}: {}{}", location,
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
|
||||
// extract the atom coords and image flags (if they exist)
|
||||
|
||||
} else {
|
||||
int imx = 0, imy = 0, imz = 0;
|
||||
if (imageflag) {
|
||||
imx = utils::inumeric(FLERR,values[iptr],false,lmp);
|
||||
imy = utils::inumeric(FLERR,values[iptr+1],false,lmp);
|
||||
imz = utils::inumeric(FLERR,values[iptr+2],false,lmp);
|
||||
if ((domain->dimension == 2) && (imz != 0))
|
||||
if ((dimension == 2) && (imz != 0))
|
||||
error->all(FLERR,"Z-direction image flag must be 0 for 2d-systems");
|
||||
if ((!domain->xperiodic) && (imx != 0)) { reset_image_flag[0] = true; imx = 0; }
|
||||
if ((!domain->yperiodic) && (imy != 0)) { reset_image_flag[1] = true; imy = 0; }
|
||||
@ -1180,13 +1199,35 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
xdata[0] = utils::numeric(FLERR,values[xptr],false,lmp);
|
||||
xdata[1] = utils::numeric(FLERR,values[xptr+1],false,lmp);
|
||||
xdata[2] = utils::numeric(FLERR,values[xptr+2],false,lmp);
|
||||
|
||||
// for 2d simulation:
|
||||
// check if z coord is within EPS_ZCOORD of zero and set to zero
|
||||
|
||||
if (dimension == 2) {
|
||||
if (fabs(xdata[2]) > EPS_ZCOORD)
|
||||
error->all(FLERR,"Read_data atom z coord is non-zero for 2d simulation");
|
||||
xdata[2] = 0.0;
|
||||
}
|
||||
|
||||
// convert atom coords from general to restricted triclinic
|
||||
// so can decide which proc owns the atom
|
||||
|
||||
if (triclinic_general) domain->general_to_restricted_coords(xdata);
|
||||
|
||||
// apply shift if requested by read_data command
|
||||
|
||||
if (shiftflag) {
|
||||
xdata[0] += shift[0];
|
||||
xdata[1] += shift[1];
|
||||
xdata[2] += shift[2];
|
||||
}
|
||||
|
||||
// map atom into simulation box for periodic dimensions
|
||||
|
||||
domain->remap(xdata,imagedata);
|
||||
|
||||
// determine if this proc owns the atom
|
||||
|
||||
if (triclinic) {
|
||||
domain->x2lamda(xdata,lamda);
|
||||
coord = lamda;
|
||||
@ -1195,6 +1236,9 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
|
||||
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
|
||||
coord[2] >= sublo[2] && coord[2] < subhi[2]) {
|
||||
|
||||
// atom-style specific method parses single line
|
||||
|
||||
avec->data_atom(xdata,imagedata,values,typestr);
|
||||
typestr = utils::utf8_subst(typestr);
|
||||
if (id_offset) tag[nlocal-1] += id_offset;
|
||||
@ -1234,8 +1278,8 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
|
||||
/* ----------------------------------------------------------------------
|
||||
unpack N lines from Velocity section of data file
|
||||
check that atom IDs are > 0 and <= map_tag_max
|
||||
call style-specific routine to parse line
|
||||
------------------------------------------------------------------------- */
|
||||
call style-specific routine to parse line-
|
||||
------------------------------------------------------------------------ */
|
||||
|
||||
void Atom::data_vels(int n, char *buf, tagint id_offset)
|
||||
{
|
||||
@ -1254,7 +1298,8 @@ void Atom::data_vels(int n, char *buf, tagint id_offset)
|
||||
if (values.size() == 0) {
|
||||
// skip over empty or comment lines
|
||||
} else if ((int)values.size() != avec->size_data_vel) {
|
||||
error->all(FLERR, "Incorrect velocity format in data file: {}", utils::trim(buf));
|
||||
error->all(FLERR, "Incorrect format in Velocities section of data file: {}{}",
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
} else {
|
||||
tagint tagdata = utils::tnumeric(FLERR,values[0],false,lmp) + id_offset;
|
||||
if (tagdata <= 0 || tagdata > map_tag_max)
|
||||
@ -1298,7 +1343,9 @@ void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset,
|
||||
// skip over empty or comment lines
|
||||
// Bonds line is: number(ignored), bond type, atomID 1, atomID 2
|
||||
if (nwords > 0) {
|
||||
if (nwords != 4) error->all(FLERR, "Incorrect format in {}: {}", location, utils::trim(buf));
|
||||
if (nwords != 4)
|
||||
error->all(FLERR, "Incorrect format in {}: {}{}", location,
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
typestr = utils::utf8_subst(values[1]);
|
||||
atom1 = utils::tnumeric(FLERR, values[2], false, lmp);
|
||||
atom2 = utils::tnumeric(FLERR, values[3], false, lmp);
|
||||
@ -1389,7 +1436,9 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset,
|
||||
// skip over empty or comment lines
|
||||
// Angles line is: number(ignored), angle type, atomID 1, atomID 2, atomID 3
|
||||
if (nwords > 0) {
|
||||
if (nwords != 5) error->all(FLERR, "Incorrect format in {}: {}", location, utils::trim(buf));
|
||||
if (nwords != 5)
|
||||
error->all(FLERR, "Incorrect format in {}: {}{}", location,
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
typestr = utils::utf8_subst(values[1]);
|
||||
atom1 = utils::tnumeric(FLERR, values[2], false, lmp);
|
||||
atom2 = utils::tnumeric(FLERR, values[3], false, lmp);
|
||||
@ -1496,7 +1545,9 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset,
|
||||
// skip over empty or comment lines
|
||||
// Dihedrals line is: number(ignored), bond type, atomID 1, atomID 2, atomID 3, atomID 4
|
||||
if (nwords > 0) {
|
||||
if (nwords != 6) error->all(FLERR, "Incorrect format in {}: {}", location, utils::trim(buf));
|
||||
if (nwords != 6)
|
||||
error->all(FLERR, "Incorrect format in {}: {}{}", location,
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
typestr = utils::utf8_subst(values[1]);
|
||||
atom1 = utils::tnumeric(FLERR, values[2], false, lmp);
|
||||
atom2 = utils::tnumeric(FLERR, values[3], false, lmp);
|
||||
@ -1622,7 +1673,9 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset,
|
||||
// skip over empty or comment lines
|
||||
// Impropers line is: number(ignored), bond type, atomID 1, atomID 2, atomID 3, atomID 4
|
||||
if (nwords > 0) {
|
||||
if (nwords != 6) error->all(FLERR, "Incorrect format in {}: {}", location, utils::trim(buf));
|
||||
if (nwords != 6)
|
||||
error->all(FLERR, "Incorrect format in {}: {}{}", location,
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
typestr = utils::utf8_subst(values[1]);
|
||||
atom1 = utils::tnumeric(FLERR, values[2], false, lmp);
|
||||
atom2 = utils::tnumeric(FLERR, values[3], false, lmp);
|
||||
@ -1738,7 +1791,8 @@ void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus, tagint id_offset)
|
||||
if (values.size() == 0) {
|
||||
// skip over empty or comment lines
|
||||
} else if ((int)values.size() != avec_bonus->size_data_bonus) {
|
||||
error->all(FLERR, "Incorrect bonus data format in data file: {}", utils::trim(buf));
|
||||
error->all(FLERR, "Incorrect format in Bonus section of data file: {}{}",
|
||||
utils::trim(buf), utils::errorurl(2));
|
||||
} else {
|
||||
tagint tagdata = utils::tnumeric(FLERR,values[0],false,lmp) + id_offset;
|
||||
if (tagdata <= 0 || tagdata > map_tag_max)
|
||||
@ -1955,18 +2009,14 @@ void Atom::set_mass(const char *file, int line, int /*narg*/, char **arg)
|
||||
if (mass == nullptr)
|
||||
error->all(file,line, "Cannot set per-type atom mass for atom style {}", atom_style);
|
||||
|
||||
char *typestr = utils::expand_type(file, line, arg[0], Atom::ATOM, lmp);
|
||||
const std::string str = typestr ? typestr : arg[0];
|
||||
delete[] typestr;
|
||||
|
||||
int lo, hi;
|
||||
utils::bounds(file, line, str, 1, ntypes, lo, hi, error);
|
||||
utils::bounds_typelabel(file, line, arg[0], 1, ntypes, lo, hi, error, lmp, Atom::ATOM);
|
||||
if ((lo < 1) || (hi > ntypes))
|
||||
error->all(file, line, "Invalid atom type {} for atom mass", str);
|
||||
error->all(file, line, "Invalid atom type {} for atom mass", arg[0]);
|
||||
|
||||
const double value = utils::numeric(FLERR, arg[1], false, lmp);
|
||||
if (value <= 0.0)
|
||||
error->all(file, line, "Invalid atom mass value {} for type {}", value, str);
|
||||
error->all(file, line, "Invalid atom mass value {} for type {}", value, arg[0]);
|
||||
|
||||
for (int itype = lo; itype <= hi; itype++) {
|
||||
mass[itype] = value;
|
||||
@ -2624,6 +2674,18 @@ void Atom::update_callback(int ifix)
|
||||
if (extra_border[i] > ifix) extra_border[i]--;
|
||||
}
|
||||
|
||||
/** \brief Find a custom per-atom property with given name
|
||||
\verbatim embed:rst
|
||||
|
||||
This function returns the list index of a custom per-atom property
|
||||
with the name "name", also returning by reference its data type and
|
||||
number of values per atom.
|
||||
\endverbatim
|
||||
* \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix)
|
||||
* \param &flag Returns data type of property: 0 for int, 1 for double
|
||||
* \param &cols Returns number of values: 0 for a single value, 1 or more for a vector of values
|
||||
* \return index of property in the respective list of properties
|
||||
*/
|
||||
/* ----------------------------------------------------------------------
|
||||
find custom per-atom vector with name
|
||||
return index if found, -1 if not found
|
||||
@ -2667,6 +2729,33 @@ int Atom::find_custom(const char *name, int &flag, int &cols)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** \brief Find a custom per-atom property with given name and retrieve ghost property
|
||||
\verbatim embed:rst
|
||||
|
||||
This function returns the list index of a custom per-atom property
|
||||
with the name "name", also returning by reference its data type,
|
||||
number of values per atom, and if it is communicated to ghost particles.
|
||||
Classes rarely need to check on ghost communication and so `find_custom`
|
||||
is typically preferred to this function. See :doc:`pair amoeba <pair_amoeba>`
|
||||
for an example where checking ghost communication is necessary.
|
||||
\endverbatim
|
||||
* \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix)
|
||||
* \param &flag Returns data type of property: 0 for int, 1 for double
|
||||
* \param &cols Returns number of values: 0 for a single value, 1 or more for a vector of values
|
||||
* \param &ghost Returns whether property is communicated to ghost atoms: 0 for no, 1 for yes
|
||||
* \return index of property in the respective list of properties
|
||||
*/
|
||||
int Atom::find_custom_ghost(const char *name, int &flag, int &cols, int &ghost)
|
||||
{
|
||||
int i = find_custom(name, flag, cols);
|
||||
if (i == -1) return i;
|
||||
if ((flag == 0) && (cols == 0)) ghost = ivghost[i];
|
||||
else if ((flag == 1) && (cols == 0)) ghost = dvghost[i];
|
||||
else if ((flag == 0) && (cols == 1)) ghost = iaghost[i];
|
||||
else if ((flag == 1) && (cols == 1)) ghost = daghost[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
/** \brief Add a custom per-atom property with the given name and type and size
|
||||
\verbatim embed:rst
|
||||
|
||||
@ -2677,9 +2766,10 @@ This function is called, e.g. from :doc:`fix property/atom <fix_property_atom>`.
|
||||
* \param name Name of the property (w/o a "i_" or "d_" or "i2_" or "d2_" prefix)
|
||||
* \param flag Data type of property: 0 for int, 1 for double
|
||||
* \param cols Number of values: 0 for a single value, 1 or more for a vector of values
|
||||
* \param ghost Whether property is communicated to ghost atoms: 0 for no, 1 for yes
|
||||
* \return index of property in the respective list of properties
|
||||
*/
|
||||
int Atom::add_custom(const char *name, int flag, int cols)
|
||||
int Atom::add_custom(const char *name, int flag, int cols, int ghost)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
@ -2688,6 +2778,8 @@ int Atom::add_custom(const char *name, int flag, int cols)
|
||||
nivector++;
|
||||
ivname = (char **) memory->srealloc(ivname,nivector*sizeof(char *),"atom:ivname");
|
||||
ivname[index] = utils::strdup(name);
|
||||
ivghost = (int *) memory->srealloc(ivghost,nivector*sizeof(int),"atom:ivghost");
|
||||
ivghost[index] = ghost;
|
||||
ivector = (int **) memory->srealloc(ivector,nivector*sizeof(int *),"atom:ivector");
|
||||
memory->create(ivector[index],nmax,"atom:ivector");
|
||||
|
||||
@ -2696,6 +2788,8 @@ int Atom::add_custom(const char *name, int flag, int cols)
|
||||
ndvector++;
|
||||
dvname = (char **) memory->srealloc(dvname,ndvector*sizeof(char *),"atom:dvname");
|
||||
dvname[index] = utils::strdup(name);
|
||||
dvghost = (int *) memory->srealloc(dvghost,ndvector*sizeof(int),"atom:dvghost");
|
||||
dvghost[index] = ghost;
|
||||
dvector = (double **) memory->srealloc(dvector,ndvector*sizeof(double *),"atom:dvector");
|
||||
memory->create(dvector[index],nmax,"atom:dvector");
|
||||
|
||||
@ -2704,6 +2798,8 @@ int Atom::add_custom(const char *name, int flag, int cols)
|
||||
niarray++;
|
||||
ianame = (char **) memory->srealloc(ianame,niarray*sizeof(char *),"atom:ianame");
|
||||
ianame[index] = utils::strdup(name);
|
||||
iaghost = (int *) memory->srealloc(iaghost,niarray*sizeof(int),"atom:iaghost");
|
||||
iaghost[index] = ghost;
|
||||
iarray = (int ***) memory->srealloc(iarray,niarray*sizeof(int **),"atom:iarray");
|
||||
memory->create(iarray[index],nmax,cols,"atom:iarray");
|
||||
icols = (int *) memory->srealloc(icols,niarray*sizeof(int),"atom:icols");
|
||||
@ -2714,6 +2810,8 @@ int Atom::add_custom(const char *name, int flag, int cols)
|
||||
ndarray++;
|
||||
daname = (char **) memory->srealloc(daname,ndarray*sizeof(char *),"atom:daname");
|
||||
daname[index] = utils::strdup(name);
|
||||
daghost = (int *) memory->srealloc(daghost,ndarray*sizeof(int),"atom:daghost");
|
||||
daghost[index] = ghost;
|
||||
darray = (double ***) memory->srealloc(darray,ndarray*sizeof(double **),"atom:darray");
|
||||
memory->create(darray[index],nmax,cols,"atom:darray");
|
||||
dcols = (int *) memory->srealloc(dcols,ndarray*sizeof(int),"atom:dcols");
|
||||
@ -2722,6 +2820,7 @@ int Atom::add_custom(const char *name, int flag, int cols)
|
||||
|
||||
if (index < 0)
|
||||
error->all(FLERR,"Invalid call to Atom::add_custom()");
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user