preempt some read/write data file bugs

currently, require all type labels (for all interactions) to be defined, if any are, when reading data files
This commit is contained in:
jrgissing
2021-01-31 20:44:19 -05:00
parent 4f219a94aa
commit ffa46ad951
5 changed files with 79 additions and 16 deletions

View File

@ -623,20 +623,23 @@ integers (1, not 1.0).
Type labels can be used to make data files more general, by defining
atom, bond, etc. types in terms of user-provided strings instead of
numbers. If a type label section exists for a given interaction, the
numeric types listed in the *Atoms*, *Bonds*, etc. section are first
converted into their corresponding type label before being read into
LAMMPS; type labels cannot be directly substituted for numeric types
used in data files. Data files can also be used to populate the
default label map; if the type label does not already exist, the type
label is created as a new type and assigned to the default label map.
The corresponding interaction coefficients listed in the data file are
associated to this type. When reading multiple data files, or if the
default label map already exists, there must be enough space in the
per-type data arrays to create new types; see the *extra/atom/types*
keyword for how to reserve extra space for new types. Note that, in
this case, the numeric-to-label mapping within a data file does not
necessary correspond to that of the simulation; the :doc:`write_data <write_data>`
numbers. If a type label section exists for any one interaction
(atom, bond, angle, dihedral or improper), then all types must be
assigned a type label for all interactions. All type label sections
must come before any section that includes types. The numeric types
listed in the *Atoms*, *Bonds*, etc. section are first converted into
their corresponding type label before being read into LAMMPS; type
labels cannot be directly substituted for numeric types used in data
files. Data files assign all types to the default label map; if the
type label does not already exist, the type label is created as a new
type and assigned to the default label map. The corresponding
interaction coefficients listed in the data file are associated to
this type. There must be enough space in the per-type data
arrays to create new types; see the *extra/atom/types* keyword for how
to reserve extra space for new types, e.g., when reading multiple data
files. Note that, in this case, the numeric-to-label mapping within a
data file does not necessary correspond to that of the simulation;
once the default label map is fully defined, the :doc:`write_data <write_data>`
command can be used to print out the default label map at a given
point in a simulation. See the :doc:`labelmap <labelmap>` command for
more discussion on how to use type label maps.

View File

@ -108,7 +108,9 @@ from :doc:`fix property/atom <fix_property_atom>`.
The *nolabelmap* keyword requests that the default label map should
not be written to the data file (see the Type Label sections of
:doc:`read_data <read_data>` command for details).
:doc:`read_data <read_data>` command for details). By default, if the
default label map is fully defined, i.e. every atom, bond, etc. type
has an associated type label, it is written to the data file.
The *pair* keyword lets you specify in what format the pair
coefficient information is written into the data file. If the value

View File

