add mechanism to check for known data file section names
using this mechanism we can reject custom section names that will conflict with existing section names and thus avoid misleading errors. apply this also to fix property atom, where the section name is determined by the fix ID. in addition, allow to specify NULL as section name, which will use the fix ID.
This commit is contained in:
@ -39,6 +39,8 @@
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
@ -49,9 +51,27 @@ static constexpr int DELTA = 4; // must be 2 or larger
|
||||
static constexpr int MAXBODY = 32; // max # of lines in one body
|
||||
|
||||
// customize for new sections
|
||||
// change when add to header::section_keywords
|
||||
static constexpr int NSECTIONS = 25;
|
||||
|
||||
static std::unordered_set<std::string> section_keywords = {
|
||||
"Atoms", "Velocities", "Ellipsoids", "Lines", "Triangles", "Bodies",
|
||||
"Bonds", "Angles", "Dihedrals", "Impropers",
|
||||
"Masses", "Pair Coeffs", "PairIJ Coeffs", "Bond Coeffs", "Angle Coeffs",
|
||||
"Dihedral Coeffs", "Improper Coeffs",
|
||||
"BondBond Coeffs", "BondAngle Coeffs", "MiddleBondTorsion Coeffs",
|
||||
"EndBondTorsion Coeffs", "AngleTorsion Coeffs",
|
||||
"AngleAngleTorsion Coeffs", "BondBond13 Coeffs", "AngleAngle Coeffs"
|
||||
};
|
||||
|
||||
// function to check whether a string is a known data section name
|
||||
// made a static class member, so it can be called from other classes
|
||||
|
||||
bool ReadData::is_data_section(const std::string &keyword)
|
||||
{
|
||||
return section_keywords.count(keyword) > 0;
|
||||
}
|
||||
|
||||
|
||||
// clang-format off
|
||||
enum{NONE,APPEND,VALUE,MERGE};
|
||||
|
||||
// pair style suffixes to ignore
|
||||
@ -266,18 +286,19 @@ void ReadData::command(int narg, char **arg)
|
||||
if (iarg+4 > narg)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
memory->grow(fix_index,nfix+1,"read_data:fix_index");
|
||||
fix_header = (char **)
|
||||
memory->srealloc(fix_header,(nfix+1)*sizeof(char *),
|
||||
"read_data:fix_header");
|
||||
fix_section = (char **)
|
||||
memory->srealloc(fix_section,(nfix+1)*sizeof(char *),
|
||||
"read_data:fix_section");
|
||||
fix_header = (char **) memory->srealloc(fix_header,(nfix+1)*sizeof(char *),
|
||||
"read_data:fix_header");
|
||||
fix_section = (char **) memory->srealloc(fix_section,(nfix+1)*sizeof(char *),
|
||||
"read_data:fix_section");
|
||||
if (is_data_section(arg[iarg+3]))
|
||||
error->all(FLERR,"Custom data section name {} for fix {} collides with existing "
|
||||
"data section",arg[iarg+3],arg[iarg+1]);
|
||||
fix_index[nfix] = modify->find_fix(arg[iarg+1]);
|
||||
if (fix_index[nfix] < 0)
|
||||
error->all(FLERR,"Fix ID for read_data does not exist");
|
||||
if (fix_index[nfix] < 0) error->all(FLERR,"Fix ID for read_data does not exist");
|
||||
if (strcmp(arg[iarg+2],"NULL") == 0) fix_header[nfix] = nullptr;
|
||||
else fix_header[nfix] = utils::strdup(arg[iarg+2]);
|
||||
fix_section[nfix] = utils::strdup(arg[iarg+3]);
|
||||
if (strcmp(arg[iarg+3],"NULL") == 0) fix_section[nfix] = utils::strdup(arg[iarg+1]);
|
||||
else fix_section[nfix] = utils::strdup(arg[iarg+3]);
|
||||
nfix++;
|
||||
iarg += 4;
|
||||
|
||||
@ -521,6 +542,7 @@ void ReadData::command(int narg, char **arg)
|
||||
"from currently defined atom style");
|
||||
atoms();
|
||||
} else skip_lines(natoms);
|
||||
|
||||
} else if (strcmp(keyword,"Velocities") == 0) {
|
||||
if (atomflag == 0)
|
||||
error->all(FLERR,"Must read Atoms before Velocities");
|
||||
@ -529,52 +551,50 @@ void ReadData::command(int narg, char **arg)
|
||||
|
||||
} else if (strcmp(keyword,"Bonds") == 0) {
|
||||
topoflag = bondflag = 1;
|
||||
if (nbonds == 0)
|
||||
error->all(FLERR,"Invalid data file section: Bonds");
|
||||
if (nbonds == 0) error->all(FLERR,"Invalid data file section: Bonds");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds");
|
||||
bonds(firstpass);
|
||||
|
||||
} else if (strcmp(keyword,"Angles") == 0) {
|
||||
topoflag = angleflag = 1;
|
||||
if (nangles == 0)
|
||||
error->all(FLERR,"Invalid data file section: Angles");
|
||||
if (nangles == 0) error->all(FLERR,"Invalid data file section: Angles");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles");
|
||||
angles(firstpass);
|
||||
|
||||
} else if (strcmp(keyword,"Dihedrals") == 0) {
|
||||
topoflag = dihedralflag = 1;
|
||||
if (ndihedrals == 0)
|
||||
error->all(FLERR,"Invalid data file section: Dihedrals");
|
||||
if (ndihedrals == 0) error->all(FLERR,"Invalid data file section: Dihedrals");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals");
|
||||
dihedrals(firstpass);
|
||||
|
||||
} else if (strcmp(keyword,"Impropers") == 0) {
|
||||
topoflag = improperflag = 1;
|
||||
if (nimpropers == 0)
|
||||
error->all(FLERR,"Invalid data file section: Impropers");
|
||||
if (nimpropers == 0) error->all(FLERR,"Invalid data file section: Impropers");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers");
|
||||
impropers(firstpass);
|
||||
|
||||
} else if (strcmp(keyword,"Ellipsoids") == 0) {
|
||||
ellipsoidflag = 1;
|
||||
if (!avec_ellipsoid)
|
||||
error->all(FLERR,"Invalid data file section: Ellipsoids");
|
||||
if (atomflag == 0)
|
||||
error->all(FLERR,"Must read Atoms before Ellipsoids");
|
||||
if (!avec_ellipsoid) error->all(FLERR,"Invalid data file section: Ellipsoids");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids");
|
||||
if (firstpass)
|
||||
bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
|
||||
else skip_lines(nellipsoids);
|
||||
|
||||
} else if (strcmp(keyword,"Lines") == 0) {
|
||||
lineflag = 1;
|
||||
if (!avec_line)
|
||||
error->all(FLERR,"Invalid data file section: Lines");
|
||||
if (!avec_line) error->all(FLERR,"Invalid data file section: Lines");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines");
|
||||
if (firstpass) bonus(nlines,(AtomVec *) avec_line,"lines");
|
||||
else skip_lines(nlines);
|
||||
|
||||
} else if (strcmp(keyword,"Triangles") == 0) {
|
||||
triflag = 1;
|
||||
if (!avec_tri)
|
||||
error->all(FLERR,"Invalid data file section: Triangles");
|
||||
if (!avec_tri) error->all(FLERR,"Invalid data file section: Triangles");
|
||||
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles");
|
||||
if (firstpass) bonus(ntris,(AtomVec *) avec_tri,"triangles");
|
||||
else skip_lines(ntris);
|
||||
|
||||
} else if (strcmp(keyword,"Bodies") == 0) {
|
||||
bodyflag = 1;
|
||||
if (!avec_body)
|
||||
@ -655,6 +675,7 @@ void ReadData::command(int narg, char **arg)
|
||||
error->all(FLERR,"Must define angle_style before BondBond Coeffs");
|
||||
if (firstpass) anglecoeffs(1);
|
||||
else skip_lines(nangletypes);
|
||||
|
||||
} else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
|
||||
if (atom->avec->angles_allow == 0)
|
||||
error->all(FLERR,"Invalid data file section: BondAngle Coeffs");
|
||||
@ -665,46 +686,41 @@ void ReadData::command(int narg, char **arg)
|
||||
|
||||
} else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
|
||||
if (atom->avec->dihedrals_allow == 0)
|
||||
error->all(FLERR,
|
||||
"Invalid data file section: MiddleBondTorsion Coeffs");
|
||||
error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
|
||||
if (force->dihedral == nullptr)
|
||||
error->all(FLERR,
|
||||
"Must define dihedral_style before "
|
||||
"MiddleBondTorsion Coeffs");
|
||||
error->all(FLERR,"Must define dihedral_style before MiddleBondTorsion Coeffs");
|
||||
if (firstpass) dihedralcoeffs(1);
|
||||
else skip_lines(ndihedraltypes);
|
||||
|
||||
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
|
||||
if (atom->avec->dihedrals_allow == 0)
|
||||
error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
|
||||
if (force->dihedral == nullptr)
|
||||
error->all(FLERR,
|
||||
"Must define dihedral_style before EndBondTorsion Coeffs");
|
||||
error->all(FLERR,"Must define dihedral_style before EndBondTorsion Coeffs");
|
||||
if (firstpass) dihedralcoeffs(2);
|
||||
else skip_lines(ndihedraltypes);
|
||||
|
||||
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
|
||||
if (atom->avec->dihedrals_allow == 0)
|
||||
error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
|
||||
if (force->dihedral == nullptr)
|
||||
error->all(FLERR,
|
||||
"Must define dihedral_style before AngleTorsion Coeffs");
|
||||
error->all(FLERR,"Must define dihedral_style before AngleTorsion Coeffs");
|
||||
if (firstpass) dihedralcoeffs(3);
|
||||
else skip_lines(ndihedraltypes);
|
||||
|
||||
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
|
||||
if (atom->avec->dihedrals_allow == 0)
|
||||
error->all(FLERR,
|
||||
"Invalid data file section: AngleAngleTorsion Coeffs");
|
||||
error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
|
||||
if (force->dihedral == nullptr)
|
||||
error->all(FLERR,
|
||||
"Must define dihedral_style before "
|
||||
"AngleAngleTorsion Coeffs");
|
||||
error->all(FLERR,"Must define dihedral_style before AngleAngleTorsion Coeffs");
|
||||
if (firstpass) dihedralcoeffs(4);
|
||||
else skip_lines(ndihedraltypes);
|
||||
|
||||
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
|
||||
if (atom->avec->dihedrals_allow == 0)
|
||||
error->all(FLERR,"Invalid data file section: BondBond13 Coeffs");
|
||||
if (force->dihedral == nullptr)
|
||||
error->all(FLERR,
|
||||
"Must define dihedral_style before BondBond13 Coeffs");
|
||||
error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
|
||||
if (firstpass) dihedralcoeffs(5);
|
||||
else skip_lines(ndihedraltypes);
|
||||
|
||||
@ -712,8 +728,7 @@ void ReadData::command(int narg, char **arg)
|
||||
if (atom->avec->impropers_allow == 0)
|
||||
error->all(FLERR,"Invalid data file section: AngleAngle Coeffs");
|
||||
if (force->improper == nullptr)
|
||||
error->all(FLERR,
|
||||
"Must define improper_style before AngleAngle Coeffs");
|
||||
error->all(FLERR,"Must define improper_style before AngleAngle Coeffs");
|
||||
if (firstpass) impropercoeffs(1);
|
||||
else skip_lines(nimpropertypes);
|
||||
|
||||
@ -724,8 +739,7 @@ void ReadData::command(int narg, char **arg)
|
||||
for (i = 0; i < nfix; i++)
|
||||
if (strcmp(keyword,fix_section[i]) == 0) {
|
||||
if (firstpass) fix(fix_index[i],keyword);
|
||||
else skip_lines(modify->fix[fix_index[i]]->
|
||||
read_data_skip_lines(keyword));
|
||||
else skip_lines(modify->fix[fix_index[i]]->read_data_skip_lines(keyword));
|
||||
parse_keyword(0);
|
||||
break;
|
||||
}
|
||||
@ -882,8 +896,7 @@ void ReadData::command(int narg, char **arg)
|
||||
bigint nblocal = atom->nlocal;
|
||||
MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
|
||||
if (natoms != atom->natoms)
|
||||
error->all(FLERR,
|
||||
"Read_data shrink wrap did not assign all atoms correctly");
|
||||
error->all(FLERR,"Read_data shrink wrap did not assign all atoms correctly");
|
||||
}
|
||||
|
||||
// restore old styles, when reading with nocoeff flag given
|
||||
@ -947,17 +960,6 @@ void ReadData::header(int firstpass)
|
||||
atom->nimpropertypes = extra_improper_types;
|
||||
}
|
||||
|
||||
// customize for new sections
|
||||
|
||||
const char *section_keywords[NSECTIONS] =
|
||||
{"Atoms","Velocities","Ellipsoids","Lines","Triangles","Bodies",
|
||||
"Bonds","Angles","Dihedrals","Impropers",
|
||||
"Masses","Pair Coeffs","PairIJ Coeffs","Bond Coeffs","Angle Coeffs",
|
||||
"Dihedral Coeffs","Improper Coeffs",
|
||||
"BondBond Coeffs","BondAngle Coeffs","MiddleBondTorsion Coeffs",
|
||||
"EndBondTorsion Coeffs","AngleTorsion Coeffs",
|
||||
"AngleAngleTorsion Coeffs","BondBond13 Coeffs","AngleAngle Coeffs"};
|
||||
|
||||
// skip 1st line of file
|
||||
|
||||
if (me == 0) {
|
||||
@ -1186,9 +1188,7 @@ void ReadData::header(int firstpass)
|
||||
// check that exiting string is a valid section keyword
|
||||
|
||||
parse_keyword(1);
|
||||
for (n = 0; n < NSECTIONS; n++)
|
||||
if (strcmp(keyword,section_keywords[n]) == 0) break;
|
||||
if (n == NSECTIONS)
|
||||
if (!is_data_section(keyword))
|
||||
error->all(FLERR,"Unknown identifier in data file: {}",keyword);
|
||||
|
||||
// error checks on header values
|
||||
@ -1730,8 +1730,7 @@ void ReadData::bodies(int firstpass, AtomVec *ptr)
|
||||
error->one(FLERR,"Too many values in body lines in data file");
|
||||
|
||||
if (onebody+1 > MAXBODY)
|
||||
error->one(FLERR,
|
||||
"Too many lines in one body in data file - boost MAXBODY");
|
||||
error->one(FLERR,"Too many lines in one body in data file - boost MAXBODY");
|
||||
|
||||
nchunk++;
|
||||
nline += onebody+1;
|
||||
|
||||
Reference in New Issue
Block a user