From 3fc47a9366c7ad4b53b1b10eeca3a1770efabbdc Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Sun, 7 Nov 2021 00:51:55 -0400 Subject: [PATCH] read_data: bond, etc. direct label support --- doc/src/Errors_messages.rst | 0 doc/src/read_data.rst | 45 ++++++++++++------------ doc/src/write_data.rst | 3 +- src/atom.cpp | 69 +++++++++++++++++++++++++++++-------- 4 files changed, 80 insertions(+), 37 deletions(-) mode change 100755 => 100644 doc/src/Errors_messages.rst diff --git a/doc/src/Errors_messages.rst b/doc/src/Errors_messages.rst old mode 100755 new mode 100644 diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index c1323cafde..18146378b7 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -587,7 +587,7 @@ label maps. .. parsed-literal:: ID = number of angle (1-Nangles) - type = angle type (1-Nangletype) + type = angle type (1-Nangletype, or type label) atom1,atom2,atom3 = IDs of 1st,2nd,3rd atom in angle example: @@ -631,23 +631,24 @@ atom, bond, etc. types in terms of user-provided strings instead of 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 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 -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 ` -command can be used to print out the default label map at a given -point in a simulation. See the :doc:`labelmap ` command for -more discussion on how to use type label maps. +come before any section that utilizes that type. Type labels can be +directly substituted for numeric types listed in the *Atoms*, *Bonds*, +etc. sections of data files. If numeric types are used, each +interaction type is first converted into its corresponding type label +before being read into LAMMPS. 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 ` command can be used to print out the +default label map at a given point in a simulation. See the +:doc:`labelmap ` command for more discussion on how to use +type label maps. ---------- @@ -720,7 +721,7 @@ of analysis. The per-atom values have these meanings and units, listed alphabetically: * atom-ID = integer ID of atom -* atom-type = type of atom (1-Ntype) +* atom-type = type of atom (1-Ntype, or type label) * bodyflag = 1 for body particles, 0 for point particles * bond_nt = bond NT factor for MESONT particles (?? units) * buckling = buckling factor for MESONT particles (?? units) @@ -1044,7 +1045,7 @@ label maps. .. parsed-literal:: ID = bond number (1-Nbonds) - type = bond type (1-Nbondtype) + type = bond type (1-Nbondtype, or type label) atom1,atom2 = IDs of 1st,2nd atom in bond * example: @@ -1108,7 +1109,7 @@ use type label maps. .. parsed-literal:: ID = number of dihedral (1-Ndihedrals) - type = dihedral type (1-Ndihedraltype) + type = dihedral type (1-Ndihedraltype, or type label) atom1,atom2,atom3,atom4 = IDs of 1st,2nd,3rd,4th atom in dihedral * example: @@ -1227,7 +1228,7 @@ use type label maps. .. parsed-literal:: ID = number of improper (1-Nimpropers) - type = improper type (1-Nimpropertype) + type = improper type (1-Nimpropertype, or type label) atom1,atom2,atom3,atom4 = IDs of 1st,2nd,3rd,4th atom in improper * example: diff --git a/doc/src/write_data.rst b/doc/src/write_data.rst index a441d6a043..b7eb7cf94d 100644 --- a/doc/src/write_data.rst +++ b/doc/src/write_data.rst @@ -118,7 +118,8 @@ etc. types are written in the Atoms, Bonds, etc. sections. If the value is specified as *numeric*, then numeric types are used. If the value is specified as *labels*, then interaction types are written as type labels using the default label map. When using type labels, the -default label map must be written to the data file. +default label map (i.e., Type Label sections) must be 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/atom.cpp b/src/atom.cpp index da1aaff7b4..a82dab77bb 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -53,6 +53,7 @@ using namespace MathConst; #define DELTA 1 #define DELTA_PERATOM 64 #define EPSILON 1.0e-6 +#define MAXLINE 256 /* ---------------------------------------------------------------------- */ @@ -1198,9 +1199,9 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset, if (id_offset) tag[nlocal-1] += id_offset; if (mol_offset) molecule[nlocal-1] += mol_offset; if (!isdigit(typestr[0])) { - if (!atom->labelmapflag) error->one(FLERR,"Invalid Types section in molecule file"); + if (!atom->labelmapflag) error->one(FLERR,"Invalid Atoms section in data file"); type[nlocal-1] = atom->find_label(typestr,Atom::ATOM); - if (type[nlocal-1] == -1) error->one(FLERR,"Invalid Types section in molecule file"); + if (type[nlocal-1] == -1) error->one(FLERR,"Invalid Atoms section in data file"); } else { type[nlocal-1] = utils::inumeric(FLERR,typestr.c_str(),true,lmp); if (labelflag) type[nlocal-1] = ilabel[type[nlocal-1]-1]; @@ -1275,20 +1276,30 @@ void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset, int m,tmp,itype,rv; tagint atom1,atom2; char *next; + char typechar[MAXLINE]; + std::string typestr; int newton_bond = force->newton_bond; for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2); + rv = sscanf(buf,"%d %s " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,typechar,&atom1,&atom2); if (rv != 4) error->one(FLERR,"Incorrect format of Bonds section in data file"); if (id_offset) { atom1 += id_offset; atom2 += id_offset; } - if (labelflag) itype = ilabel[itype-1]; + typestr = typechar; + if (!isdigit(typestr[0])) { + if (!atom->labelmapflag) error->one(FLERR,"Invalid Bonds section in data file"); + itype = atom->find_label(typestr,Atom::BOND); + if (itype == -1) error->one(FLERR,"Invalid Bonds section in data file"); + } else { + itype = utils::inumeric(FLERR,typechar,true,lmp); + if (labelflag) itype = ilabel[itype-1]; + } itype += type_offset; if ((atom1 <= 0) || (atom1 > map_tag_max) || @@ -1333,13 +1344,15 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset, int m,tmp,itype,rv; tagint atom1,atom2,atom3; char *next; + char typechar[MAXLINE]; + std::string typestr; int newton_bond = force->newton_bond; for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3); + rv = sscanf(buf,"%d %s " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, + &tmp,typechar,&atom1,&atom2,&atom3); if (rv != 5) error->one(FLERR,"Incorrect format of Angles section in data file"); if (id_offset) { @@ -1347,7 +1360,15 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset, atom2 += id_offset; atom3 += id_offset; } - if (labelflag) itype = ilabel[itype-1]; + typestr = typechar; + if (!isdigit(typestr[0])) { + if (!atom->labelmapflag) error->one(FLERR,"Invalid Angles section in data file"); + itype = atom->find_label(typestr,Atom::ANGLE); + if (itype == -1) error->one(FLERR,"Invalid Angles section in data file"); + } else { + itype = utils::inumeric(FLERR,typechar,true,lmp); + if (labelflag) itype = ilabel[itype-1]; + } itype += type_offset; if ((atom1 <= 0) || (atom1 > map_tag_max) || @@ -1406,14 +1427,16 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset, int m,tmp,itype,rv; tagint atom1,atom2,atom3,atom4; char *next; + char typechar[MAXLINE]; + std::string typestr; int newton_bond = force->newton_bond; for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT + rv = sscanf(buf,"%d %s " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + &tmp,typechar,&atom1,&atom2,&atom3,&atom4); if (rv != 6) error->one(FLERR,"Incorrect format of Dihedrals section in data file"); if (id_offset) { @@ -1422,7 +1445,15 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset, atom3 += id_offset; atom4 += id_offset; } - if (labelflag) itype = ilabel[itype-1]; + typestr = typechar; + if (!isdigit(typestr[0])) { + if (!atom->labelmapflag) error->one(FLERR,"Invalid Dihedrals section in data file"); + itype = atom->find_label(typestr,Atom::DIHEDRAL); + if (itype == -1) error->one(FLERR,"Invalid Dihedrals section in data file"); + } else { + itype = utils::inumeric(FLERR,typechar,true,lmp); + if (labelflag) itype = ilabel[itype-1]; + } itype += type_offset; if ((atom1 <= 0) || (atom1 > map_tag_max) || @@ -1498,14 +1529,16 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset, int m,tmp,itype,rv; tagint atom1,atom2,atom3,atom4; char *next; + char typechar[MAXLINE]; + std::string typestr; int newton_bond = force->newton_bond; for (int i = 0; i < n; i++) { next = strchr(buf,'\n'); *next = '\0'; - rv = sscanf(buf,"%d %d " + rv = sscanf(buf,"%d %s " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, - &tmp,&itype,&atom1,&atom2,&atom3,&atom4); + &tmp,typechar,&atom1,&atom2,&atom3,&atom4); if (rv != 6) error->one(FLERR,"Incorrect format of Impropers section in data file"); if (id_offset) { @@ -1514,7 +1547,15 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset, atom3 += id_offset; atom4 += id_offset; } - if (labelflag) itype = ilabel[itype-1]; + typestr = typechar; + if (!isdigit(typestr[0])) { + if (!atom->labelmapflag) error->one(FLERR,"Invalid Impropers section in data file"); + itype = atom->find_label(typestr,Atom::IMPROPER); + if (itype == -1) error->one(FLERR,"Invalid Impropers section in data file"); + } else { + itype = utils::inumeric(FLERR,typechar,true,lmp); + if (labelflag) itype = ilabel[itype-1]; + } itype += type_offset; if ((atom1 <= 0) || (atom1 > map_tag_max) ||