@ -237,12 +237,46 @@ int LabelMap::search(std::string mylabel, std::vector<std::string> labels, int n
return -1;
}
/* ----------------------------------------------------------------------
check if all types have been assigned a type label
------------------------------------------------------------------------- */
int LabelMap::is_complete()
{
for (int i = 0; i < natomtypes; i++)
if (typelabel[i].empty()) return 0;
if (force->bond)
for (int i = 0; i < nbondtypes; i++)
if (btypelabel[i].empty()) return 0;
if (force->angle)
for (int i = 0; i < nangletypes; i++)
if (atypelabel[i].empty()) return 0;
if (force->dihedral)
for (int i = 0; i < ndihedraltypes; i++)
if (dtypelabel[i].empty()) return 0;
if (force->improper)
for (int i = 0; i < nimpropertypes; i++)
if (itypelabel[i].empty()) return 0;
return 1;
}
/* ----------------------------------------------------------------------
proc 0 writes to data file
------------------------------------------------------------------------- */
void LabelMap::write_data(FILE *fp)
{
if (!is_complete()) {
error->warning(FLERR,"Default label map is incomplete. "
"Assign all type labels to write to data file.");
return;
}
fmt::print(fp,"\nAtom Type Labels\n\n");
for (int i = 0; i < natomtypes; i++)
fmt::print(fp,"{} {}\n",i+1,typelabel[i]);

View File

@ -48,6 +48,7 @@ class LabelMap : protected Pointers {
int find_or_create(std::string, std::vector<std::string> &, int); // look up type or create new type
int find(std::string, int); // find numeric type of type label
int search(std::string, std::vector<std::string>, int); // look up type index
int is_complete(); // check if all types are assigned
// input/output for atom class label map

View File

@ -1279,6 +1279,9 @@ void ReadData::atoms()
nchunk = MIN(natoms-nread,CHUNK);
eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
if (eof) error->all(FLERR,"Unexpected end of data file");
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
atom->data_atoms(nchunk,buffer,id_offset,mol_offset,toffset,
shiftflag,shift,labelflag,lmap->lmap2lmap.atom);
nread += nchunk;
@ -1378,6 +1381,9 @@ void ReadData::bonds(int firstpass)
nchunk = MIN(nbonds-nread,CHUNK);
eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
if (eof) error->all(FLERR,"Unexpected end of data file");
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
atom->data_bonds(nchunk,buffer,count,id_offset,boffset,
labelflag,lmap->lmap2lmap.bond);
nread += nchunk;
@ -1453,6 +1459,9 @@ void ReadData::angles(int firstpass)
nchunk = MIN(nangles-nread,CHUNK);
eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
if (eof) error->all(FLERR,"Unexpected end of data file");
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
atom->data_angles(nchunk,buffer,count,id_offset,aoffset,
labelflag,lmap->lmap2lmap.angle);
nread += nchunk;
@ -1528,6 +1537,9 @@ void ReadData::dihedrals(int firstpass)
nchunk = MIN(ndihedrals-nread,CHUNK);
eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
if (eof) error->all(FLERR,"Unexpected end of data file");
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
atom->data_dihedrals(nchunk,buffer,count,id_offset,doffset,
labelflag,lmap->lmap2lmap.dihedral);
nread += nchunk;
@ -1603,6 +1615,9 @@ void ReadData::impropers(int firstpass)
nchunk = MIN(nimpropers-nread,CHUNK);
eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
if (eof) error->all(FLERR,"Unexpected end of data file");
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
atom->data_impropers(nchunk,buffer,count,id_offset,ioffset,
labelflag,lmap->lmap2lmap.improper);
nread += nchunk;
@ -1798,6 +1813,9 @@ void ReadData::mass()
int eof = comm->read_lines_from_file(fp,ntypes,MAXLINE,buf);
if (eof) error->all(FLERR,"Unexpected end of data file");
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
char *original = buf;
for (int i = 0; i < ntypes; i++) {
@ -1983,7 +2001,8 @@ void ReadData::typelabels(std::vector<std::string> &mytypelabel, int myntypes, i
for (int i = 0; i < myntypes; i++) {
next = strchr(buf,'\n');
*next = '\0';
sscanf(buf,"%*d %s",typelabel);
int rv = sscanf(buf,"%*d %s",typelabel);
if (rv != 1) error->all(FLERR,"Invalid data file section: Type Labels");
if (isdigit(typelabel[0])) error->all(FLERR,"Type labels cannot start with a number");
mytypelabel[i] = typelabel;
buf = next + 1;
@ -2164,6 +2183,10 @@ void ReadData::skip_lines(bigint n)
void ReadData::parse_coeffs(char *line, const char *addstr, int dupflag,
int noffset, int offset, int *ilabel)
{
if (labelflag && !lmap->is_complete())
error->all(FLERR,"Label map is incomplete. "
"All types must be assigned a type label.");
settypeflag = 1;
char *ptr;
if ((ptr = strchr(line,'#'))) *ptr = '\0';