diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 16c98794a1..223b0ea6d8 100755 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -623,10 +623,10 @@ 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 any one interaction +numbers. If a type label section exists for a given 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 +assigned a type label for that interaction. Type label sections must +come before any section that utilizes that type. 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 diff --git a/doc/src/write_data.rst b/doc/src/write_data.rst index e6edd1d36a..6a0a532237 100755 --- a/doc/src/write_data.rst +++ b/doc/src/write_data.rst @@ -109,8 +109,10 @@ from :doc:`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 ` 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. +default label map is fully defined for a given interaction, i.e. every +atom, bond, angle, dihedral or improper type has an associated type +label, then a type label section for that interaction 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 diff --git a/src/label_map.cpp b/src/label_map.cpp index b7a8479737..948521dbbb 100755 --- a/src/label_map.cpp +++ b/src/label_map.cpp @@ -241,24 +241,25 @@ int LabelMap::search(std::string mylabel, std::vector labels, int n check if all types have been assigned a type label ------------------------------------------------------------------------- */ -int LabelMap::is_complete() +int LabelMap::is_complete(int mode) { + if (mode == Atom::ATOM) for (int i = 0; i < natomtypes; i++) if (typelabel[i].empty()) return 0; - if (force->bond) + if (force->bond && mode == Atom::BOND) for (int i = 0; i < nbondtypes; i++) if (btypelabel[i].empty()) return 0; - if (force->angle) + if (force->angle && mode == Atom::ANGLE) for (int i = 0; i < nangletypes; i++) if (atypelabel[i].empty()) return 0; - if (force->dihedral) + if (force->dihedral && mode == Atom::DIHEDRAL) for (int i = 0; i < ndihedraltypes; i++) if (dtypelabel[i].empty()) return 0; - if (force->improper) + if (force->improper && mode == Atom::IMPROPER) for (int i = 0; i < nimpropertypes; i++) if (itypelabel[i].empty()) return 0; @@ -271,35 +272,31 @@ int LabelMap::is_complete() 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; + if (is_complete(Atom::ATOM)) { + fmt::print(fp,"\nAtom Type Labels\n\n"); + for (int i = 0; i < natomtypes; i++) + fmt::print(fp,"{} {}\n",i+1,typelabel[i]); } - fmt::print(fp,"\nAtom Type Labels\n\n"); - for (int i = 0; i < natomtypes; i++) - fmt::print(fp,"{} {}\n",i+1,typelabel[i]); - - if (force->bond) { + if (force->bond && is_complete(Atom::BOND)) { fmt::print(fp,"\nBond Type Labels\n\n"); for (int i = 0; i < nbondtypes; i++) fmt::print(fp,"{} {}\n",i+1,btypelabel[i]); } - if (force->angle) { + if (force->angle && is_complete(Atom::ANGLE)) { fmt::print(fp,"\nAngle Type Labels\n\n"); for (int i = 0; i < nangletypes; i++) fmt::print(fp,"{} {}\n",i+1,atypelabel[i]); } - if (force->dihedral) { + if (force->dihedral && is_complete(Atom::DIHEDRAL)) { fmt::print(fp,"\nDihedral Type Labels\n\n"); for (int i = 0; i < ndihedraltypes; i++) fmt::print(fp,"{} {}\n",i+1,dtypelabel[i]); } - if (force->improper) { + if (force->improper && is_complete(Atom::IMPROPER)) { fmt::print(fp,"\nImproper Type Labels\n\n"); for (int i = 0; i < nimpropertypes; i++) fmt::print(fp,"{} {}\n",i+1,itypelabel[i]); diff --git a/src/label_map.h b/src/label_map.h index 5553402e9b..d5a1d44c75 100755 --- a/src/label_map.h +++ b/src/label_map.h @@ -48,7 +48,7 @@ class LabelMap : protected Pointers { int find_or_create(std::string, std::vector &, 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, int); // look up type index - int is_complete(); // check if all types are assigned + int is_complete(int); // check if all types are assigned // input/output for atom class label map diff --git a/src/read_data.cpp b/src/read_data.cpp index f444012403..ac5e97af1a 100755 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -124,7 +124,8 @@ void ReadData::command(int narg, char **arg) addflag = NONE; coeffflag = 1; id_offset = mol_offset = 0; - offsetflag = shiftflag = settypeflag = labelflag = 0; + offsetflag = shiftflag = settypeflag = 0; + tlabelflag = blabelflag = alabelflag = dlabelflag = ilabelflag = 0; toffset = boffset = aoffset = doffset = ioffset = 0; shift[0] = shift[1] = shift[2] = 0.0; extra_atom_types = extra_bond_types = extra_angle_types = @@ -729,6 +730,7 @@ void ReadData::command(int narg, char **arg) if (firstpass) { if (atomflag == 1) error->all(FLERR,"Must read Atom Type Labels before Atoms"); + tlabelflag = 1; typelabels(lmap->typelabel,ntypes,Atom::ATOM); } else skip_lines(ntypes); @@ -737,6 +739,7 @@ void ReadData::command(int narg, char **arg) if (firstpass) { if (bondflag == 1) error->all(FLERR,"Must read Bond Type Labels before Bonds"); + blabelflag = 1; typelabels(lmap->btypelabel,nbondtypes,Atom::BOND); } else skip_lines(nbondtypes); } @@ -746,6 +749,7 @@ void ReadData::command(int narg, char **arg) if (firstpass) { if (angleflag == 1) error->all(FLERR,"Must read Angle Type Labels before Angles"); + alabelflag = 1; typelabels(lmap->atypelabel,nangletypes,Atom::ANGLE); } else skip_lines(nangletypes); } @@ -755,6 +759,7 @@ void ReadData::command(int narg, char **arg) if (firstpass) { if (dihedralflag == 1) error->all(FLERR,"Must read Dihedral Type Labels before Dihedrals"); + dlabelflag = 1; typelabels(lmap->dtypelabel,ndihedraltypes,Atom::DIHEDRAL); } else skip_lines(ndihedraltypes); } @@ -764,6 +769,7 @@ void ReadData::command(int narg, char **arg) if (firstpass) { if (improperflag == 1) error->all(FLERR,"Must read Improper Type Labels before Impropers"); + ilabelflag = 1; typelabels(lmap->itypelabel,nimpropertypes,Atom::IMPROPER); } else skip_lines(nimpropertypes); } @@ -1279,11 +1285,11 @@ 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()) + if (tlabelflag && !lmap->is_complete(Atom::ATOM)) 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); + shiftflag,shift,tlabelflag,lmap->lmap2lmap.atom); nread += nchunk; } @@ -1381,11 +1387,11 @@ 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()) + if (blabelflag && !lmap->is_complete(Atom::BOND)) 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); + blabelflag,lmap->lmap2lmap.bond); nread += nchunk; } @@ -1459,11 +1465,11 @@ 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()) + if (alabelflag && !lmap->is_complete(Atom::ANGLE)) 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); + alabelflag,lmap->lmap2lmap.angle); nread += nchunk; } @@ -1537,11 +1543,11 @@ 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()) + if (dlabelflag && !lmap->is_complete(Atom::DIHEDRAL)) 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); + dlabelflag,lmap->lmap2lmap.dihedral); nread += nchunk; } @@ -1615,11 +1621,11 @@ 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()) + if (ilabelflag && !lmap->is_complete(Atom::IMPROPER)) 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); + ilabelflag,lmap->lmap2lmap.improper); nread += nchunk; } @@ -1813,7 +1819,7 @@ 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()) + if (tlabelflag && !lmap->is_complete(Atom::ATOM)) error->all(FLERR,"Label map is incomplete. " "All types must be assigned a type label."); @@ -1821,7 +1827,7 @@ void ReadData::mass() for (int i = 0; i < ntypes; i++) { next = strchr(buf,'\n'); *next = '\0'; - atom->set_mass(FLERR,buf,toffset,labelflag,lmap->lmap2lmap.atom); + atom->set_mass(FLERR,buf,toffset,tlabelflag,lmap->lmap2lmap.atom); buf = next + 1; } delete [] original; @@ -1837,11 +1843,16 @@ void ReadData::paircoeffs() int eof = comm->read_lines_from_file(fp,ntypes,MAXLINE,buf); if (eof) error->all(FLERR,"Unexpected end of data file"); + if (tlabelflag && !lmap->is_complete(Atom::ATOM)) + 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++) { next = strchr(buf,'\n'); *next = '\0'; - parse_coeffs(buf,nullptr,1,2,toffset,lmap->lmap2lmap.atom); + parse_coeffs(buf,nullptr,1,2,toffset,tlabelflag, + lmap->lmap2lmap.atom); if (narg == 0) error->all(FLERR,"Unexpected empty line in PairCoeffs section"); force->pair->coeff(narg,arg); @@ -1863,12 +1874,17 @@ void ReadData::pairIJcoeffs() int eof = comm->read_lines_from_file(fp,nsq,MAXLINE,buf); if (eof) error->all(FLERR,"Unexpected end of data file"); + if (tlabelflag && !lmap->is_complete(Atom::ATOM)) + error->all(FLERR,"Label map is incomplete. " + "All types must be assigned a type label."); + char *original = buf; for (i = 0; i < ntypes; i++) for (j = i; j < ntypes; j++) { next = strchr(buf,'\n'); *next = '\0'; - parse_coeffs(buf,nullptr,0,2,toffset,lmap->lmap2lmap.atom); + parse_coeffs(buf,nullptr,0,2,toffset,tlabelflag, + lmap->lmap2lmap.atom); if (narg == 0) error->all(FLERR,"Unexpected empty line in PairCoeffs section"); force->pair->coeff(narg,arg); @@ -1889,11 +1905,15 @@ void ReadData::bondcoeffs() int eof = comm->read_lines_from_file(fp,nbondtypes,MAXLINE,buf); if (eof) error->all(FLERR,"Unexpected end of data file"); + if (blabelflag && !lmap->is_complete(Atom::BOND)) + error->all(FLERR,"Label map is incomplete. " + "All types must be assigned a type label."); + char *original = buf; for (int i = 0; i < nbondtypes; i++) { next = strchr(buf,'\n'); *next = '\0'; - parse_coeffs(buf,nullptr,0,1,boffset,lmap->lmap2lmap.bond); + parse_coeffs(buf,nullptr,0,1,boffset,blabelflag,lmap->lmap2lmap.bond); if (narg == 0) error->all(FLERR,"Unexpected empty line in BondCoeffs section"); force->bond->coeff(narg,arg); @@ -1914,13 +1934,20 @@ void ReadData::anglecoeffs(int which) int eof = comm->read_lines_from_file(fp,nangletypes,MAXLINE,buf); if (eof) error->all(FLERR,"Unexpected end of data file"); + if (alabelflag && !lmap->is_complete(Atom::ANGLE)) + error->all(FLERR,"Label map is incomplete. " + "All types must be assigned a type label."); + char *original = buf; for (int i = 0; i < nangletypes; i++) { next = strchr(buf,'\n'); *next = '\0'; - if (which == 0) parse_coeffs(buf,nullptr,0,1,aoffset,lmap->lmap2lmap.angle); - else if (which == 1) parse_coeffs(buf,"bb",0,1,aoffset,lmap->lmap2lmap.angle); - else if (which == 2) parse_coeffs(buf,"ba",0,1,aoffset,lmap->lmap2lmap.angle); + if (which == 0) parse_coeffs(buf,nullptr,0,1,aoffset,alabelflag, + lmap->lmap2lmap.angle); + else if (which == 1) parse_coeffs(buf,"bb",0,1,aoffset,alabelflag, + lmap->lmap2lmap.angle); + else if (which == 2) parse_coeffs(buf,"ba",0,1,aoffset,alabelflag, + lmap->lmap2lmap.angle); if (narg == 0) error->all(FLERR,"Unexpected empty line in AngleCoeffs section"); force->angle->coeff(narg,arg); buf = next + 1; @@ -1940,16 +1967,26 @@ void ReadData::dihedralcoeffs(int which) int eof = comm->read_lines_from_file(fp,ndihedraltypes,MAXLINE,buf); if (eof) error->all(FLERR,"Unexpected end of data file"); + if (dlabelflag && !lmap->is_complete(Atom::DIHEDRAL)) + error->all(FLERR,"Label map is incomplete. " + "All types must be assigned a type label."); + char *original = buf; for (int i = 0; i < ndihedraltypes; i++) { next = strchr(buf,'\n'); *next = '\0'; - if (which == 0) parse_coeffs(buf,nullptr,0,1,doffset,lmap->lmap2lmap.dihedral); - else if (which == 1) parse_coeffs(buf,"mbt",0,1,doffset,lmap->lmap2lmap.dihedral); - else if (which == 2) parse_coeffs(buf,"ebt",0,1,doffset,lmap->lmap2lmap.dihedral); - else if (which == 3) parse_coeffs(buf,"at",0,1,doffset,lmap->lmap2lmap.dihedral); - else if (which == 4) parse_coeffs(buf,"aat",0,1,doffset,lmap->lmap2lmap.dihedral); - else if (which == 5) parse_coeffs(buf,"bb13",0,1,doffset,lmap->lmap2lmap.dihedral); + if (which == 0) parse_coeffs(buf,nullptr,0,1,doffset,dlabelflag, + lmap->lmap2lmap.dihedral); + else if (which == 1) parse_coeffs(buf,"mbt",0,1,doffset,dlabelflag, + lmap->lmap2lmap.dihedral); + else if (which == 2) parse_coeffs(buf,"ebt",0,1,doffset,dlabelflag, + lmap->lmap2lmap.dihedral); + else if (which == 3) parse_coeffs(buf,"at",0,1,doffset,dlabelflag, + lmap->lmap2lmap.dihedral); + else if (which == 4) parse_coeffs(buf,"aat",0,1,doffset,dlabelflag, + lmap->lmap2lmap.dihedral); + else if (which == 5) parse_coeffs(buf,"bb13",0,1,doffset,dlabelflag, + lmap->lmap2lmap.dihedral); if (narg == 0) error->all(FLERR,"Unexpected empty line in DihedralCoeffs section"); force->dihedral->coeff(narg,arg); @@ -1970,12 +2007,18 @@ void ReadData::impropercoeffs(int which) int eof = comm->read_lines_from_file(fp,nimpropertypes,MAXLINE,buf); if (eof) error->all(FLERR,"Unexpected end of data file"); + if (ilabelflag && !lmap->is_complete(Atom::IMPROPER)) + error->all(FLERR,"Label map is incomplete. " + "All types must be assigned a type label."); + char *original = buf; for (int i = 0; i < nimpropertypes; i++) { next = strchr(buf,'\n'); *next = '\0'; - if (which == 0) parse_coeffs(buf,nullptr,0,1,ioffset,lmap->lmap2lmap.improper); - else if (which == 1) parse_coeffs(buf,"aa",0,1,ioffset,lmap->lmap2lmap.improper); + if (which == 0) parse_coeffs(buf,nullptr,0,1,ioffset,ilabelflag, + lmap->lmap2lmap.improper); + else if (which == 1) parse_coeffs(buf,"aa",0,1,ioffset,ilabelflag, + lmap->lmap2lmap.improper); if (narg == 0) error->all(FLERR,"Unexpected empty line in ImproperCoeffs section"); force->improper->coeff(narg,arg); buf = next + 1; @@ -1991,7 +2034,6 @@ void ReadData::typelabels(std::vector &mytypelabel, int myntypes, i char *next; char *buf = new char[myntypes*MAXLINE]; - labelflag = 1; if (!atom->labelmapflag) atom->add_label_map(); int eof = comm->read_lines_from_file(fp,myntypes,MAXLINE,buf); @@ -2181,12 +2223,8 @@ void ReadData::skip_lines(bigint n) ------------------------------------------------------------------------- */ void ReadData::parse_coeffs(char *line, const char *addstr, int dupflag, - int noffset, int offset, int *ilabel) + int noffset, int offset, int labelmode, 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'; @@ -2212,12 +2250,12 @@ void ReadData::parse_coeffs(char *line, const char *addstr, int dupflag, if (noffset) { int value = utils::inumeric(FLERR,arg[0],false,lmp); - if (labelflag) value = ilabel[value-1]; + if (labelmode) value = ilabel[value-1]; sprintf(argoffset1,"%d",value+offset); arg[0] = argoffset1; if (noffset == 2) { value = utils::inumeric(FLERR,arg[1],false,lmp); - if (labelflag) value = ilabel[value-1]; + if (labelmode) value = ilabel[value-1]; sprintf(argoffset2,"%d",value+offset); arg[1] = argoffset2; } diff --git a/src/read_data.h b/src/read_data.h index a2b72d136e..8f761ce88c 100755 --- a/src/read_data.h +++ b/src/read_data.h @@ -67,7 +67,8 @@ class ReadData : protected Pointers { // optional args - int addflag,offsetflag,shiftflag,coeffflag,settypeflag,labelflag; + int addflag,offsetflag,shiftflag,coeffflag,settypeflag; + int tlabelflag,blabelflag,alabelflag,dlabelflag,ilabelflag; tagint addvalue; int toffset,boffset,aoffset,doffset,ioffset; double shift[3]; @@ -88,7 +89,7 @@ class ReadData : protected Pointers { void header(int); void parse_keyword(int); void skip_lines(bigint); - void parse_coeffs(char *, const char *, int, int, int, int *); + void parse_coeffs(char *, const char *, int, int, int, int, int *); int style_match(const char *, const char *); void atoms();